@Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { if (LOG.isTraceEnabled()) { LOG.trace("Channel closed: {}", ctx.getChannel()); } Exchange exchange = getExchange(ctx); AsyncCallback callback = getAsyncCallback(ctx); // remove state producer.removeState(ctx.getChannel()); // to keep track of open sockets producer.getAllChannels().remove(ctx.getChannel()); if (producer.getConfiguration().isSync() && !messageReceived && !exceptionHandled) { // To avoid call the callback.done twice exceptionHandled = true; // session was closed but no message received. This could be because the remote server had an // internal error // and could not return a response. We should count down to stop waiting for a response if (LOG.isDebugEnabled()) { LOG.debug( "Channel closed but no message received from address: {}", producer.getConfiguration().getAddress()); } exchange.setException( new CamelExchangeException( "No response received from remote server: " + producer.getConfiguration().getAddress(), exchange)); // signal callback callback.done(false); } }
@Override public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent channelStateEvent) throws Exception { if (LOG.isTraceEnabled()) { LOG.trace("Channel open: {}", ctx.getChannel()); } // to keep track of open sockets producer.getAllChannels().add(channelStateEvent.getChannel()); }
/** * Gets the Camel {@link Message} to use as the message to be set on the current {@link Exchange} * when we have received a reply message. * * <p> * * @param exchange the current exchange * @param messageEvent the incoming event which has the response message from Netty. * @return the Camel {@link Message} to set on the current {@link Exchange} as the response * message. * @throws Exception is thrown if error getting the response message */ protected Message getResponseMessage(Exchange exchange, MessageEvent messageEvent) throws Exception { Object body = messageEvent.getMessage(); if (LOG.isDebugEnabled()) { LOG.debug("Channel: {} received body: {}", new Object[] {messageEvent.getChannel(), body}); } // if textline enabled then covert to a String which must be used for textline if (producer.getConfiguration().isTextline()) { body = producer.getContext().getTypeConverter().mandatoryConvertTo(String.class, exchange, body); } // set the result on either IN or OUT on the original exchange depending on its pattern if (ExchangeHelper.isOutCapable(exchange)) { NettyPayloadHelper.setOut(exchange, body); return exchange.getOut(); } else { NettyPayloadHelper.setIn(exchange, body); return exchange.getIn(); } }
private AsyncCallback getAsyncCallback(ChannelHandlerContext ctx) { NettyCamelState state = producer.getState(ctx.getChannel()); return state != null ? state.getCallback() : null; }
private Exchange getExchange(ChannelHandlerContext ctx) { NettyCamelState state = producer.getState(ctx.getChannel()); return state != null ? state.getExchange() : null; }
@Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent messageEvent) throws Exception { messageReceived = true; if (LOG.isTraceEnabled()) { LOG.trace("Message received: {}", messageEvent); } if (producer.getConfiguration().getRequestTimeout() > 0) { ChannelHandler handler = ctx.getPipeline().get("timeout"); if (handler != null) { LOG.trace("Removing timeout channel as we received message"); ctx.getPipeline().remove(handler); } } Exchange exchange = getExchange(ctx); if (exchange == null) { // we just ignore the received message as the channel is closed return; } AsyncCallback callback = getAsyncCallback(ctx); Message message; try { message = getResponseMessage(exchange, messageEvent); } catch (Exception e) { exchange.setException(e); callback.done(false); return; } // set the result on either IN or OUT on the original exchange depending on its pattern if (ExchangeHelper.isOutCapable(exchange)) { exchange.setOut(message); } else { exchange.setIn(message); } try { // should channel be closed after complete? Boolean close; if (ExchangeHelper.isOutCapable(exchange)) { close = exchange .getOut() .getHeader(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, Boolean.class); } else { close = exchange .getIn() .getHeader(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, Boolean.class); } // check the setting on the exchange property if (close == null) { close = exchange.getProperty(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, Boolean.class); } // should we disconnect, the header can override the configuration boolean disconnect = producer.getConfiguration().isDisconnect(); if (close != null) { disconnect = close; } if (disconnect) { if (LOG.isTraceEnabled()) { LOG.trace( "Closing channel when complete at address: {}", producer.getConfiguration().getAddress()); } NettyHelper.close(ctx.getChannel()); } } finally { // signal callback callback.done(false); } }