public void startReceiving() { final Channel channel = this.channelAssociation.getChannel(); channel.addCloseHandler(new ChannelCloseHandler()); channel.receiveMessage(this); // listen to module availability/unavailability events this.deploymentRepository.addListener(this); // listen to new clusters (a.k.a groups) being started/stopped this.clientMappingRegistryCollector.addListener(this); // Send the cluster topology for existing clusters in the registry // and for each of these clusters added ourselves as a listener for cluster // topology changes (members added/removed events in the cluster) final Collection<Registry<String, List<ClientMapping>>> clusters = this.clientMappingRegistryCollector.getRegistries(); try { this.sendNewClusterFormedMessage(clusters); } catch (IOException ioe) { // just log and don't throw an error EjbLogger.ROOT_LOGGER.failedToSendClusterFormationMessageToClient(ioe, channel); } for (final Registry<String, List<ClientMapping>> cluster : clusters) { // add the topology update listener final ClusterTopologyUpdateListener clusterTopologyUpdateListener = new ClusterTopologyUpdateListener(cluster, this); cluster.addListener(clusterTopologyUpdateListener); // keep track of this topology update listener so that we can unregister it when the channel // is closed and // we no longer are interested in the topology updates this.clusterTopologyUpdateListeners.add(clusterTopologyUpdateListener); } }
@Override public ProxyController serverCommunicationRegistered( final String serverProcessName, final ManagementChannelHandler channelAssociation) { if (shutdown || connectionFinished) { throw HostControllerMessages.MESSAGES.hostAlreadyShutdown(); } final String serverName = ManagedServer.getServerName(serverProcessName); final ManagedServer server = servers.get(serverName); if (server == null) { ROOT_LOGGER.noServerAvailable(serverName); return null; } try { final TransactionalProtocolClient client = server.channelRegistered(channelAssociation); final Channel channel = channelAssociation.getChannel(); channel.addCloseHandler( new CloseHandler<Channel>() { public void handleClose(final Channel closed, final IOException exception) { final boolean shuttingDown = shutdown || connectionFinished; // Unregister right away if (server.callbackUnregistered(client, shuttingDown)) { domainController.unregisterRunningServer(server.getServerName()); } } }); return server.getProxyController(); } catch (IOException e) { throw new RuntimeException(e); } }
/** * Execute an operation and wait until the connection is closed. This is only useful for :reload * and :shutdown operations. * * @param operation the operation to execute * @return the operation result * @throws IOException for any error */ public ModelNode executeAwaitConnectionClosed(final ModelNode operation) throws IOException { final DomainTestClient client = internalGetOrCreateClient(); final Channel channel = client.getChannel(); final Connection ref = channel.getConnection(); ModelNode result = new ModelNode(); try { result = client.execute(operation); // IN case the operation wasn't successful, don't bother waiting if (!"success".equals(result.get("outcome").asString())) { return result; } } catch (Exception e) { if (e instanceof IOException) { final Throwable cause = e.getCause(); if (cause instanceof ExecutionException) { // ignore, this might happen if the channel gets closed before we got the response } else { throw (IOException) e; } } else { throw new RuntimeException(e); } } try { if (channel != null) { // Wait for the channel to close channel.awaitClosed(); } // Wait for the connection to be closed connection.awaitConnectionClosed(ref); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return result; }
@After public void stopChannels() throws Exception { for (final Channel channel : channels) { channel.close(); } futureConnection.get().close(); channelServer.close(); channelServer = null; }
/** * Create the protocol client to talk to the remote controller. * * @param channel the remoting channel * @return the client * @throws Exception */ TransactionalProtocolClient createClient(final Channel channel) { channels.add(channel); final ManagementChannelHandler channelAssociation = new ManagementChannelHandler(channel, clientExecutor); final TransactionalProtocolClient client = TransactionalProtocolHandlers.createClient(channelAssociation); channel.addCloseHandler(channelAssociation); channel.receiveMessage(channelAssociation.getReceiver()); return client; }
@Override public void handleClose(final Channel closed, final IOException exception) { if (CLIModelControllerClient.this.closed) { return; } synchronized (lock) { if (strategy != null) { if (strategy != originalStrategy) { new Exception("Channel close handler " + strategy + " " + originalStrategy) .printStackTrace(); } strategy = null; closeHandler.handleClose(); } channelAssociation.handleChannelClosed(closed, exception); lock.notifyAll(); } // Closing the strategy in this handler may result in race conditions // with connection closing and then deadlocks in remoting // it's safer to close the strategy from the connection close handler closed .getConnection() .addCloseHandler( new CloseHandler<Connection>() { @Override public void handleClose(Connection closed, IOException exception) { StreamUtils.safeClose(originalStrategy); } }); }
@Override public void handleMessage(final Channel channel, final MessageInputStream message) { try { ROOT_LOGGER.tracef("%s handling incoming data", this); final DataInput input = new DataInputStream(message); final ManagementProtocolHeader header = ManagementProtocolHeader.parse(input); final byte type = header.getType(); if (type == ManagementProtocol.TYPE_PING) { // Handle legacy ping/pong directly ROOT_LOGGER.tracef("Received ping on %s", this); handlePing(channel, header); } else if (type == ManagementProtocol.TYPE_BYE_BYE) { // Close the channel ROOT_LOGGER.tracef("Received bye bye on %s, closing", this); handleChannelReset(channel); } else { // Handle a message handleMessage(channel, input, header); } message.close(); } catch (IOException e) { handleError(channel, e); } catch (Exception e) { handleError(channel, new IOException(e)); } finally { StreamUtils.safeClose(message); ROOT_LOGGER.tracef("%s done handling incoming data", this); } final Channel.Receiver next = next(); if (next != null) { channel.receiveMessage(next); } }
public static IoFuture<InitialHeader> getInitialHeader(final Channel channel) { VersionedIoFuture<InitialHeader> future = new VersionedIoFuture<InitialHeader>(); channel.receiveMessage(new ClientVersionReceiver(future)); return future; }
@Override public void handleEnd(final Channel channel) { try { channel.close(); } catch (IOException e) { ROOT_LOGGER.errorClosingChannel(e.getMessage()); } }
@Override protected ProxyController createProxyController( final ModelController proxiedController, final PathAddress proxyNodeAddress) { try { channels = new RemoteChannelPairSetup(); channels.setupRemoting( new ManagementChannelInitialization() { @Override public ManagementChannelHandler startReceiving(Channel channel) { final ManagementChannelHandler support = new ManagementChannelHandler(channel, channels.getExecutorService()); support.addHandlerFactory( new TransactionalProtocolOperationHandler(proxiedController, support)); channel.addCloseHandler( new CloseHandler<Channel>() { @Override public void handleClose(Channel closed, IOException exception) { support.shutdownNow(); } }); channel.receiveMessage(support.getReceiver()); return support; } }); channels.startClientConnetion(); } catch (Exception e) { throw new RuntimeException(e); } final Channel clientChannel = channels.getClientChannel(); final ManagementChannelHandler support = new ManagementChannelHandler(clientChannel, channels.getExecutorService()); final RemoteProxyController proxyController = RemoteProxyController.create( support, proxyNodeAddress, ProxyOperationAddressTranslator.SERVER); clientChannel.addCloseHandler( new CloseHandler<Channel>() { @Override public void handleClose(Channel closed, IOException exception) { support.shutdownNow(); } }); clientChannel.receiveMessage(support.getReceiver()); return proxyController; }
@Override public void handleError(final Channel channel, final IOException error) { ROOT_LOGGER.tracef(error, "%s error handling incoming data", this); try { channel.close(); } catch (IOException e) { ROOT_LOGGER.errorClosingChannel(e.getMessage()); } }
@Override public void handleError(Channel channel, IOException error) { try { channel.close(); } catch (IOException e) { throw EjbLogger.ROOT_LOGGER.couldNotCloseChannel(e); } finally { this.cleanupOnChannelDown(); } }
@Override public void handleEnd(Channel channel) { try { channel.close(); } catch (IOException e) { // ignore } finally { this.cleanupOnChannelDown(); } }
/** * Handle a simple ping request. * * @param channel the channel * @param header the protocol header * @throws IOException for any error */ protected static void handlePing(final Channel channel, final ManagementProtocolHeader header) throws IOException { final ManagementProtocolHeader response = new ManagementPongHeader(header.getVersion()); final MessageOutputStream output = channel.writeMessage(); try { writeHeader(response, output); output.close(); } finally { StreamUtils.safeClose(output); } }
protected static void writeResponse( final Channel channel, final ManagementRequestHeader header, final Exception error) throws IOException { final ManagementResponseHeader response = ManagementResponseHeader.create(header, error); final MessageOutputStream output = channel.writeMessage(); try { writeHeader(response, output); output.close(); } finally { StreamUtils.safeClose(output); } }
@Override public void connectionOpened(final Connection connection) throws IOException { final Channel channel = openChannel(connection, CHANNEL_SERVICE_TYPE, configuration.getOptionMap()); if (setChannel(channel)) { channel.receiveMessage(channelHandler.getReceiver()); channel.addCloseHandler(channelHandler); try { // Start the registration process channelHandler.executeRequest(new RegisterHostControllerRequest(), null).getResult().get(); } catch (Exception e) { if (e.getCause() instanceof IOException) { throw (IOException) e.getCause(); } throw new IOException(e); } // Registered registered(); } else { channel.closeAsync(); } }
@Override public void handleMessage( final Channel channel, final DataInput input, final ManagementProtocolHeader header) throws IOException { final byte type = header.getType(); if (type == ManagementProtocol.TYPE_REQUEST) { final ManagementRequestHeader request = (ManagementRequestHeader) header; handleMessage(channel, input, request); } else { safeWriteResponse(channel, header, MESSAGES.unrecognizedType(type)); channel.close(); } }
@Override public Channel.Key startReceiving(final Channel channel) { final ManagementChannelHandler handler = new ManagementChannelHandler( ManagementClientChannelStrategy.create(channel), getExecutor()); // Assemble the request handlers for the domain channel handler.addHandlerFactory( new HostControllerRegistrationHandler(handler, getController(), domainController)); handler.addHandlerFactory(new ModelControllerClientOperationHandler(getController(), handler)); handler.addHandlerFactory(new MasterDomainControllerOperationHandlerImpl(domainController)); final Channel.Key key = channel.addCloseHandler( new CloseHandler<Channel>() { @Override public void handleClose(Channel closed, IOException exception) { handler.shutdown(); boolean interrupted = false; try { if (!handler.awaitCompletion(CHANNEL_SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS)) { ROOT_LOGGER.gracefulManagementChannelHandlerShutdownTimedOut( CHANNEL_SHUTDOWN_TIMEOUT); } } catch (InterruptedException e) { interrupted = true; ROOT_LOGGER.serviceShutdownIncomplete(e); } catch (Exception e) { ROOT_LOGGER.serviceShutdownIncomplete(e); } finally { handler.shutdownNow(); if (interrupted) { Thread.currentThread().interrupt(); } } } }); channel.receiveMessage(handler.getReceiver()); return key; }
@Override public synchronized ProxyController popChannelAndCreateProxy(final String hostName) { final Channel channel = unregisteredHostChannels.remove(hostName); if (channel == null) { throw new IllegalArgumentException("No channel for host " + hostName); } channel.addCloseHandler( new CloseHandler<Channel>() { public void handleClose(final Channel closed, final IOException exception) { unregisterRemoteHost(hostName); } }); final PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(ModelDescriptionConstants.HOST, hostName)); RemoteProxyController proxy = RemoteProxyController.create( proxyExecutor, addr, ProxyOperationAddressTranslator.HOST, channel); ProxyCreatedCallback callback = proxyCreatedCallbacks.remove(hostName); if (callback != null) { callback.proxyCreated(proxy); } return proxy; }
public void handleMessage( final Channel channel, final DataInput input, final ManagementRequestHeader header) throws IOException { final byte type = header.getOperationId(); if (type == DomainServerProtocol.REGISTER_REQUEST) { expectHeader(input, DomainServerProtocol.PARAM_SERVER_NAME); final String serverName = input.readUTF(); CONTROLLER_MANAGEMENT_LOGGER.serverRegistered(serverName, channel); executorService.execute( new Runnable() { @Override public void run() { // Create the server mgmt handler final ManagementChannelHandler handler = new ManagementChannelHandler( channel, executorService, new ServerHandlerFactory(serverName)); ServerToHostOperationHandlerFactoryService.this .callback .getValue() .serverCommunicationRegistered( serverName, handler, new ServerInventory.ProxyCreatedCallback() { @Override public void proxyOperationHandlerCreated( final ManagementRequestHandlerFactory handlerFactory) { channel.addCloseHandler( new CloseHandler<Channel>() { @Override public void handleClose(Channel closed, IOException exception) { handler.shutdownNow(); } }); // Send the response once the server is fully registered safeWriteResponse(channel, header, null); // Once the server and handlers are registered, receive the next message handler.addHandlerFactory(handlerFactory); channel.receiveMessage(handler.getReceiver()); } }); } }); } else { safeWriteResponse(channel, header, MESSAGES.unrecognizedType(type)); channel.close(); } }
@Override public void handleMessage(Channel channel, MessageInputStream messageInputStream) { try { this.processMessage(channel, messageInputStream); // enroll for next message (whenever it's available) channel.receiveMessage(this); } catch (Throwable e) { // log it EjbLogger.ROOT_LOGGER.exceptionOnChannel(e, channel, messageInputStream); // no more messages can be sent or received on this channel IoUtils.safeClose(channel); } finally { IoUtils.safeClose(messageInputStream); } }
private void sendVersionZeroHeader(Channel channel) throws IOException { log.debug("Selecting version 0x00 to receive full version list."); CancellableDataOutputStream dos = new CancellableDataOutputStream(channel.writeMessage()); try { dos.writeBytes(JMX); dos.writeByte(0x00); String remotingJMXVersion = Version.getVersionString(); byte[] versionBytes = remotingJMXVersion.getBytes("UTF-8"); dos.writeInt(versionBytes.length); dos.write(versionBytes); } catch (IOException e) { dos.cancel(); throw e; } finally { IoUtils.safeClose(dos); } }
protected void processMessage(final Channel channel, final InputStream inputStream) throws IOException { // read the first byte to see what type of a message it is final int header = inputStream.read(); if (EjbLogger.ROOT_LOGGER.isTraceEnabled()) { EjbLogger.ROOT_LOGGER.trace( "Got message with header 0x" + Integer.toHexString(header) + " on channel " + channel); } final MessageHandler messageHandler = getMessageHandler((byte) header); if (messageHandler == null) { // enroll for next message (whenever it's available) channel.receiveMessage(this); // log a message that the message wasn't identified EjbLogger.ROOT_LOGGER.unsupportedMessageHeader(Integer.toHexString(header), channel); return; } // let the message handler process the message messageHandler.processMessage(channelAssociation, inputStream); }
@Override public ManagementChannelHandler startReceiving(final Channel channel) { final ManagementChannelHandler handler = new ManagementChannelHandler( ManagementClientChannelStrategy.create(channel), getExecutor()); // Assemble the request handlers for the domain channel handler.addHandlerFactory( new HostControllerRegistrationHandler( handler, domainController, operationExecutor, getExecutor(), runtimeIgnoreTransformationRegistry)); handler.addHandlerFactory(new ModelControllerClientOperationHandler(getController(), handler)); handler.addHandlerFactory( new MasterDomainControllerOperationHandlerImpl(domainController, getExecutor())); handler.addHandlerFactory(pongRequestHandler); handler.addHandlerFactory( new DomainTransactionalProtocolOperationHandler(txOperationExecutor, handler)); channel.receiveMessage(handler.getReceiver()); return handler; }
@Override public synchronized void registerChannel( final String hostName, final Channel channel, final ProxyCreatedCallback callback) { /* Disable this as part of the REM3-121 workarounds PathAddress addr = PathAddress.pathAddress(PathElement.pathElement(HOST, hostName)); if (modelNodeRegistration.getProxyController(addr) != null) { throw new IllegalArgumentException("There is already a registered slave named '" + hostName + "'"); } */ if (unregisteredHostChannels.containsKey(hostName)) { throw new IllegalArgumentException("Already have a connection for host " + hostName); } unregisteredHostChannels.put(hostName, channel); proxyCreatedCallbacks.put(hostName, callback); channel.addCloseHandler( new CloseHandler<Channel>() { public void handleClose(final Channel closed, final IOException exception) { unregisteredHostChannels.remove(hostName); proxyCreatedCallbacks.remove(hostName); } }); }
/** * Verify the header received, confirm to the server the version selected, create the client * channel receiver and assign it to the channel. */ public void handleMessage( org.jboss.remoting3.Channel channel, MessageInputStream messageInputStream) { DataInputStream dis = new DataInputStream(messageInputStream); try { log.tracef("Bytes Available %d", dis.available()); byte[] firstThree = new byte[3]; dis.read(firstThree); log.tracef("First Three %s", new String(firstThree)); if (Arrays.equals(firstThree, JMX_BYTES) == false) { throw new IOException("Invalid leading bytes in header."); } log.tracef("Bytes Available %d", dis.available()); int versionCount = dis.readInt(); log.tracef("Expecting %d versions", versionCount); byte[] versions = new byte[versionCount]; dis.read(versions); if (log.isDebugEnabled()) { StringBuffer sbVersions = new StringBuffer("Versions "); for (byte current : versions) { sbVersions.append(" 0x0").append(current); } log.debugf("Available version (%s)", sbVersions); } byte stability = dis.readByte(); switch (stability) { case STABLE: log.debug("Calling a stable server"); break; case SNAPSHOT: log.warn("Calling a snapshot server"); break; default: throw new IOException("Unrecognised stability value."); } String serverVersion = null; if (expectServerVersion) { int length = dis.readInt(); byte[] versionBytes = new byte[length]; dis.read(versionBytes); serverVersion = new String(versionBytes, "UTF-8"); log.debugf("Server version %s", serverVersion); } for (byte current : versions) { if (current == 0x00) { sendVersionZeroHeader(channel); expectServerVersion = true; channel.receiveMessage(this); return; } } InitialHeader ih = new InitialHeader(); ih.versions = versions; ih.stability = stability; ih.serverVersion = serverVersion; future.setResult(ih); } catch (IOException e) { log.error("Unable to negotiate connection.", e); future.setException(e); } finally { IoUtils.safeClose(dis); } }
@Override public HandleableCloseable.Key startReceiving(final Channel channel) { final Channel.Receiver receiver = new InitialMessageHandler(executorService); channel.receiveMessage(receiver); return null; }