/*
* Copyright 2016 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.ConnectionString;
import com.mongodb.ServerAddress;
import com.mongodb.event.ClusterListener;
import org.bson.BsonArray;
import org.bson.BsonDocument;
import org.bson.BsonInt32;
import util.JsonPoweredTestHelper;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static com.mongodb.connection.DescriptionHelper.createServerDescription;
import static com.mongodb.connection.DescriptionHelper.getVersion;
import static com.mongodb.connection.ServerConnectionState.CONNECTING;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
public class AbstractServerDiscoveryAndMonitoringTest {
private final BsonDocument definition;
private DefaultTestClusterableServerFactory factory;
private BaseCluster cluster;
public AbstractServerDiscoveryAndMonitoringTest(final BsonDocument definition) {
this.definition = definition;
}
public static Collection<Object[]> data(final String root) throws URISyntaxException, IOException {
List<Object[]> data = new ArrayList<Object[]>();
for (File file : JsonPoweredTestHelper.getTestFiles(root)) {
BsonDocument testDocument = JsonPoweredTestHelper.getTestDocument(file);
data.add(new Object[]{testDocument.getString("description").getValue(), testDocument});
}
return data;
}
protected void applyResponse(final BsonArray response) {
ServerAddress serverAddress = new ServerAddress(response.get(0).asString().getValue());
BsonDocument isMasterResult = response.get(1).asDocument();
ServerDescription serverDescription;
if (isMasterResult.isEmpty()) {
serverDescription = ServerDescription.builder().type(ServerType.UNKNOWN).state(CONNECTING).address(serverAddress).build();
} else {
serverDescription = createServerDescription(serverAddress, isMasterResult,
getVersion(new BsonDocument("versionArray",
new BsonArray(asList(new BsonInt32(2),
new BsonInt32(6),
new BsonInt32(0))))),
5000000);
}
factory.sendNotification(serverAddress, serverDescription);
}
protected ClusterType getClusterType(final String topologyType) {
return getClusterType(topologyType, Collections.<ServerDescription>emptyList());
}
protected ClusterType getClusterType(final String topologyType, final Collection<ServerDescription> serverDescriptions) {
if (topologyType.equalsIgnoreCase("Single")) {
assertEquals(1, serverDescriptions.size());
return serverDescriptions.iterator().next().getClusterType();
} else if (topologyType.equalsIgnoreCase("Sharded")) {
return ClusterType.SHARDED;
} else if (topologyType.startsWith("ReplicaSet")) {
return ClusterType.REPLICA_SET;
} else if (topologyType.equalsIgnoreCase("Unknown")) {
return ClusterType.UNKNOWN;
} else {
throw new IllegalArgumentException("Unsupported topology type: " + topologyType);
}
}
protected ServerType getServerType(final String serverTypeString) {
ServerType serverType;
if (serverTypeString.equals("RSPrimary")) {
serverType = ServerType.REPLICA_SET_PRIMARY;
} else if (serverTypeString.equals("RSSecondary")) {
serverType = ServerType.REPLICA_SET_SECONDARY;
} else if (serverTypeString.equals("RSArbiter")) {
serverType = ServerType.REPLICA_SET_ARBITER;
} else if (serverTypeString.equals("RSGhost")) {
serverType = ServerType.REPLICA_SET_GHOST;
} else if (serverTypeString.equals("RSOther")) {
serverType = ServerType.REPLICA_SET_OTHER;
} else if (serverTypeString.equals("Mongos")) {
serverType = ServerType.SHARD_ROUTER;
} else if (serverTypeString.equals("Standalone")) {
serverType = ServerType.STANDALONE;
} else if (serverTypeString.equals("PossiblePrimary")) {
serverType = ServerType.UNKNOWN;
} else if (serverTypeString.equals("Unknown")) {
serverType = ServerType.UNKNOWN;
} else {
throw new UnsupportedOperationException("No handler for server type " + serverTypeString);
}
return serverType;
}
protected void init(final ServerListenerFactory serverListenerFactory, final ClusterListener clusterListener) {
ConnectionString connectionString = new ConnectionString(definition.getString("uri").getValue());
ClusterConnectionMode mode = getMode(connectionString);
ClusterSettings settings = ClusterSettings.builder()
.serverSelectionTimeout(1, TimeUnit.SECONDS)
.hosts(getHosts(connectionString))
.mode(mode)
.requiredReplicaSetName(connectionString.getRequiredReplicaSetName())
.addClusterListener(clusterListener)
.build();
ClusterId clusterId = new ClusterId();
factory = new DefaultTestClusterableServerFactory(clusterId, mode, serverListenerFactory);
if (settings.getMode() == ClusterConnectionMode.SINGLE) {
cluster = new SingleServerCluster(clusterId, settings, factory);
} else {
cluster = new MultiServerCluster(clusterId, settings, factory);
}
}
private List<ServerAddress> getHosts(final ConnectionString connectionString) {
List<ServerAddress> serverAddresses = new ArrayList<ServerAddress>();
for (String host : connectionString.getHosts()) {
serverAddresses.add(new ServerAddress(host));
}
return serverAddresses;
}
private ClusterConnectionMode getMode(final ConnectionString connectionString) {
if (connectionString.getHosts().size() > 1 || connectionString.getRequiredReplicaSetName() != null) {
return ClusterConnectionMode.MULTIPLE;
} else {
return ClusterConnectionMode.SINGLE;
}
}
protected BsonDocument getDefinition() {
return definition;
}
protected DefaultTestClusterableServerFactory getFactory() {
return factory;
}
protected BaseCluster getCluster() {
return cluster;
}
}