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)); } } }); } } }