use of org.jboss.netty.channel.ChannelFutureListener in project camel by apache.
the class NettyProducer method openChannel.
protected Channel openChannel(ChannelFuture channelFuture) throws Exception {
// blocking for channel to be done
if (LOG.isTraceEnabled()) {
LOG.trace("Waiting for operation to complete {} for {} millis", channelFuture, configuration.getConnectTimeout());
}
// here we need to wait it in other thread
final CountDownLatch channelLatch = new CountDownLatch(1);
channelFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture cf) throws Exception {
channelLatch.countDown();
}
});
try {
channelLatch.await(configuration.getConnectTimeout(), TimeUnit.MILLISECONDS);
} catch (InterruptedException ex) {
throw new CamelException("Interrupted while waiting for " + "connection to " + configuration.getAddress());
}
if (!channelFuture.isDone() || !channelFuture.isSuccess()) {
ConnectException cause = new ConnectException("Cannot connect to " + configuration.getAddress());
if (channelFuture.getCause() != null) {
cause.initCause(channelFuture.getCause());
}
throw cause;
}
Channel answer = channelFuture.getChannel();
// to keep track of all channels in use
allChannels.add(answer);
if (LOG.isDebugEnabled()) {
LOG.debug("Creating connector to address: {}", configuration.getAddress());
}
return answer;
}
use of org.jboss.netty.channel.ChannelFutureListener in project Protocol-Adapter-OSLP by OSGP.
the class OslpChannelHandlerClient method send.
public void send(final InetSocketAddress address, final OslpEnvelope request, final OslpResponseHandler responseHandler, final String deviceIdentification) throws IOException {
LOGGER.info("Sending OSLP request: {}", request.getPayloadMessage());
// Open connection and send message.
final ChannelFuture channelFuture = this.bootstrap.connect(address);
this.callbackHandlers.put(channelFuture.getChannel().getId(), new OslpCallbackHandler(responseHandler));
channelFuture.addListener(new ChannelFutureListener() {
@Autowired
protected DeviceResponseMessageSender responseMessageSender;
@Override
public void operationComplete(final ChannelFuture future) throws Exception {
if (future.isSuccess()) {
OslpChannelHandlerClient.this.write(future, address, request);
// What is this call below good for?
future.getChannel().getId();
} else {
LOGGER.info("The connection to the device {} is not successful", deviceIdentification);
throw new IOException("ChannelFuture - Unable to connect");
}
}
});
}
use of org.jboss.netty.channel.ChannelFutureListener in project druid by druid-io.
the class NettyHttpClient method go.
@Override
public <Intermediate, Final> ListenableFuture<Final> go(final Request request, final HttpResponseHandler<Intermediate, Final> handler, final Duration requestReadTimeout) {
final HttpMethod method = request.getMethod();
final URL url = request.getUrl();
final Multimap<String, String> headers = request.getHeaders();
final String requestDesc = method + " " + url;
if (log.isDebugEnabled()) {
log.debug("[%s] starting", requestDesc);
}
// Block while acquiring a channel from the pool, then complete the request asynchronously.
final Channel channel;
final String hostKey = getPoolKey(url);
final ResourceContainer<ChannelFuture> channelResourceContainer = pool.take(hostKey);
final ChannelFuture channelFuture = channelResourceContainer.get().awaitUninterruptibly();
if (!channelFuture.isSuccess()) {
// Some other poor sap will have to deal with it...
channelResourceContainer.returnResource();
return Futures.immediateFailedFuture(new ChannelException("Faulty channel in resource pool", channelFuture.getCause()));
} else {
channel = channelFuture.getChannel();
// In case we get a channel that never had its readability turned back on.
channel.setReadable(true);
}
final String urlFile = StringUtils.nullToEmptyNonDruidDataString(url.getFile());
final HttpRequest httpRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, method, urlFile.isEmpty() ? "/" : urlFile);
if (!headers.containsKey(HttpHeaders.Names.HOST)) {
httpRequest.headers().add(HttpHeaders.Names.HOST, getHost(url));
}
// If Accept-Encoding is set in the Request, use that. Otherwise use the default from "compressionCodec".
if (!headers.containsKey(HttpHeaders.Names.ACCEPT_ENCODING)) {
httpRequest.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, compressionCodec.getEncodingString());
}
for (Map.Entry<String, Collection<String>> entry : headers.asMap().entrySet()) {
String key = entry.getKey();
for (String obj : entry.getValue()) {
httpRequest.headers().add(key, obj);
}
}
if (request.hasContent()) {
httpRequest.setContent(request.getContent());
}
final long readTimeout = getReadTimeout(requestReadTimeout);
final SettableFuture<Final> retVal = SettableFuture.create();
if (readTimeout > 0) {
channel.getPipeline().addLast(READ_TIMEOUT_HANDLER_NAME, new ReadTimeoutHandler(timer, readTimeout, TimeUnit.MILLISECONDS));
}
channel.getPipeline().addLast(LAST_HANDLER_NAME, new SimpleChannelUpstreamHandler() {
private volatile ClientResponse<Intermediate> response = null;
// Chunk number most recently assigned.
private long currentChunkNum = 0;
// Suspend and resume watermarks (respectively: last chunk number that triggered a suspend, and that was
// provided to the TrafficCop's resume method). Synchronized access since they are not always accessed
// from an I/O thread. (TrafficCops can be called from any thread.)
private final Object watermarkLock = new Object();
private long suspendWatermark = -1;
private long resumeWatermark = -1;
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
if (log.isDebugEnabled()) {
log.debug("[%s] messageReceived: %s", requestDesc, e.getMessage());
}
try {
Object msg = e.getMessage();
if (msg instanceof HttpResponse) {
HttpResponse httpResponse = (HttpResponse) msg;
if (log.isDebugEnabled()) {
log.debug("[%s] Got response: %s", requestDesc, httpResponse.getStatus());
}
HttpResponseHandler.TrafficCop trafficCop = resumeChunkNum -> {
synchronized (watermarkLock) {
resumeWatermark = Math.max(resumeWatermark, resumeChunkNum);
if (suspendWatermark >= 0 && resumeWatermark >= suspendWatermark) {
suspendWatermark = -1;
channel.setReadable(true);
long backPressureDuration = System.nanoTime() - backPressureStartTimeNs;
log.debug("[%s] Resumed reads from channel (chunkNum = %,d).", requestDesc, resumeChunkNum);
return backPressureDuration;
}
}
// If we didn't resume, don't know if backpressure was happening
return 0;
};
response = handler.handleResponse(httpResponse, trafficCop);
if (response.isFinished()) {
retVal.set((Final) response.getObj());
}
assert currentChunkNum == 0;
possiblySuspendReads(response);
if (!httpResponse.isChunked()) {
finishRequest();
}
} else if (msg instanceof HttpChunk) {
HttpChunk httpChunk = (HttpChunk) msg;
if (log.isDebugEnabled()) {
log.debug("[%s] Got chunk: %sB, last=%s", requestDesc, httpChunk.getContent().readableBytes(), httpChunk.isLast());
}
if (httpChunk.isLast()) {
finishRequest();
} else {
response = handler.handleChunk(response, httpChunk, ++currentChunkNum);
if (response.isFinished() && !retVal.isDone()) {
retVal.set((Final) response.getObj());
}
possiblySuspendReads(response);
}
} else {
throw new ISE("Unknown message type[%s]", msg.getClass());
}
} catch (Exception ex) {
log.warn(ex, "[%s] Exception thrown while processing message, closing channel.", requestDesc);
if (!retVal.isDone()) {
retVal.set(null);
}
channel.close();
channelResourceContainer.returnResource();
throw ex;
}
}
private void possiblySuspendReads(ClientResponse<?> response) {
if (!response.isContinueReading()) {
synchronized (watermarkLock) {
suspendWatermark = Math.max(suspendWatermark, currentChunkNum);
if (suspendWatermark > resumeWatermark) {
channel.setReadable(false);
backPressureStartTimeNs = System.nanoTime();
log.debug("[%s] Suspended reads from channel (chunkNum = %,d).", requestDesc, currentChunkNum);
}
}
}
}
private void finishRequest() {
ClientResponse<Final> finalResponse = handler.done(response);
if (!finalResponse.isFinished() || !finalResponse.isContinueReading()) {
throw new ISE("[%s] Didn't get a completed ClientResponse Object from [%s] (finished = %s, continueReading = %s)", requestDesc, handler.getClass(), finalResponse.isFinished(), finalResponse.isContinueReading());
}
if (!retVal.isDone()) {
retVal.set(finalResponse.getObj());
}
removeHandlers();
channel.setReadable(true);
channelResourceContainer.returnResource();
}
@Override
public void exceptionCaught(ChannelHandlerContext context, ExceptionEvent event) {
if (log.isDebugEnabled()) {
final Throwable cause = event.getCause();
if (cause == null) {
log.debug("[%s] Caught exception", requestDesc);
} else {
log.debug(cause, "[%s] Caught exception", requestDesc);
}
}
retVal.setException(event.getCause());
// response is non-null if we received initial chunk and then exception occurs
if (response != null) {
handler.exceptionCaught(response, event.getCause());
}
try {
if (channel.isOpen()) {
channel.close();
}
} catch (Exception e) {
log.warn(e, "Error while closing channel");
} finally {
channelResourceContainer.returnResource();
}
}
@Override
public void channelDisconnected(ChannelHandlerContext context, ChannelStateEvent event) {
if (log.isDebugEnabled()) {
log.debug("[%s] Channel disconnected", requestDesc);
}
// response is non-null if we received initial chunk and then exception occurs
if (response != null) {
handler.exceptionCaught(response, new ChannelException("Channel disconnected"));
}
channel.close();
channelResourceContainer.returnResource();
if (!retVal.isDone()) {
log.warn("[%s] Channel disconnected before response complete", requestDesc);
retVal.setException(new ChannelException("Channel disconnected"));
}
}
private void removeHandlers() {
if (readTimeout > 0) {
channel.getPipeline().remove(READ_TIMEOUT_HANDLER_NAME);
}
channel.getPipeline().remove(LAST_HANDLER_NAME);
}
});
channel.write(httpRequest).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
if (!future.isSuccess()) {
channel.close();
channelResourceContainer.returnResource();
if (!retVal.isDone()) {
retVal.setException(new ChannelException(StringUtils.format("[%s] Failed to write request to channel", requestDesc), future.getCause()));
}
}
}
});
return retVal;
}
use of org.jboss.netty.channel.ChannelFutureListener in project druid by druid-io.
the class ChannelResourceFactory method generate.
@Override
public ChannelFuture generate(final String hostname) {
log.debug("Generating: %s", hostname);
URL url;
try {
url = new URL(hostname);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
final String host = url.getHost();
final int port = url.getPort() == -1 ? url.getDefaultPort() : url.getPort();
final ChannelFuture retVal;
final ChannelFuture connectFuture;
if (proxyConfig != null) {
final ChannelFuture proxyFuture = bootstrap.connect(new InetSocketAddress(proxyConfig.getHost(), proxyConfig.getPort()));
connectFuture = Channels.future(proxyFuture.getChannel());
final String proxyUri = StringUtils.format("%s:%d", host, port);
DefaultHttpRequest connectRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.CONNECT, proxyUri);
if (proxyConfig.getUser() != null) {
connectRequest.headers().add("Proxy-Authorization", Request.makeBasicAuthenticationString(proxyConfig.getUser(), proxyConfig.getPassword()));
}
proxyFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture f1) {
if (f1.isSuccess()) {
final Channel channel = f1.getChannel();
channel.getPipeline().addLast(DRUID_PROXY_HANDLER, new SimpleChannelUpstreamHandler() {
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
Object msg = e.getMessage();
final ChannelPipeline pipeline = ctx.getPipeline();
pipeline.remove(DRUID_PROXY_HANDLER);
if (msg instanceof HttpResponse) {
HttpResponse httpResponse = (HttpResponse) msg;
if (HttpResponseStatus.OK.equals(httpResponse.getStatus())) {
// When the HttpClientCodec sees the CONNECT response complete, it goes into a "done"
// mode which makes it just do nothing. Swap it with a new instance that will cover
// subsequent requests
pipeline.replace("codec", "codec", new HttpClientCodec());
connectFuture.setSuccess();
} else {
connectFuture.setFailure(new ChannelException(StringUtils.format("Got status[%s] from CONNECT request to proxy[%s]", httpResponse.getStatus(), proxyUri)));
}
} else {
connectFuture.setFailure(new ChannelException(StringUtils.format("Got message of type[%s], don't know what to do.", msg.getClass())));
}
}
});
channel.write(connectRequest).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture f2) {
if (!f2.isSuccess()) {
connectFuture.setFailure(new ChannelException(StringUtils.format("Problem with CONNECT request to proxy[%s]", proxyUri), f2.getCause()));
}
}
});
} else {
connectFuture.setFailure(new ChannelException(StringUtils.format("Problem connecting to proxy[%s]", proxyUri), f1.getCause()));
}
}
});
} else {
connectFuture = bootstrap.connect(new InetSocketAddress(host, port));
}
if ("https".equals(url.getProtocol())) {
if (sslContext == null) {
throw new IllegalStateException("No sslContext set, cannot do https");
}
final SSLEngine sslEngine = sslContext.createSSLEngine(host, port);
final SSLParameters sslParameters = new SSLParameters();
sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
sslEngine.setSSLParameters(sslParameters);
sslEngine.setUseClientMode(true);
final SslHandler sslHandler = new SslHandler(sslEngine, SslHandler.getDefaultBufferPool(), false, timer, sslHandshakeTimeout);
// https://github.com/netty/netty/issues/160
sslHandler.setCloseOnSSLException(true);
final ChannelFuture handshakeFuture = Channels.future(connectFuture.getChannel());
connectFuture.getChannel().getPipeline().addLast("connectionErrorHandler", new SimpleChannelUpstreamHandler() {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
final Channel channel = ctx.getChannel();
if (channel == null) {
// For the case where this pipeline is not attached yet.
handshakeFuture.setFailure(new ChannelException(StringUtils.format("Channel is null. The context name is [%s]", ctx.getName())));
return;
}
handshakeFuture.setFailure(e.getCause());
if (channel.isOpen()) {
channel.close();
}
}
});
connectFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture f) {
if (f.isSuccess()) {
final ChannelPipeline pipeline = f.getChannel().getPipeline();
pipeline.addFirst("ssl", sslHandler);
sslHandler.handshake().addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture f2) {
if (f2.isSuccess()) {
handshakeFuture.setSuccess();
} else {
handshakeFuture.setFailure(new ChannelException(StringUtils.format("Failed to handshake with host[%s]", hostname), f2.getCause()));
}
}
});
} else {
handshakeFuture.setFailure(new ChannelException(StringUtils.format("Failed to connect to host[%s]", hostname), f.getCause()));
}
}
});
retVal = handshakeFuture;
} else {
retVal = connectFuture;
}
return retVal;
}
use of org.jboss.netty.channel.ChannelFutureListener in project jstorm by alibaba.
the class NettyClient method doReconnect.
/**
* The function can't be synchronized, otherwise it will cause deadlock
*/
public void doReconnect() {
if (channelRef.get() != null) {
// }
return;
}
if (isClosed()) {
return;
}
if (isConnecting.getAndSet(true)) {
LOG.info("Connect twice {}", name());
return;
}
long sleepMs = getSleepTimeMs();
LOG.info("Reconnect ... [{}], {}, sleep {}ms", retries.get(), name, sleepMs);
ChannelFuture future = bootstrap.connect(remoteAddr);
future.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) throws Exception {
isConnecting.set(false);
Channel channel = future.getChannel();
if (future.isSuccess()) {
// do something else
LOG.info("Connection established, channel = :{}", channel);
setChannel(channel);
// handleResponse();
BATCH_THRESHOLD_WARN = ConfigExtension.getNettyBufferThresholdSize(stormConf);
// Check if any pending message
/*synchronized (writeLock) {
if (channel != null && messageBuffer.size() > 0) {
MessageBatch messageBatch = messageBuffer.drain();
flushRequest(channel, messageBatch);
} else {
LOG.warn("Failed to flush pending message after reconnecting, channel={}, messageBuffer.size={}",
channel, messageBuffer.size());
}
}*/
} else {
if (!isClosed()) {
LOG.info("Failed to reconnect ... [{}], {}, channel = {}, cause = {}", retries.get(), name, channel, future.getCause());
reconnect();
}
}
}
});
JStormUtils.sleepMs(sleepMs);
}
Aggregations