public SendPingRequestEvent( final ID messageReference, final Channel channel, final PingRequest message) { super( messageReference, MessageEventType.SEND_PING_REQUEST, channel, Channels.future(channel, false), message); }
private void sendByteArray(ChannelHandlerContext ctx, byte[] buffer) { try { Channel channel = ctx.getChannel(); ChannelFuture future = Channels.future(ctx.getChannel()); ChannelBuffer b = ChannelBuffers.dynamicBuffer(); // first send encoded key bytes size b.writeInt(buffer.length); // then the public key b.writeBytes(buffer); Channels.write(ctx, future, b); } catch (Exception e) { e.printStackTrace(); } }
private void writeReset(final InetSocketAddress remoteEndpoint, final int messageID) { try { CoapMessage resetMessage = CoapMessage.createEmptyReset(messageID); ChannelFuture future = Channels.future(ctx.getChannel()); Channels.write(this.getChannelHandlerContext(), future, resetMessage, remoteEndpoint); future.addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { log.info("RST for message ID {} succesfully sent to {}.", messageID, remoteEndpoint); } }); } catch (IllegalArgumentException e) { log.error("This should never happen.", e); } }
private void writeEmptyAcknowledgement( final InetSocketAddress remoteAddress, final int messageID) { try { CoapMessage emptyAcknowledgement = CoapMessage.createEmptyAcknowledgement(messageID); ChannelFuture future = Channels.future(ctx.getChannel()); Channels.write(ctx, future, emptyAcknowledgement, remoteAddress); future.addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { log.info( "Empty ACK for message ID {} succesfully sent to {}.", messageID, remoteAddress); } }); } catch (IllegalArgumentException e) { log.error("This should never happen.", e); } }
/* (non-Javadoc) * @see org.rzo.netty.ahessian.auth.AuthToken#sendPassword(org.jboss.netty.channel.ChannelHandlerContext) */ public void sendPassword(ChannelHandlerContext ctx) { Channels.write(ctx, Channels.future(ctx.getChannel()), ChannelBuffers.wrappedBuffer(_password)); }
public class Robot { private static final InternalLogger LOGGER = InternalLoggerFactory.getInstance(Robot.class); private final List<ChannelFuture> bindFutures = new ArrayList<>(); private final List<ChannelFuture> connectFutures = new ArrayList<>(); private final Channel channel = new DefaultLocalClientChannelFactory().newChannel(pipeline(new SimpleChannelHandler())); private final ChannelFuture startedFuture = Channels.future(channel); private final ChannelFuture abortedFuture = Channels.future(channel); private final ChannelFuture finishedFuture = Channels.future(channel); private final DefaultChannelGroup serverChannels = new DefaultChannelGroup(); private final DefaultChannelGroup clientChannels = new DefaultChannelGroup(); private Configuration configuration; private ChannelFuture preparedFuture; private volatile boolean destroyed; private final ChannelAddressFactory addressFactory; private final BootstrapFactory bootstrapFactory; private final boolean createdBootstrapFactory; private ScriptProgress progress; private final ChannelHandler closeOnExceptionHandler = new CloseOnExceptionHandler(); private final ConcurrentMap<String, Barrier> barriersByName = new ConcurrentHashMap<String, Barrier>(); // tests public Robot() { this(newChannelAddressFactory()); } private Robot(ChannelAddressFactory addressFactory) { this( addressFactory, newBootstrapFactory( Collections.<Class<?>, Object>singletonMap( ChannelAddressFactory.class, addressFactory)), true); } private Robot( ChannelAddressFactory addressFactory, BootstrapFactory bootstrapFactory, boolean createdBootstrapFactory) { this.addressFactory = addressFactory; this.bootstrapFactory = bootstrapFactory; this.createdBootstrapFactory = createdBootstrapFactory; ChannelFutureListener stopConfigurationListener = createStopConfigurationListener(); this.abortedFuture.addListener(stopConfigurationListener); this.finishedFuture.addListener(stopConfigurationListener); } public ChannelFuture getPreparedFuture() { return preparedFuture; } public ChannelFuture getStartedFuture() { return startedFuture; } public ChannelFuture prepare(String expectedScript) throws Exception { if (preparedFuture != null) { throw new IllegalStateException("Script already prepared"); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("Expected script:\n" + expectedScript); } final ScriptParser parser = new Parser(); AstScriptNode scriptAST = parser.parse(new ByteArrayInputStream(expectedScript.getBytes(UTF_8))); final ScriptValidator validator = new ScriptValidator(); validator.validate(scriptAST); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Parsed script:\n" + scriptAST); } RegionInfo scriptInfo = scriptAST.getRegionInfo(); progress = new ScriptProgress(scriptInfo, expectedScript); final GenerateConfigurationVisitor visitor = new GenerateConfigurationVisitor(bootstrapFactory, addressFactory); configuration = scriptAST.accept(visitor, new GenerateConfigurationVisitor.State(barriersByName)); preparedFuture = prepareConfiguration(); return preparedFuture; } // ONLY used for testing, TODO, remove and use TestSpecification instead ChannelFuture prepareAndStart(String script) throws Exception { ChannelFuture preparedFuture = prepare(script); preparedFuture.addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { start(); } }); return startedFuture; } public ChannelFuture start() throws Exception { if (preparedFuture == null || !preparedFuture.isDone()) { throw new IllegalStateException("Script has not been prepared or is still preparing"); } else if (startedFuture.isDone()) { throw new IllegalStateException("Script has already been started"); } // ensure prepare has completed before start can progress preparedFuture.addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { try { startConfiguration(); startedFuture.setSuccess(); } catch (Exception ex) { startedFuture.setFailure(ex); } } }); return startedFuture; } public ChannelFuture abort() { abortedFuture.setSuccess(); return finishedFuture; } public ChannelFuture finish() { return finishedFuture; } public String getObservedScript() { return (progress != null) ? progress.getObservedScript() : null; } public boolean isDestroyed() { return destroyed; } public boolean destroy() { if (destroyed) { return true; } abort(); if (createdBootstrapFactory) { try { bootstrapFactory.shutdown(); bootstrapFactory.releaseExternalResources(); } catch (Exception e) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Caught exception releasing resources", e); } return false; } } return destroyed = true; } private ChannelFuture prepareConfiguration() throws Exception { List<ChannelFuture> completionFutures = new ArrayList<>(); ChannelFutureListener streamCompletionListener = createStreamCompletionListener(); for (ChannelPipeline pipeline : configuration.getClientAndServerPipelines()) { CompletionHandler completionHandler = pipeline.get(CompletionHandler.class); ChannelFuture completionFuture = completionHandler.getHandlerFuture(); completionFutures.add(completionFuture); completionFuture.addListener(streamCompletionListener); } ChannelFuture executionFuture = new CompositeChannelFuture<>(channel, completionFutures); ChannelFutureListener executionListener = createScriptCompletionListener(); executionFuture.addListener(executionListener); return prepareServers(); } private ChannelFuture prepareServers() throws Exception { /* Accept's ... Robot acting as a server */ for (ServerBootstrapResolver serverResolver : configuration.getServerResolvers()) { ServerBootstrap server = serverResolver.resolve(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Binding to address " + server.getOption("localAddress")); } /* Keep track of the client channels */ server.setParentHandler( new SimpleChannelHandler() { @Override public void childChannelOpen(ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception { clientChannels.add(e.getChildChannel()); } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { Channel channel = ctx.getChannel(); channel.close(); } }); // Bind Asynchronously ChannelFuture bindFuture = server.bindAsync(); // Add to out serverChannel Group serverChannels.add(bindFuture.getChannel()); // Add to our list of bindFutures so we can cancel them later on a possible abort bindFutures.add(bindFuture); // Listen for the bindFuture. RegionInfo regionInfo = (RegionInfo) server.getOption("regionInfo"); bindFuture.addListener( createBindCompleteListener(regionInfo, serverResolver.getNotifyBarrier())); } return new CompositeChannelFuture<>(channel, bindFutures); } private void startConfiguration() throws Exception { /* Connect to any clients */ for (final ClientBootstrapResolver clientResolver : configuration.getClientResolvers()) { Barrier awaitBarrier = clientResolver.getAwaitBarrier(); if (awaitBarrier != null) { awaitBarrier .getFuture() .addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { connectClient(clientResolver); } }); } else { connectClient(clientResolver); } } } private void connectClient(ClientBootstrapResolver clientResolver) throws Exception { final RegionInfo regionInfo = clientResolver.getRegionInfo(); ClientBootstrap client = clientResolver.resolve(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("[id: ] connect " + client.getOption("remoteAddress")); } ChannelFuture connectFuture = client.connect(); connectFutures.add(connectFuture); clientChannels.add(connectFuture.getChannel()); connectFuture.addListener(createConnectCompleteListener(regionInfo)); } private void stopConfiguration() throws Exception { if (configuration == null) { // abort received but script not prepared, therefore entire script failed if (progress == null) { progress = new ScriptProgress(newSequential(0, 0), ""); } RegionInfo scriptInfo = progress.getScriptInfo(); progress.addScriptFailure(scriptInfo); } else { // stopping the configuration will implicitly trigger the script complete listener // to handle incomplete script that is being aborted by canceling the finish future // clear out the pipelines for new connections to avoid impacting the observed script for (ServerBootstrapResolver serverResolver : configuration.getServerResolvers()) { ServerBootstrap server = serverResolver.resolve(); server.setPipelineFactory(pipelineFactory(pipeline(closeOnExceptionHandler))); } for (ClientBootstrapResolver clientResolver : configuration.getClientResolvers()) { ClientBootstrap client = clientResolver.resolve(); client.setPipelineFactory(pipelineFactory(pipeline(closeOnExceptionHandler))); } // remove each handler from the configuration pipelines // this will trigger failures for any handlers on a pipeline for an incomplete stream // including pipelines not yet associated with any channel for (ChannelPipeline pipeline : configuration.getClientAndServerPipelines()) { stopStream(pipeline); } // cancel any pending binds and connects for (ChannelFuture bindFuture : bindFutures) { bindFuture.cancel(); } for (ChannelFuture connectFuture : connectFutures) { connectFuture.cancel(); } // close server and client channels final ChannelGroupFuture closeFuture = serverChannels.close(); closeFuture.addListener( new ChannelGroupFutureListener() { @Override public void operationComplete(final ChannelGroupFuture future) { clientChannels.close(); } }); for (AutoCloseable resource : configuration.getResources()) { try { resource.close(); } catch (Exception e) { // ignore } } } } private void stopStream(final ChannelPipeline pipeline) { if (pipeline.isAttached()) { // avoid race between pipeline clean up and channel events on same pipeline // by executing the pipeline clean up on the I/O worker thread pipeline.execute( new Runnable() { @Override public void run() { stopStreamAligned(pipeline); } }); } else { // no race if not attached stopStreamAligned(pipeline); } } private void stopStreamAligned(final ChannelPipeline pipeline) { for (ChannelHandler handler : pipeline.toMap().values()) { // note: removing this handler can trigger script completion // which in turn can re-attempt to stop this pipeline pipeline.remove(handler); } // non-empty pipeline required to avoid warnings if (pipeline.getContext(closeOnExceptionHandler) == null) { pipeline.addLast("closeOnException", closeOnExceptionHandler); } } private ChannelFutureListener createBindCompleteListener( final RegionInfo regionInfo, final Barrier notifyBarrier) { return new ChannelFutureListener() { @Override public void operationComplete(final ChannelFuture bindFuture) throws Exception { if (bindFuture.isSuccess()) { if (LOGGER.isDebugEnabled()) { Channel boundChannel = bindFuture.getChannel(); SocketAddress localAddress = boundChannel.getLocalAddress(); LOGGER.debug("Successfully bound to " + localAddress); } if (notifyBarrier != null) { ChannelFuture barrierFuture = notifyBarrier.getFuture(); barrierFuture.setSuccess(); } } else { Throwable cause = bindFuture.getCause(); String message = format("accept failed: %s", cause.getMessage()); progress.addScriptFailure(regionInfo, message); // fail each pipeline that required this bind to succeed List<ChannelPipeline> acceptedPipelines = configuration.getServerPipelines(regionInfo); for (ChannelPipeline acceptedPipeline : acceptedPipelines) { stopStream(acceptedPipeline); } } } }; } private ChannelFutureListener createConnectCompleteListener(final RegionInfo regionInfo) { return new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture connectFuture) throws Exception { if (connectFuture.isCancelled()) { // This is more that the connect never really fired, as in the case of a barrier, or the // the connect // is still in process here, so an empty line annotates that it did not do a connect, an // actual connect // failure should fail the future progress.addScriptFailure(regionInfo, ""); } else if (!connectFuture.isSuccess()) { Throwable cause = connectFuture.getCause(); String message = format("connect failed: %s", cause.getMessage()); progress.addScriptFailure(regionInfo, message); } } }; } private ChannelFutureListener createStreamCompletionListener() { return new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture completionFuture) throws Exception { if (!completionFuture.isSuccess()) { Throwable cause = completionFuture.getCause(); if (cause instanceof ScriptProgressException) { ScriptProgressException exception = (ScriptProgressException) cause; progress.addScriptFailure(exception.getRegionInfo(), exception.getMessage()); } else { LOGGER.warn("Unexpected exception", cause); } } } }; } private ChannelFutureListener createScriptCompletionListener() { ChannelFutureListener executionListener = new ChannelFutureListener() { @Override public void operationComplete(final ChannelFuture future) throws Exception { if (LOGGER.isDebugEnabled()) { // detect observed script String observedScript = progress.getObservedScript(); LOGGER.debug("Observed script:\n" + observedScript); } if (abortedFuture.isDone()) { // abort complete, trigger finished future finishedFuture.setSuccess(); } else { // execution complete, trigger finished future finishedFuture.setSuccess(); } } }; return executionListener; } private ChannelFutureListener createStopConfigurationListener() { return new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { stopConfiguration(); } }; } @Sharable private static final class CloseOnExceptionHandler extends SimpleChannelHandler { @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { // avoid stack overflow when exception happens on close if (TRUE != ctx.getAttachment()) { ctx.setAttachment(TRUE); // close channel and avoid warning logged by default exceptionCaught implementation Channel channel = ctx.getChannel(); channel.close(); } else { // log exception during close super.exceptionCaught(ctx, e); } } } public Map<String, Barrier> getBarriersByName() { return barriersByName; } public void notifyBarrier(String barrierName) throws Exception { final Barrier barrier = barriersByName.get(barrierName); if (barrier == null) { throw new Exception( "Can not notify a barrier that does not exist in the script: " + barrierName); } barrier.getFuture().setSuccess(); } public ChannelFuture awaitBarrier(String barrierName) throws Exception { final Barrier barrier = barriersByName.get(barrierName); if (barrier == null) { throw new Exception( "Can not notify a barrier that does not exist in the script: " + barrierName); } return barrier.getFuture(); } }