/driver-core/src/main/com/mongodb/connection/InternalStreamConnectionInitializer.java
http://github.com/mongodb/mongo-java-driver · Java · 206 lines · 166 code · 25 blank · 15 comment · 30 complexity · 922cb8057f2de778e547452b0e5b54d1 MD5 · raw file
- /*
- * Copyright (c) 2008-2014 MongoDB, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.mongodb.connection;
- import com.mongodb.async.SingleResultCallback;
- import org.bson.BsonDocument;
- import org.bson.BsonInt32;
- import java.util.List;
- import java.util.concurrent.atomic.AtomicInteger;
- import static com.mongodb.assertions.Assertions.notNull;
- import static com.mongodb.connection.CommandHelper.executeCommand;
- import static com.mongodb.connection.CommandHelper.executeCommandAsync;
- import static com.mongodb.connection.CommandHelper.executeCommandWithoutCheckingForFailure;
- import static com.mongodb.connection.DescriptionHelper.createConnectionDescription;
- class InternalStreamConnectionInitializer implements InternalConnectionInitializer {
- private final List<Authenticator> authenticators;
- InternalStreamConnectionInitializer(final List<Authenticator> authenticators) {
- this.authenticators = notNull("authenticators", authenticators);
- }
- @Override
- public ConnectionDescription initialize(final InternalConnection internalConnection) {
- notNull("internalConnection", internalConnection);
- ConnectionDescription connectionDescription = initializeConnectionDescription(internalConnection);
- authenticateAll(internalConnection, connectionDescription);
- return completeConnectionDescriptionInitialization(internalConnection, connectionDescription);
- }
- @Override
- public void initializeAsync(final InternalConnection internalConnection, final SingleResultCallback<ConnectionDescription> callback) {
- initializeConnectionDescriptionAsync(internalConnection, createConnectionDescriptionCallback(internalConnection, callback));
- }
- private SingleResultCallback<ConnectionDescription>
- createConnectionDescriptionCallback(final InternalConnection internalConnection,
- final SingleResultCallback<ConnectionDescription> callback) {
- return new SingleResultCallback<ConnectionDescription>() {
- @Override
- public void onResult(final ConnectionDescription connectionDescription, final Throwable t) {
- if (t != null) {
- callback.onResult(null, t);
- } else {
- new CompoundAuthenticator(internalConnection, connectionDescription,
- new SingleResultCallback<Void>() {
- @Override
- public void onResult(final Void result, final Throwable t) {
- if (t != null) {
- callback.onResult(null, t);
- } else {
- completeConnectionDescriptionInitializationAsync(internalConnection,
- connectionDescription,
- callback);
- }
- }
- })
- .start();
- }
- }
- };
- }
- private ConnectionDescription initializeConnectionDescription(final InternalConnection internalConnection) {
- BsonDocument isMasterResult = executeCommand("admin", new BsonDocument("ismaster", new BsonInt32(1)), internalConnection);
- BsonDocument buildInfoResult = executeCommand("admin", new BsonDocument("buildinfo", new BsonInt32(1)), internalConnection);
- return createConnectionDescription(internalConnection.getDescription().getConnectionId(), isMasterResult, buildInfoResult);
- }
- private ConnectionDescription completeConnectionDescriptionInitialization(final InternalConnection internalConnection,
- final ConnectionDescription connectionDescription) {
- return applyGetLastErrorResult(executeCommandWithoutCheckingForFailure("admin",
- new BsonDocument("getlasterror", new BsonInt32(1)),
- internalConnection),
- connectionDescription);
- }
- private void authenticateAll(final InternalConnection internalConnection, final ConnectionDescription connectionDescription) {
- if (connectionDescription.getServerType() != ServerType.REPLICA_SET_ARBITER) {
- for (final Authenticator cur : authenticators) {
- cur.authenticate(internalConnection, connectionDescription);
- }
- }
- }
- private void initializeConnectionDescriptionAsync(final InternalConnection internalConnection,
- final SingleResultCallback<ConnectionDescription> callback) {
- executeCommandAsync("admin", new BsonDocument("ismaster", new BsonInt32(1)), internalConnection,
- new SingleResultCallback<BsonDocument>() {
- @Override
- public void onResult(final BsonDocument isMasterResult, final Throwable t) {
- if (t != null) {
- callback.onResult(null, t);
- } else {
- executeCommandAsync("admin", new BsonDocument("buildinfo", new BsonInt32(1)), internalConnection,
- new SingleResultCallback<BsonDocument>() {
- @Override
- public void onResult(final BsonDocument buildInfoResult,
- final Throwable t) {
- if (t != null) {
- callback.onResult(null, t);
- } else {
- ConnectionId connectionId = internalConnection.getDescription()
- .getConnectionId();
- callback.onResult(createConnectionDescription(connectionId,
- isMasterResult,
- buildInfoResult),
- null);
- }
- }
- });
- }
- }
- });
- }
- private void completeConnectionDescriptionInitializationAsync(final InternalConnection internalConnection,
- final ConnectionDescription connectionDescription,
- final SingleResultCallback<ConnectionDescription> callback) {
- executeCommandAsync("admin", new BsonDocument("getlasterror", new BsonInt32(1)),
- internalConnection,
- new SingleResultCallback<BsonDocument>() {
- @Override
- public void onResult(final BsonDocument result, final Throwable t) {
- if (result == null) {
- callback.onResult(connectionDescription, null);
- } else {
- callback.onResult(applyGetLastErrorResult(result, connectionDescription), null);
- }
- }
- });
- }
- private ConnectionDescription applyGetLastErrorResult(final BsonDocument getLastErrorResult,
- final ConnectionDescription connectionDescription) {
- ConnectionId connectionId;
- if (getLastErrorResult.containsKey("connectionId")) {
- connectionId = connectionDescription.getConnectionId().withServerValue(getLastErrorResult.getNumber("connectionId").intValue());
- } else {
- connectionId = connectionDescription.getConnectionId();
- }
- return connectionDescription.withConnectionId(connectionId);
- }
- private class CompoundAuthenticator implements SingleResultCallback<Void> {
- private final InternalConnection internalConnection;
- private final ConnectionDescription connectionDescription;
- private final SingleResultCallback<Void> callback;
- private final AtomicInteger currentAuthenticatorIndex = new AtomicInteger(-1);
- public CompoundAuthenticator(final InternalConnection internalConnection, final ConnectionDescription connectionDescription,
- final SingleResultCallback<Void> callback) {
- this.internalConnection = internalConnection;
- this.connectionDescription = connectionDescription;
- this.callback = callback;
- }
- @Override
- public void onResult(final Void result, final Throwable t) {
- if (t != null) {
- callback.onResult(null, t);
- } else if (completedAuthentication()) {
- callback.onResult(null, null);
- } else {
- authenticateNext();
- }
- }
- public void start() {
- if (connectionDescription.getServerType() == ServerType.REPLICA_SET_ARBITER || authenticators.isEmpty()) {
- callback.onResult(null, null);
- } else {
- authenticateNext();
- }
- }
- private boolean completedAuthentication() {
- return currentAuthenticatorIndex.get() == authenticators.size() - 1;
- }
- private void authenticateNext() {
- authenticators.get(currentAuthenticatorIndex.incrementAndGet())
- .authenticateAsync(internalConnection, connectionDescription, this);
- }
- }
- }