com.ca.apm.mongo.Topology.java Source code

Java tutorial

Introduction

Here is the source code for com.ca.apm.mongo.Topology.java

Source

/*
 *
 * Copyright (c) 2014 CA. All rights reserved.
 *
 * 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.
    
 * IN NO EVENT WILL CA BE LIABLE TO THE END USER OR ANY THIRD PARTY FOR ANY LOSS
 * OR DAMAGE, DIRECT OR INDIRECT, FROM THE USE OF THIS MATERIAL,
 * INCLUDING WITHOUT LIMITATION, LOST PROFITS, BUSINESS INTERRUPTION, GOODWILL,
 * OR LOST DATA, EVEN IF CA IS EXPRESSLY ADVISED OF SUCH LOSS OR DAMAGE.
 *
 */
package com.ca.apm.mongo;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Logger;
import java.util.logging.Level;

import javax.net.ssl.SSLSocketFactory;

import com.mongodb.CommandResult;
import com.mongodb.DB;
import com.mongodb.MongoCredential;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress;

public abstract class Topology {

    protected enum ClusterType {
        STANDALONE("Standalone Mongod"), REPLICA_SET("Replica Set"), SHARDED_CLUSTER("Sharded Cluster");

        private String name;

        private ClusterType(String inName) {
            name = inName;
        }

        @Override
        public String toString() {
            return name;
        }
    }

    protected Logger logger;

    private Properties props;
    private List<MongoCredential> mongoCreds = new ArrayList<MongoCredential>();
    protected String dbHost;
    protected int dbPort;

    protected ClusterType type;

    protected Set<String> members = new HashSet<String>();

    protected Topology(final Properties props, final String host, final int port, final Logger l,
            final ClusterType t) {
        this.props = props;
        Collector.setupCreds(mongoCreds, props);
        setConnProps(host, port);
        setLogger(l);
        type = t;
    }

    public void setConnProps(final String host, final int port) {
        this.dbHost = host;
        this.dbPort = port;
    }

    public void setLogger(final Logger logger) {
        this.logger = logger;
    }

    abstract void discoverServers(final String nodeType) throws Exception;

    public List<String> getDiscoveredServers() {
        return new ArrayList<String>(members);
    }

    protected List<String> discoverReplicas(final String host, final int port) throws Exception {

        List<String> replicas = new ArrayList<String>();

        final CommandResult cr = dbAdminCmd(host, port, "isMaster");

        replicas.addAll((List<String>) cr.get("hosts"));
        // hidden replicas are replicas that cannot become primaries and
        // are hidden to the client app
        if (cr.getBoolean("hidden")) {
            // TODO: We can't assume we're the master here....
            replicas.add(cr.getString("me"));
        }
        // passives are replicas that cannot become primaries because
        // their priority is set to 0
        if (cr.containsField("passives")) {
            replicas.addAll((List<String>) cr.get("passives"));
        }
        // arbiters exist only to vote in master elections.  They don't
        // actually hold replica data.
        if (cr.containsField("arbiters")) {
            replicas.addAll((List<String>) cr.get("arbiters"));
        }
        return replicas;
    }

    protected CommandResult dbAdminCmd(final String host, final int port, final String cmd) throws Exception {
        return runDBCmd(host, port, "admin", cmd);
    }

    private CommandResult runDBCmd(final String host, final int port, final String database, final String cmd)
            throws Exception {
        MongoClient dbClient = null;
        try {
            dbClient = setupDbClient(host, port);
            DB db = dbClient.getDB(database);
            return db.command(cmd);
        } finally {
            if (dbClient != null) {
                dbClient.close();
            }
        }
    }

    protected MongoClient setupDbClient(final String dbHost, final int dbPort) {
        final boolean useSSL = Collector.getBooleanProp(Collector.USE_SSL_PROP, props);
        final String clientTrustStore = Collector.getOptionalStringProp(Collector.SSL_CLIENT_TRUST_STORE_FILE_PROP,
                props);
        final String clientPasswd = Collector.getOptionalStringProp(Collector.SSL_CLIENT_TRUST_STORE_PASSWD_PROP,
                props);

        try {
            MongoClientOptions.Builder builder = new MongoClientOptions.Builder();

            if (useSSL) {
                System.setProperty(Collector.SSL_CLIENT_TRUST_STORE_FILE_PROP, clientTrustStore);
                System.setProperty(Collector.SSL_CLIENT_TRUST_STORE_PASSWD_PROP, clientPasswd);
                builder = builder.socketFactory(SSLSocketFactory.getDefault());
            }

            final MongoClientOptions options = builder.build();
            MongoClient dbClient = new MongoClient(new ServerAddress(dbHost, dbPort), mongoCreds, options);
            logger.log(Level.FINE, "Connected to mongo at {0}", dbClient.getConnectPoint());
            logger.log(Level.FINE, "Client options: " + dbClient.getMongoClientOptions());
            return dbClient;
        } catch (Exception ex) {
            throw new RuntimeException("Can't initialize mongo client", ex);
        }
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append(String.format("%s%n", type));
        for (String member : members) {
            sb.append("  Server: ");
            sb.append(member);
            sb.append("\n");
        }
        return sb.toString();
    }
}