org.apache.whirr.service.mongodb.MongoDBReplSetMemberClusterActionHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.whirr.service.mongodb.MongoDBReplSetMemberClusterActionHandler.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.whirr.service.mongodb;

import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.CommandResult;
import java.io.IOException;
import java.util.Set;
import java.util.ArrayList;
import java.net.InetAddress;
import org.apache.commons.configuration.Configuration;
import org.apache.whirr.Cluster;
import org.apache.whirr.ClusterSpec;
import org.apache.whirr.service.ClusterActionEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.apache.whirr.RolePredicates.role;
import static org.apache.whirr.RolePredicates.anyRoleIn;
import static org.apache.whirr.service.FirewallManager.Rule;
import static org.jclouds.scriptbuilder.domain.Statements.call;
import com.google.common.collect.Sets;

public class MongoDBReplSetMemberClusterActionHandler extends BaseMongoDBClusterActionHandler {

    public static final String ROLE = "mongodb-replsetmember";
    public static final int PORT = 27017;
    private int arbiterPort = MongoDBArbiterClusterActionHandler.PORT;
    private static final String CFG_KEY_PORT = "mongodb.replset.port";
    private static final Logger LOG = LoggerFactory.getLogger(MongoDBReplSetMemberClusterActionHandler.class);

    public MongoDBReplSetMemberClusterActionHandler() {
        super(ROLE, PORT, CFG_KEY_PORT);
    }

    @Override
    protected void afterConfigure(ClusterActionEvent event) {
        ClusterSpec clusterSpec = event.getClusterSpec();
        Cluster cluster = event.getCluster();

        LOG.info("Configuring replica set members.");

        //Get all the instances that are marked as replica set members
        Set<String> replSetRoles = Sets.newHashSet(ROLE, MongoDBArbiterClusterActionHandler.ROLE);
        Set<Cluster.Instance> replSetInstances = cluster.getInstancesMatching(anyRoleIn(replSetRoles));
        //Just grab the first of these instances, use it to send the rs.initiate()
        Cluster.Instance setLeader = replSetInstances.iterator().next();

        try {
            Configuration config = getConfiguration(clusterSpec);
            this.arbiterPort = config.getInt(MongoDBArbiterClusterActionHandler.CFG_KEY_PORT,
                    MongoDBArbiterClusterActionHandler.PORT);
        } catch (IOException e) {
            this.arbiterPort = MongoDBArbiterClusterActionHandler.PORT;
        }

        Mongo mongo;
        DB db;

        try {
            // throws IOExc, UnknownHostExc:
            LOG.info(
                    "Connecting to " + setLeader.getPublicAddress().getHostAddress() + " to initiate replica set.");
            mongo = new Mongo(setLeader.getPublicAddress().getHostAddress(), PORT);
            db = mongo.getDB("admin");
            if (this.authPassword != null && this.authUsername != null) {
                db.authenticate(this.authUsername, this.authPassword.toCharArray());
            }
        } catch (Exception e) {
            LOG.error("Unable to get public host address of replica set leader, " + e.getMessage());
            return;
        }

        try {
            BasicDBObject configObject = this.generateReplicaSetConfig(replSetInstances); // throws IOexc
            LOG.info("config object:" + configObject.toString());
            BasicDBObject commandInfo = new BasicDBObject("replSetInitiate", configObject);
            LOG.info("Sending rs.initiate() command");
            CommandResult initiateResult = db.command(commandInfo);
            LOG.info("Command Result: " + initiateResult.toString());
        } catch (IOException e) {
            LOG.error("Unable to get private host addresses of replica set members, " + e.getMessage());
        } finally {
            //TODO any cleanup?
        }

    }

    /** 
     * Returns a BasicDBObject containing a replica set config object, usable as param to rs.initiate().
     * 
     * @param memberInstances   A set containing instances to be included in config object.
     * @throws IOException      Thrown if the private IP of any instance is unavailable
     *
     */
    private BasicDBObject generateReplicaSetConfig(Set<Cluster.Instance> memberInstances) throws IOException {
        BasicDBObject returnVal = new BasicDBObject();

        if (this.replicaSetName != null) {
            returnVal.put("_id", this.replicaSetName);
        } else {
            returnVal.put("_id", "whirr");
        }
        int counter = 0;

        ArrayList replicaSetMembers = new ArrayList();
        for (Cluster.Instance member : memberInstances) {
            BasicDBObjectBuilder hostObj = BasicDBObjectBuilder.start().add("_id", counter);
            if (member.getRoles().contains(MongoDBArbiterClusterActionHandler.ROLE)) {
                //it's an arbiter, use port from config file
                hostObj.add("host", member.getPrivateAddress().getHostAddress() + ":" + this.arbiterPort);
                hostObj.add("arbiterOnly", true);
            } else {
                // it's a data member
                hostObj.add("host", member.getPrivateAddress().getHostAddress() + ":" + this.port); // throws an IOExc
            }

            replicaSetMembers.add(hostObj.get());
            counter++;
        }

        returnVal.put("members", replicaSetMembers);
        return returnVal;
    }

}