private void handleReattachSession(final ReattachSessionMessage request) {
    Packet response = null;

    try {

      if (!server.isStarted()) {
        response = new ReattachSessionResponseMessage(-1, false);
      }

      logger.debug("Reattaching request from " + connection.getRemoteAddress());

      ServerSessionPacketHandler sessionHandler =
          protocolManager.getSessionHandler(request.getName());

      // HORNETQ-720 XXX ataylor?
      if (
      /*!server.checkActivate() || */ sessionHandler == null) {
        response = new ReattachSessionResponseMessage(-1, false);
      } else {
        if (sessionHandler.getChannel().getConfirmationWindowSize() == -1) {
          // Even though session exists, we can't reattach since confi window size == -1,
          // i.e. we don't have a resend cache for commands, so we just close the old session
          // and let the client recreate

          ActiveMQServerLogger.LOGGER.reattachRequestFailed(connection.getRemoteAddress());

          sessionHandler.closeListeners();
          sessionHandler.close();

          response = new ReattachSessionResponseMessage(-1, false);
        } else {
          // Reconnect the channel to the new connection
          int serverLastConfirmedCommandID =
              sessionHandler.transferConnection(connection, request.getLastConfirmedCommandID());

          response = new ReattachSessionResponseMessage(serverLastConfirmedCommandID, true);
        }
      }
    } catch (Exception e) {
      ActiveMQServerLogger.LOGGER.failedToReattachSession(e);

      response = new ActiveMQExceptionMessage(new ActiveMQInternalErrorException());
    }

    channel1.send(response);
  }
  public ConnectionEntry createConnectionEntry(
      final Acceptor acceptorUsed, final Connection connection) {
    final Configuration config = server.getConfiguration();

    Executor connectionExecutor = server.getExecutorFactory().getExecutor();

    final CoreRemotingConnection rc =
        new RemotingConnectionImpl(
            ServerPacketDecoder.INSTANCE,
            connection,
            incomingInterceptors,
            outgoingInterceptors,
            config.isAsyncConnectionExecutionEnabled() ? connectionExecutor : null,
            server.getNodeID());

    Channel channel1 = rc.getChannel(CHANNEL_ID.SESSION.id, -1);

    ChannelHandler handler = new ActiveMQPacketHandler(this, server, channel1, rc);

    channel1.setHandler(handler);

    long ttl = ActiveMQClient.DEFAULT_CONNECTION_TTL;

    if (config.getConnectionTTLOverride() != -1) {
      ttl = config.getConnectionTTLOverride();
    }

    final ConnectionEntry entry =
        new ConnectionEntry(rc, connectionExecutor, System.currentTimeMillis(), ttl);

    final Channel channel0 = rc.getChannel(ChannelImpl.CHANNEL_ID.PING.id, -1);

    channel0.setHandler(new LocalChannelHandler(config, entry, channel0, acceptorUsed, rc));

    server
        .getClusterManager()
        .addClusterChannelHandler(
            rc.getChannel(CHANNEL_ID.CLUSTER.id, -1), acceptorUsed, rc, server.getActivation());

    return entry;
  }
  private void handleCreateSession(final CreateSessionMessage request) {
    boolean incompatibleVersion = false;
    Packet response;
    try {
      Version version = server.getVersion();
      if (!version.isCompatible(request.getVersion())) {
        throw ActiveMQMessageBundle.BUNDLE.incompatibleClientServer();
      }

      if (!server.isStarted()) {
        throw ActiveMQMessageBundle.BUNDLE.serverNotStarted();
      }

      // XXX HORNETQ-720 Taylor commented out this test. Should be verified.
      /*if (!server.checkActivate())
      {
         throw new ActiveMQException(ActiveMQException.SESSION_CREATION_REJECTED,
                                    "Server will not accept create session requests");
      }*/

      if (connection.getClientVersion() == 0) {
        connection.setClientVersion(request.getVersion());
      } else if (connection.getClientVersion() != request.getVersion()) {
        ActiveMQServerLogger.LOGGER.incompatibleVersionAfterConnect(
            request.getVersion(), connection.getClientVersion());
      }

      Channel channel =
          connection.getChannel(request.getSessionChannelID(), request.getWindowSize());

      ActiveMQPrincipal activeMQPrincipal = null;

      if (request.getUsername() == null) {
        activeMQPrincipal = connection.getDefaultActiveMQPrincipal();
      }

      ServerSession session =
          server.createSession(
              request.getName(),
              activeMQPrincipal == null ? request.getUsername() : activeMQPrincipal.getUserName(),
              activeMQPrincipal == null ? request.getPassword() : activeMQPrincipal.getPassword(),
              request.getMinLargeMessageSize(),
              connection,
              request.isAutoCommitSends(),
              request.isAutoCommitAcks(),
              request.isPreAcknowledge(),
              request.isXA(),
              request.getDefaultAddress(),
              new CoreSessionCallback(request.getName(), protocolManager, channel, connection),
              true);

      ServerSessionPacketHandler handler =
          new ServerSessionPacketHandler(session, server.getStorageManager(), channel);
      channel.setHandler(handler);

      // TODO - where is this removed?
      protocolManager.addSessionHandler(request.getName(), handler);

      response = new CreateSessionResponseMessage(server.getVersion().getIncrementingVersion());
    } catch (ActiveMQException e) {
      if (e.getType() == ActiveMQExceptionType.INCOMPATIBLE_CLIENT_SERVER_VERSIONS) {
        incompatibleVersion = true;
        logger.debug("Sending ActiveMQException after Incompatible client", e);
      } else {
        ActiveMQServerLogger.LOGGER.failedToCreateSession(e);
      }

      response = new ActiveMQExceptionMessage(e);
    } catch (Exception e) {
      ActiveMQServerLogger.LOGGER.failedToCreateSession(e);

      response = new ActiveMQExceptionMessage(new ActiveMQInternalErrorException());
    }

    // send the exception to the client and destroy
    // the connection if the client and server versions
    // are not compatible
    if (incompatibleVersion) {
      channel1.sendAndFlush(response);
    } else {
      channel1.send(response);
    }
  }
    public void handlePacket(final Packet packet) {
      if (packet.getType() == PacketImpl.PING) {
        Ping ping = (Ping) packet;

        if (config.getConnectionTTLOverride() == -1) {
          // Allow clients to specify connection ttl
          entry.ttl = ping.getConnectionTTL();
        }

        // Just send a ping back
        channel0.send(packet);
      } else if (packet.getType() == PacketImpl.SUBSCRIBE_TOPOLOGY
          || packet.getType() == PacketImpl.SUBSCRIBE_TOPOLOGY_V2) {
        SubscribeClusterTopologyUpdatesMessage msg =
            (SubscribeClusterTopologyUpdatesMessage) packet;

        if (packet.getType() == PacketImpl.SUBSCRIBE_TOPOLOGY_V2) {
          channel0
              .getConnection()
              .setClientVersion(
                  ((SubscribeClusterTopologyUpdatesMessageV2) msg).getClientVersion());
        }

        final ClusterTopologyListener listener =
            new ClusterTopologyListener() {
              @Override
              public void nodeUP(final TopologyMember topologyMember, final boolean last) {
                try {
                  final Pair<TransportConfiguration, TransportConfiguration> connectorPair =
                      BackwardsCompatibilityUtils.getTCPair(
                          channel0.getConnection().getClientVersion(), topologyMember);

                  final String nodeID = topologyMember.getNodeId();
                  // Using an executor as most of the notifications on the Topology
                  // may come from a channel itself
                  // What could cause deadlocks
                  entry.connectionExecutor.execute(
                      new Runnable() {
                        public void run() {
                          if (channel0.supports(PacketImpl.CLUSTER_TOPOLOGY_V3)) {
                            channel0.send(
                                new ClusterTopologyChangeMessage_V3(
                                    topologyMember.getUniqueEventID(),
                                    nodeID,
                                    topologyMember.getBackupGroupName(),
                                    topologyMember.getScaleDownGroupName(),
                                    connectorPair,
                                    last));
                          } else if (channel0.supports(PacketImpl.CLUSTER_TOPOLOGY_V2)) {
                            channel0.send(
                                new ClusterTopologyChangeMessage_V2(
                                    topologyMember.getUniqueEventID(),
                                    nodeID,
                                    topologyMember.getBackupGroupName(),
                                    connectorPair,
                                    last));
                          } else {
                            channel0.send(
                                new ClusterTopologyChangeMessage(nodeID, connectorPair, last));
                          }
                        }
                      });
                } catch (RejectedExecutionException ignored) {
                  // this could happen during a shutdown and we don't care, if we lost a nodeDown
                  // during a shutdown
                  // what can we do anyways?
                }
              }

              @Override
              public void nodeDown(final long uniqueEventID, final String nodeID) {
                // Using an executor as most of the notifications on the Topology
                // may come from a channel itself
                // What could cause deadlocks
                try {
                  entry.connectionExecutor.execute(
                      new Runnable() {
                        public void run() {
                          if (channel0.supports(PacketImpl.CLUSTER_TOPOLOGY_V2)) {
                            channel0.send(
                                new ClusterTopologyChangeMessage_V2(uniqueEventID, nodeID));
                          } else {
                            channel0.send(new ClusterTopologyChangeMessage(nodeID));
                          }
                        }
                      });
                } catch (RejectedExecutionException ignored) {
                  // this could happen during a shutdown and we don't care, if we lost a nodeDown
                  // during a shutdown
                  // what can we do anyways?
                }
              }

              @Override
              public String toString() {
                return "Remote Proxy on channel "
                    + Integer.toHexString(System.identityHashCode(this));
              }
            };

        if (acceptorUsed.getClusterConnection() != null) {
          acceptorUsed.getClusterConnection().addClusterTopologyListener(listener);

          rc.addCloseListener(
              new CloseListener() {
                public void connectionClosed() {
                  acceptorUsed.getClusterConnection().removeClusterTopologyListener(listener);
                }
              });
        } else {
          // if not clustered, we send a single notification to the client containing the node-id
          // where the server is connected to
          // This is done this way so Recovery discovery could also use the node-id for
          // non-clustered setups
          entry.connectionExecutor.execute(
              new Runnable() {
                public void run() {
                  String nodeId = server.getNodeID().toString();
                  Pair<TransportConfiguration, TransportConfiguration> emptyConfig =
                      new Pair<TransportConfiguration, TransportConfiguration>(null, null);
                  if (channel0.supports(PacketImpl.CLUSTER_TOPOLOGY_V2)) {
                    channel0.send(
                        new ClusterTopologyChangeMessage_V2(
                            System.currentTimeMillis(), nodeId, null, emptyConfig, true));
                  } else {
                    channel0.send(new ClusterTopologyChangeMessage(nodeId, emptyConfig, true));
                  }
                }
              });
        }
      }
    }