/** Test method for {@link X509Authenticator#startAuthentication(Credential, Connection)} . */ @Test public void testStartAuthentication() { final Credential credential = Credential.builder().userName("CN=foo").build(); final Connection mockConnection = createMock(Connection.class); final Capture<ReplyCallback> capture = new Capture<ReplyCallback>(); final DocumentBuilder b = BuilderFactory.start(); b.add("authenticate", 1); b.add("user", "CN=foo"); b.add("mechanism", X509Authenticator.MECHANISM); mockConnection.send( eq(new Command(X509Authenticator.EXTERNAL, Command.COMMAND_COLLECTION, b.build())), capture(capture)); expectLastCall(); replay(mockConnection); final X509Authenticator auth = new X509Authenticator(); auth.startAuthentication(credential, mockConnection); verify(mockConnection); assertThat(capture.getValue(), instanceOf(X509ResponseCallback.class)); }
/** * Re-bootstraps the environment. Normally this method is only called once during the constructor * of the factory to initialize the delegate but users can reset the delegate by manually invoking * this method. * * <p>A bootstrap will issue one commands to the first working MongoDB process. The reply to the * {@link IsMaster} command is used to detect connecting to a mongos <tt>process</tt> and by * extension a Sharded configuration. * * <p>If not using a Sharded configuration then the server status is checked for a <tt>repl</tt> * element. If present a Replication Set configuration is assumed. * * <p>If neither a Sharded or Replication Set is being used then a plain socket connection factory * is used. */ protected void bootstrap() { final SocketConnectionFactory socketFactory = createSocketFactory(myConfig); socketFactory.setMetrics(myMetrics); ProxiedConnectionFactory factory = socketFactory; // Authentication has to be right on top of the physical // connection. if (myConfig.isAuthenticating()) { factory = new AuthenticationConnectionFactory(factory, myConfig); } try { // Use the socket factories cluster. final Cluster cluster = socketFactory.getCluster(); for (final InetSocketAddress addr : myConfig.getServerAddresses()) { Connection conn = null; final FutureReplyCallback future = new FutureReplyCallback(); try { conn = factory.connect(cluster.add(addr), myConfig); conn.send(new IsMaster(), future); final Reply reply = future.get(); // Close the connection now that we have the reply. IOUtils.close(conn); final List<Document> results = reply.getResults(); if (!results.isEmpty()) { final Document doc = results.get(0); if (isMongos(doc)) { LOG.debug("Sharded bootstrap to {}.", addr); cluster.clear(); // not needed. myDelegate = bootstrapSharded(factory); } else if (isReplicationSet(doc)) { LOG.debug("Replica-set bootstrap to {}.", addr); cluster.clear(); // not needed. myDelegate = bootstrapReplicaSet(factory); } else { LOG.debug("Simple MongoDB bootstrap to {}.", addr); myDelegate = factory; } factory = null; // Don't close. return; } } catch (final IOException ioe) { LOG.warn(ioe, "I/O error during bootstrap to {}.", addr); } catch (final InterruptedException e) { LOG.warn(e, "Interrupted during bootstrap to {}.", addr); } catch (final ExecutionException e) { LOG.warn(e, "Error during bootstrap to {}.", addr); } finally { IOUtils.close( conn, Level.WARNING, "I/O error shutting down bootstrap connection to " + addr + "."); } } } finally { IOUtils.close(factory); } }