All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.wordnik.mongo.connection.MongoDBConnectionManager.scala Maven / Gradle / Ivy

The newest version!
package com.wordnik.mongo.connection

import java.net.UnknownHostException
import java.util.StringTokenizer
import com.mongodb._
import java.util.logging.Logger
import scala.collection.JavaConversions._
import scala.collection.mutable._

object SchemaType {
  val READ_ONLY = 1
  val READ_WRITE = 2
}

object MongoDBConnectionManager {
  val LOGGER = Logger.getLogger(MongoDBConnectionManager.getClass.getName)
  val mongos = new HashMap[String, Member]
  val pool = new HashMap[String, List[DBServer]]

  @throws(classOf[PersistenceException])
  def getConnection(schemaName: String, schemaType: Int): DB = {
    LOGGER.finest("getting from, key: " + schemaName + ", schemaType: " + schemaType)

    val snl = schemaName.toLowerCase
    if (!pool.contains(snl)) throw new PersistenceException("no configurations found for " + schemaName)

    val servers = pool(snl)
    var output: Option[DB] = None

    schemaType match {
      //	read write => rs or master
      case SchemaType.READ_WRITE => {
        servers.foreach(server => {
          if (server.replicationType == Member.RS || server.replicationType == Member.M) {
            server.username match {
              case Some(user) => {
                if (!server.db.isAuthenticated)
                  server.db.authenticate(user, server.password.toCharArray)
              }
              case _ =>
            }
            output = Some(server.db)
          }
        })
      }
      case _ => {
        //  slaves => rs or slave unless only one master
        servers.foreach(server => {
          if (server.replicationType == Member.RS || server.replicationType == Member.S) {
            server.username match {
              case Some(user) => {
                if (!server.db.isAuthenticated)
                  server.db.authenticate(user, server.password.toCharArray)
              }
              case _ => server.db.slaveOk
            }
            output = Some(server.db)
          }
        })
        //this means there are no slaves so it is ok to get connection from any server
        if (output == None) {
          //	user master anyway
          output = Some(servers(0).db)
        }
      }
    }

    output match {
      case Some(db) => db
      case _ => throw new PersistenceException("no configurations found for " + schemaName)
    }
  }

  @throws(classOf[PersistenceException])
  def getConnection(schemaName: String, h: String, schema: String, u: String, pw: String, schemaType: Int): DB = {
    if (h.indexOf(":") > 0) getConnection(schemaName, h.split(":")(0), h.split(":")(1).toInt, schema, u, pw, schemaType)
    else getConnection(schemaName, h, 27017, schema, u, pw, schemaType)
  }

  @throws(classOf[PersistenceException])
  def getConnection(schemaName: String, h: String, p: Int, schema: String, u: String, pw: String, schemaType: Int): DB = {
    var host: String = h
    var port = p
    val username = {
      if (null != u && u.trim != "") Some(u)
      else None
    }
    val password = {
      if (null == pw) ""
      else pw
    }
    try {
      if (null == host) host = "localhost"
      if (null == port || port <= 0) port = 27017

      LOGGER.finest("getting connection to " + host + ":" + port + "/" + schema + " with username: " + username + ", password: " + password)

      val schemaId = host + ":" + port + ":" + schema
      val db = mongos.contains(schemaId) match {
        case true => {
          LOGGER.finest("getting " + schemaId + " from map")
          val db = mongos(schemaId).mongo.getDB(schema)
          username match {
            case Some(username) => db.authenticate(username, password.toCharArray)
            case _ =>
          }
          db
        }
        case _ => {
          LOGGER.finest("creating " + schemaId)
          val sa = new ServerAddress(host, port)
          var mongo = new Mongo(sa)

          var db = mongo.getDB(schema)
          val replicationType = detectReplicationType(db, username, password)

          if (replicationType == Member.RS) {
            mongo = new Mongo(List(sa))
            db = mongo.getDB(schema)
          }
          mongos += schema -> new Member(replicationType, mongo)
          addServer(schemaName, schema, db: DB, username, password, replicationType)
          db
        }
      }
      db
    } catch {
      case e: Exception => {
        LOGGER.severe("can't get connection to " + host + ":" + port + "/" + schema + " with username " + username + ", password " + password);
        throw new PersistenceException(e);
      }
    }
  }

  def detectReplicationType(db: DB, username: Option[String], password: String) = {
    try {
      //	check it
      var stat: String = null
      username match {
        case Some(username) => {
          db.authenticate(username, password.toCharArray)
          stat = db.command("isMaster").toString
          if (stat.indexOf("\"ismaster\" : true") > 0) Member.M
          else Member.S
        }
        case _ => {
          stat = db.command("isMaster").toString
          if (stat.indexOf("setName") > 0) {
            //  is a replica set
            Member.RS
          } else {
            if (stat.indexOf("\"ismaster\" : true") > 0) Member.M
            else if (stat.indexOf("\"ismaster\" : false") > 0) Member.S
            else Member.UNKNOWN
          }
        }
      }
    } catch {
      case e: Exception => {
        e.printStackTrace
        Member.UNKNOWN
      }
      case _ =>
        throw new PersistenceException("Failed to detect replication type")
    }
  }

  def addServer(schemaName: String, schema: String, db: DB, username: Option[String], password: String, replicationType: Int) = {
    val snl = schemaName.toLowerCase
    if (!pool.contains(snl)) {
      val serverList = new ListBuffer[DBServer]
      pool += snl -> List[DBServer]()
    }
    val serverList = new ListBuffer[DBServer]
    pool(snl).foreach(server => { serverList += server })

    serverList += new DBServer(db, username, password, replicationType)
    pool += snl -> serverList.toList
    LOGGER.finest("adding to pool, key: " + snl + ", server: " + db)
  }
}

class DBServer(val db: DB, val username: Option[String], val password: String, val replicationType: Int)

object Member {
  val RS = 1
  val M = 2
  val S = 3
  val UNKNOWN = 4
}

class Member(val memberType: Int, val mongo: Mongo)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy