private Channel doGetConnection() throws ConnectionFailedException
{
ChannelWithIdleTime cwi;
while ((cwi = available.poll()) != null)
{
Channel channel = cwi.getChannel();
// If the channel from available is closed, try again. This will result in
// the caller always getting a connection or an exception. If closed
// the channel is simply discarded so this also acts as a purge
// for dead channels during a health check.
if (channel.isOpen())
{
return channel;
}
}
ChannelFuture f = bootstrap.connect();
try
{
f.await();
}
catch (InterruptedException ex)
{
logger.error("Thread interrupted waiting for new connection to be made; {}",
remoteAddress);
Thread.currentThread().interrupt();
throw new ConnectionFailedException(ex);
}
if (!f.isSuccess())
{
logger.error("Connection attempt failed: {}:{}; {}",
remoteAddress, port, f.cause());
consecutiveFailedConnectionAttempts.incrementAndGet();
throw new ConnectionFailedException(f.cause());
}
consecutiveFailedConnectionAttempts.set(0);
Channel c = f.channel();
if (trustStore != null)
{
SSLContext context;
try
{
context = SSLContext.getInstance("TLS");
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
context.init(null, tmf.getTrustManagers(), null);
}
catch (Exception ex)
{
c.close();
logger.error("Failure configuring SSL; {}:{} {}", remoteAddress, port, ex);
throw new ConnectionFailedException(ex);
}
SSLEngine engine = context.createSSLEngine();
Set<String> protocols = new HashSet<String>(Arrays.asList(engine.getSupportedProtocols()));
if (protocols.contains("TLSv1.2"))
{
engine.setEnabledProtocols(new String[] {"TLSv1.2"});
logger.debug("Using TLSv1.2");
}
else if (protocols.contains("TLSv1.1"))
{
engine.setEnabledProtocols(new String[] {"TLSv1.1"});
logger.debug("Using TLSv1.1");
}
engine.setUseClientMode(true);
RiakSecurityDecoder decoder = new RiakSecurityDecoder(engine, username, password);
c.pipeline().addFirst(decoder);
try
{
DefaultPromise<Void> promise = decoder.getPromise();
promise.await();
if (promise.isSuccess())
{
logger.debug("Auth succeeded; {}:{}", remoteAddress, port);
}
else
{
c.close();
logger.error("Failure during Auth; {}:{} {}",remoteAddress, port, promise.cause());
throw new ConnectionFailedException(promise.cause());
}
}
catch (InterruptedException e)
{
c.close();
logger.error("Thread interrupted during Auth; {}:{}",
remoteAddress, port);
Thread.currentThread().interrupt();
throw new ConnectionFailedException(e);
}