static VersionedConnection createVersionedConnection( final Channel channel, final Map<String, ?> environment, final JMXServiceURL serviceURL) throws IOException { // We don't want to start chaining the use of IoFutures otherwise multiple threads are tied up // for a single negotiation process so negotiate the connection sequentially. IoFuture<InitialHeader> futureHeader = ClientVersionReceiver.getInitialHeader(channel); IoFuture.Status result = futureHeader.await(5, TimeUnit.SECONDS); switch (result) { case DONE: break; case FAILED: throw futureHeader.getException(); default: throw new IOException("Timeout out waiting for header, status=" + result.toString()); } InitialHeader header = futureHeader.get(); Versions versions = new Versions(environment); Set<Byte> supportedVersions = versions.getSupportedVersions(getRequiredCapabilities(serviceURL)); // Find the highest version. - By this point the exceptional handling of version 0x00 will have // completed. byte highest = 0x00; for (byte current : header.versions) { // Only accept it if it is one of the supported versions otherwise ignore as noise. if (supportedVersions.contains(current) && current > highest) { highest = current; } } if (highest == 0x00) { throw new IllegalStateException("No matching supported protocol version found."); } // getVersionedConnection may also make use of an IoFuture but our previous use of one has // ended. return versions.getVersionedConnection(highest, channel, serviceURL); }
public Connection connectSync( CallbackHandler handler, Map<String, String> saslOptions, SSLContext sslContext) throws IOException { CallbackHandler actualHandler = handler != null ? handler : new AnonymousCallbackHandler(); WrapperCallbackHandler wrapperHandler = new WrapperCallbackHandler(actualHandler); final IoFuture<Connection> future = connect(wrapperHandler, saslOptions, sslContext); long timeoutMillis = configuration.getConnectionTimeout(); IoFuture.Status status = future.await(timeoutMillis, TimeUnit.MILLISECONDS); while (status == IoFuture.Status.WAITING) { if (wrapperHandler.isInCall()) { // If there is currently an interaction with the user just wait again. status = future.await(timeoutMillis, TimeUnit.MILLISECONDS); } else { long lastInteraction = wrapperHandler.getCallFinished(); if (lastInteraction > 0) { long now = System.currentTimeMillis(); long timeSinceLast = now - lastInteraction; if (timeSinceLast < timeoutMillis) { // As this point we are setting the timeout based on the time of the last interaction // with the user, if there is any time left we will wait for that time but dont wait for // a full timeout. status = future.await(timeoutMillis - timeSinceLast, TimeUnit.MILLISECONDS); } else { status = null; } } else { status = null; // Just terminate status processing. } } } if (status == IoFuture.Status.DONE) { return future.get(); } if (status == IoFuture.Status.FAILED) { throw ProtocolMessages.MESSAGES.failedToConnect(uri, future.getException()); } throw ProtocolMessages.MESSAGES.couldNotConnect(uri); }