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

com.mongodb.Mongo Maven / Gradle / Ivy

Go to download

The MongoDB Java Driver uber-artifact, containing mongodb-driver, mongodb-driver-core, and bson

There is a newer version: 3.1.0
Show newest version
/*
 * 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;

import org.bson.io.PoolOutputBuffer;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Logger;

/**
 * A database connection with internal connection pooling. For most applications, you should have one Mongo instance
 * for the entire JVM.
 * 

* The following are equivalent, and all connect to the local database running on the default port: *

 * Mongo mongo1 = new Mongo();
 * Mongo mongo1 = new Mongo("localhost");
 * Mongo mongo2 = new Mongo("localhost", 27017);
 * Mongo mongo4 = new Mongo(new ServerAddress("localhost"));
 * 
*

* You can connect to a * replica set using the Java driver by passing * a ServerAddress list to the Mongo constructor. For example: *

 * Mongo mongo = new Mongo(Arrays.asList(
 *   new ServerAddress("localhost", 27017),
 *   new ServerAddress("localhost", 27018),
 *   new ServerAddress("localhost", 27019)));
 * 
* You can connect to a sharded cluster using the same constructor. Mongo will auto-detect whether the servers are * a list of replica set members or a list of mongos servers. *

* By default, all read and write operations will be made on the primary, * but it's possible to read from secondaries by changing the read preference: *

*

 * mongo.setReadPreference(ReadPreference.secondary());
 * 
* By default, write operations will not throw exceptions on failure, but that is easily changed too: *

*

 * mongo.setWriteConcern(WriteConcern.SAFE);
 * 
* * Note: This class has been superseded by {@code MongoClient}, and may be deprecated in a future release. * * @see MongoClient * @see ReadPreference * @see WriteConcern */ public class Mongo { static Logger logger = Logger.getLogger(Bytes.LOGGER.getName() + ".Mongo"); // Make sure you don't change the format of these two static variables. A preprocessing regexp // is applied and updates the version based on configuration in build.properties. /** * @deprecated Replaced by {@link #getMajorVersion()} */ @Deprecated public static final int MAJOR_VERSION = 2; /** * @deprecated Replaced by {@link #getMinorVersion()} */ @Deprecated public static final int MINOR_VERSION = 13; private static final String FULL_VERSION = "2.13.3"; static int cleanerIntervalMS; private static final String ADMIN_DATABASE_NAME = "admin"; static { cleanerIntervalMS = Integer.parseInt(System.getProperty("com.mongodb.cleanerIntervalMS", "1000")); } /** * Gets the major version of this library * * @return the major version, e.g. 2 * @deprecated Please use {@link #getVersion()} instead. */ @Deprecated public static int getMajorVersion() { return MAJOR_VERSION; } /** * Gets the minor version of this library * * @return the minor version, e.g. 8 * @deprecated Please use {@link #getVersion()} instead. */ @Deprecated public static int getMinorVersion() { return MINOR_VERSION; } /** * Connect to the MongoDB instance at the given address, select and return the {@code DB} specified in the {@code DBAddress} parameter. * * @param addr The details of the server and database to connect to * @return the DB requested in the addr parameter. * @throws MongoException * @deprecated Please use {@link MongoClient#getDB(String)} instead. */ @Deprecated public static DB connect( DBAddress addr ){ return new Mongo( addr ).getDB( addr.getDBName() ); } /** * Creates a Mongo instance based on a (single) mongodb node (localhost, default port) * * @throws UnknownHostException This exception is no longer thrown, but leaving in throws clause so as not to break source * compatibility. The exception will be removed from the declaration in the next major release of the * driver. * @deprecated Replaced by {@link MongoClient#MongoClient()}) */ @Deprecated public Mongo() throws UnknownHostException { this(new ServerAddress() ); } /** * Creates a Mongo instance based on a (single) mongodb node (default port) * * @param host server to connect to * @throws UnknownHostException This exception is no longer thrown, but leaving in throws clause so as not to break source * compatibility. The exception will be removed from the declaration in the next major release of the * driver. * @deprecated Replaced by {@link MongoClient#MongoClient(String)} */ @Deprecated public Mongo(String host) throws UnknownHostException{ this( new ServerAddress( host ) ); } /** * Creates a Mongo instance based on a (single) mongodb node (default port) * * @param host server to connect to * @param options default query options * @throws UnknownHostException This exception is no longer thrown, but leaving in throws clause so as not to break source * compatibility. The exception will be removed from the declaration in the next major release of the * driver. * @deprecated Replaced by {@link MongoClient#MongoClient(String, MongoClientOptions)} */ @Deprecated public Mongo(String host, MongoOptions options) throws UnknownHostException { this( new ServerAddress( host ) , options ); } /** * Creates a Mongo instance based on a (single) mongodb node * * @param host the database's host address * @param port the port on which the database is running * @throws UnknownHostException This exception is no longer thrown, but leaving in throws clause so as not to break source * compatibility. The exception will be removed from the declaration in the next major release of the * driver. * @deprecated Replaced by {@link MongoClient#MongoClient(String, int)} */ @Deprecated public Mongo(String host, int port) throws UnknownHostException { this( new ServerAddress( host , port ) ); } /** * Creates a Mongo instance based on a (single) mongodb node * * @param addr the database address * @see com.mongodb.ServerAddress * @deprecated Replaced by {@link MongoClient#MongoClient(ServerAddress)} */ @Deprecated public Mongo(ServerAddress addr) { this(addr, new MongoOptions()); } /** * Creates a Mongo instance based on a (single) mongo node using a given ServerAddress * * @param addr the database address * @param options default query options * @see com.mongodb.ServerAddress * @deprecated Replaced by {@link MongoClient#MongoClient(ServerAddress, MongoClientOptions)} */ @Deprecated public Mongo(ServerAddress addr, MongoOptions options) { this(MongoAuthority.direct(addr), options); } /** * Creates a Mongo in paired mode. This will also work for a replica set and will find all members (the master will be used by * default). * * @param left left side of the pair * @param right right side of the pair * @throws MongoException */ @Deprecated public Mongo(ServerAddress left, ServerAddress right) { this(left, right, new MongoOptions()); } /** * Creates a Mongo connection in paired mode. This will also work for a replica set and will find all members (the master will be used * by default). * * @param left left side of the pair * @param right right side of the pair * @param options the optional settings for the Mongo instance * @see com.mongodb.ServerAddress * @deprecated Please use {@link MongoClient#MongoClient(java.util.List, MongoClientOptions)} instead. */ @Deprecated public Mongo(ServerAddress left, ServerAddress right, MongoOptions options) { this(MongoAuthority.dynamicSet(Arrays.asList(left, right)), options); } /** *

Creates a Mongo based on a list of replica set members or a list of mongos. It will find all members (the master will be used by * default). If you pass in a single server in the list, the driver will still function as if it is a replica set. If you have a * standalone server, use the Mongo(ServerAddress) constructor.

* *

If this is a list of mongos servers, it will pick the closest (lowest ping time) one to send all requests to, and automatically * fail over to the next server if the closest is down.

* * @param seeds Put as many servers as you can in the list and the system will figure out the rest. This can either be a list of mongod * servers in the same replica set or a list of mongos servers in the same sharded cluster. * @see com.mongodb.ServerAddress * @deprecated Replaced by {@link MongoClient#MongoClient(java.util.List)} */ @Deprecated public Mongo(List seeds) { this( seeds , new MongoOptions() ); } /** *

Creates a Mongo based on a list of replica set members or a list of mongos. It will find all members (the master will be used by * default). If you pass in a single server in the list, the driver will still function as if it is a replica set. If you have a * standalone server, use the Mongo(ServerAddress) constructor.

* *

If this is a list of mongos servers, it will pick the closest (lowest ping time) one to send all requests to, and automatically * fail over to the next server if the closest is down.

* * @param seeds Put as many servers as you can in the list and the system will figure out the rest. This can either be a list of * mongod servers in the same replica set or a list of mongos servers in the same sharded cluster. * @param options for configuring this Mongo instance * @see com.mongodb.ServerAddress * @deprecated Replaced by {@link MongoClient#MongoClient(java.util.List, MongoClientOptions)} */ @Deprecated public Mongo( List seeds , MongoOptions options ) { this(MongoAuthority.dynamicSet(seeds), options); } /** *

Creates a Mongo described by a URI. If only one address is used it will only connect to that node, otherwise it will discover all * nodes. If the URI contains database credentials, the database will be authenticated lazily on first use with those credentials.

* *

Examples:

*
    *
  • mongodb://localhost
  • *
  • mongodb://fred:foobar@localhost/
  • *
* * @param uri URI to connect to, optionally containing additional information like credentials * @mongodb.driver.manual reference/connection-string Connection String URI Format * @see MongoURI * @deprecated Replaced by {@link MongoClient#MongoClient(MongoClientURI)} */ @Deprecated public Mongo(MongoURI uri) throws UnknownHostException { this(getMongoAuthorityFromURI(uri), uri.getOptions()); } /** *

Creates a Mongo based on an authority and options.

* *

Note: This constructor is provisional and is subject to change before the final release

* * @param authority the authority * @param options the options */ Mongo(MongoAuthority authority, MongoOptions options) { logger.info("Creating Mongo instance (driver version " + getVersion() + ") with authority " + authority + " and options " + options); _authority = authority; _options = options; _applyMongoOptions(); _connector = new DBTCPConnector( this ); _connector.start(); if (_options.cursorFinalizerEnabled) { _cleaner = new CursorCleanerThread(); _cleaner.start(); } else { _cleaner = null; } } /** * Gets a database object from this MongoDB instance. * * @param dbname the name of the database to retrieve * @return a DB representing the specified database */ public DB getDB( String dbname ){ DB db = _dbs.get( dbname ); if ( db != null ) return db; db = new DBApiLayer( this , dbname , _connector ); DB temp = _dbs.putIfAbsent( dbname , db ); if ( temp != null ) return temp; return db; } /** * Returns the list of databases used by the driver since this Mongo instance was created. This may include DBs that exist in the client * but not yet on the server. * * @return a collection of database objects */ public Collection getUsedDatabases(){ return _dbs.values(); } /** * Gets a list of the names of all databases on the connected server. * * @return list of database names * @throws MongoException */ public List getDatabaseNames(){ BasicDBObject cmd = new BasicDBObject(); cmd.put("listDatabases", 1); CommandResult res = getDB(ADMIN_DATABASE_NAME).command(cmd, getOptions()); res.throwOnError(); List l = (List)res.get("databases"); List list = new ArrayList(); for (Object o : l) { list.add(((BasicDBObject)o).getString("name")); } return list; } /** * Drops the database if it exists. * * @param dbName name of database to drop * @throws MongoException */ public void dropDatabase(String dbName){ getDB( dbName ).dropDatabase(); } /** * Gets this driver version. * * @return the full version string of this driver, e.g. "2.8.0" * @deprecated There is no replacement for this method. */ @Deprecated public String getVersion(){ return FULL_VERSION; } /** * Get a String for debug purposes. * * @return a string representing the hosts used in this Mongo instance * @deprecated This method is NOT a part of public API and will be dropped in 3.x versions. */ @Deprecated public String debugString(){ return _connector.debugString(); } /** * Gets a {@code String} representation of current connection point, i.e. master. * * @return server address in a host:port form */ public String getConnectPoint(){ return _connector.getConnectPoint(); } /** * Gets the underlying TCP connector * * @return A DBTCPConnector representing the connection to MongoDB * @deprecated {@link DBTCPConnector} is NOT part of the public API. It will be dropped in 3.x releases. */ @Deprecated public DBTCPConnector getConnector() { return _connector; } /** * Get the status of the replica set cluster. * * @return replica set status information */ public ReplicaSetStatus getReplicaSetStatus() { return _connector.getReplicaSetStatus(); } /** * Gets the address of the current master * * @return the address */ public ServerAddress getAddress(){ return _connector.getAddress(); } /** * Gets a list of all server addresses used when this Mongo was created * * @return list of server addresses * @throws MongoException */ public List getAllAddress() { List result = _connector.getAllAddress(); if (result == null) { return Arrays.asList(getAddress()); } return result; } /** * Gets the list of server addresses currently seen by this client. This includes addresses auto-discovered from a replica set. * * @return list of server addresses * @throws MongoException */ public List getServerAddressList() { return _connector.getServerAddressList(); } /** * Closes the underlying connector, which in turn closes all open connections. Once called, this Mongo instance can no longer be used. */ public void close(){ try { _connector.close(); } catch (final Throwable t) { /* nada */ } if (_cleaner != null) { _cleaner.interrupt(); try { _cleaner.join(); } catch (InterruptedException e) { //end early } } } /** * Sets the write concern for this database. Will be used as default for writes to any collection in any database. See the documentation * for {@link WriteConcern} for more information. * * @param concern write concern to use */ public void setWriteConcern( WriteConcern concern ){ _concern = concern; } /** * Gets the default write concern * * @return the default write concern */ public WriteConcern getWriteConcern(){ return _concern; } /** * Sets the read preference for this database. Will be used as default for reads from any collection in any database. See the * documentation for {@link ReadPreference} for more information. * * @param preference Read Preference to use */ public void setReadPreference(ReadPreference preference) { _readPref = preference; } /** * Gets the default read preference * * @return the default read preference */ public ReadPreference getReadPreference(){ return _readPref; } /** * Makes it possible to run read queries on secondary nodes * * @see ReadPreference#secondaryPreferred() * @deprecated Replaced with {@code ReadPreference.secondaryPreferred()} */ @Deprecated public void slaveOk() { addOption( Bytes.QUERYOPTION_SLAVEOK ); } /** * Add a default query option keeping any previously added options. * * @param option value to be added to current options */ public void addOption( int option ){ _netOptions.add( option ); } /** * Set the default query options. Overrides any existing options. * * @param options value to be set */ public void setOptions( int options ){ _netOptions.set( options ); } /** * Reset the default query options */ public void resetOptions(){ _netOptions.reset(); } /** * Gets the default query options * * @return an int representing the options to be used by queries */ public int getOptions(){ return _netOptions.get(); } /** * Helper method for setting up MongoOptions at instantiation so that any options which affect this connection can be set. */ @SuppressWarnings("deprecation") void _applyMongoOptions() { if (_options.slaveOk) { slaveOk(); } if (_options.getReadPreference() != null) { setReadPreference(_options.getReadPreference()); } setWriteConcern(_options.getWriteConcern()); } /** * Returns the mongo options. * * @return A {@link com.mongodb.MongoOptions} containing the settings for this MongoDB instance. * @deprecated Please use {@link MongoClient} and corresponding {@link com.mongodb.MongoClient#getMongoClientOptions()} */ @Deprecated public MongoOptions getMongoOptions() { return _options; } /** * Gets the maximum size for a BSON object supported by the current master server. Note that this value may change over time depending * on which server is master. * * @return the maximum size, or 0 if not obtained from servers yet. * @throws MongoException */ public int getMaxBsonObjectSize() { return _connector.getMaxBsonObjectSize(); } boolean isMongosConnection() { return _connector.isMongosConnection(); } private static MongoAuthority getMongoAuthorityFromURI(final MongoURI uri) throws UnknownHostException { if ( uri.getHosts().size() == 1 ){ return MongoAuthority.direct(new ServerAddress(uri.getHosts().get(0)), uri.getCredentials()); } else { List replicaSetSeeds = new ArrayList(uri.getHosts().size()); for ( String host : uri.getHosts() ) replicaSetSeeds.add( new ServerAddress( host ) ); return MongoAuthority.dynamicSet(replicaSetSeeds, uri.getCredentials()); } } final MongoOptions _options; final DBTCPConnector _connector; final ConcurrentMap _dbs = new ConcurrentHashMap(); private WriteConcern _concern = WriteConcern.NORMAL; private ReadPreference _readPref = ReadPreference.primary(); final Bytes.OptionHolder _netOptions = new Bytes.OptionHolder( null ); final CursorCleanerThread _cleaner; final MongoAuthority _authority; org.bson.util.SimplePool _bufferPool = new org.bson.util.SimplePool( 1000 ){ protected PoolOutputBuffer createNew(){ return new PoolOutputBuffer(); } }; /** * Forces the master server to fsync the RAM data to disk This is done automatically by the server at intervals, but can be forced for * better reliability. * * @param async if true, the fsync will be done asynchronously on the server. * @return result of the command execution * @throws MongoException * @mongodb.driver.manual reference/command/fsync/ fsync command */ public CommandResult fsync(boolean async) { DBObject cmd = new BasicDBObject("fsync", 1); if (async) { cmd.put("async", 1); } CommandResult result = getDB(ADMIN_DATABASE_NAME).command(cmd); result.throwOnError(); return result; } /** * Forces the master server to fsync the RAM data to disk, then lock all writes. The database will be read-only after this command * returns. * * @return result of the command execution * @throws MongoException * @mongodb.driver.manual reference/command/fsync/ fsync command */ public CommandResult fsyncAndLock() { DBObject cmd = new BasicDBObject("fsync", 1); cmd.put("lock", 1); CommandResult result = getDB(ADMIN_DATABASE_NAME).command(cmd); result.throwOnError(); return result; } /** * Unlocks the database, allowing the write operations to go through. This command may be asynchronous on the server, which means there * may be a small delay before the database becomes writable. * * @return {@code DBObject} in the following form {@code {"ok": 1,"info": "unlock completed"}} * @throws MongoException * @mongodb.driver.manual reference/command/fsync/ fsync command */ public DBObject unlock() { DB db = getDB(ADMIN_DATABASE_NAME); DBCollection col = db.getCollection("$cmd.sys.unlock"); return col.findOne(); } /** * Returns true if the database is locked (read-only), false otherwise. * * @return result of the command execution * @throws MongoException * @mongodb.driver.manual reference/command/fsync/ fsync command */ public boolean isLocked() { DB db = getDB(ADMIN_DATABASE_NAME); DBCollection col = db.getCollection("$cmd.sys.inprog"); BasicDBObject res = (BasicDBObject) col.findOne(); if (res.containsField("fsyncLock")) { return res.getInt("fsyncLock") == 1; } return false; } // ------- /** * Mongo.Holder can be used as a static place to hold several instances of Mongo. Security is not enforced at this level, and needs to * be done on the application side. */ public static class Holder { /** * Attempts to find an existing MongoClient instance matching that URI in the holder, and returns it if exists. * Otherwise creates a new Mongo instance based on this URI and adds it to the holder. * * @param uri the Mongo URI * @return the client * @throws MongoException * @throws UnknownHostException * * @deprecated Please use {@link #connect(MongoClientURI)} instead. */ @Deprecated public Mongo connect(final MongoURI uri) throws UnknownHostException { return connect(uri.toClientURI()); } /** * Attempts to find an existing MongoClient instance matching that URI in the holder, and returns it if exists. * Otherwise creates a new Mongo instance based on this URI and adds it to the holder. * * @param uri the Mongo URI * @return the client * @throws MongoException * @throws UnknownHostException */ public Mongo connect(final MongoClientURI uri) throws UnknownHostException { final String key = toKey(uri); Mongo client = _mongos.get(key); if (client == null) { final Mongo newbie = new MongoClient(uri); client = _mongos.putIfAbsent(key, newbie); if (client == null) { client = newbie; } else { newbie.close(); } } return client; } private String toKey(final MongoClientURI uri) { return uri.toString(); } public static Holder singleton() { return _default; } private static Holder _default = new Holder(); private final ConcurrentMap _mongos = new ConcurrentHashMap(); } class CursorCleanerThread extends Thread { CursorCleanerThread() { setDaemon(true); setName("MongoCleaner" + hashCode()); } public void run() { while (_connector.isOpen()) { try { try { Thread.sleep(cleanerIntervalMS); } catch (InterruptedException e) { //caused by the Mongo instance being closed -- proceed with cleanup } for (DB db : _dbs.values()) { db.cleanCursors(true); } } catch (Throwable t) { // thread must never die } } } } @Override public String toString() { return "Mongo{" + "authority=" + _authority + ", options=" + _options + '}'; } /** * Gets the authority, which includes the connection type, the server address(es), and the credentials. * * @return the authority */ MongoAuthority getAuthority() { return _authority; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy