@Test @SuppressWarnings("deprecation") public void testToClientOptions() throws UnknownHostException { MongoOptions options = new MongoOptions(); options.description = "my client"; options.fsync = true; options.readPreference = ReadPreference.secondary(); options.requiredReplicaSetName = "test"; options.cursorFinalizerEnabled = false; options.alwaysUseMBeans = true; options.connectTimeout = 100; options.maxWaitTime = 500; options.socketKeepAlive = true; options.threadsAllowedToBlockForConnectionMultiplier = 10; MongoClientOptions clientOptions = options.toClientOptions(); assertEquals(options.requiredReplicaSetName, clientOptions.getRequiredReplicaSetName()); assertEquals(options.description, clientOptions.getDescription()); assertEquals(WriteConcern.ACKNOWLEDGED.withFsync(true), clientOptions.getWriteConcern()); assertEquals(0, clientOptions.getMinConnectionsPerHost()); assertEquals(10, clientOptions.getConnectionsPerHost()); assertEquals(100, clientOptions.getConnectTimeout()); assertEquals(500, clientOptions.getMaxWaitTime()); assertEquals(ReadPreference.secondary(), clientOptions.getReadPreference()); assertEquals(10, clientOptions.getThreadsAllowedToBlockForConnectionMultiplier()); assertTrue(clientOptions.isSocketKeepAlive()); assertFalse(clientOptions.isSslEnabled()); assertEquals(options.dbDecoderFactory, clientOptions.getDbDecoderFactory()); assertEquals(options.dbEncoderFactory, clientOptions.getDbEncoderFactory()); assertEquals(15, clientOptions.getLocalThreshold()); assertTrue(clientOptions.isAlwaysUseMBeans()); assertFalse(clientOptions.isCursorFinalizerEnabled()); }
/** * Determines the read preference that should be used for the given command. * * @param command the {@link DBObject} representing the command * @param requestedPreference the preference requested by the client. * @return the read preference to use for the given command. It will never return {@code null}. * @see com.mongodb.ReadPreference */ ReadPreference getCommandReadPreference(DBObject command, ReadPreference requestedPreference) { String comString = command.keySet().iterator().next(); if (comString.equals("getnonce") || comString.equals("authenticate")) { return ReadPreference.primaryPreferred(); } boolean primaryRequired; // explicitly check mapreduce commands are inline if (comString.equals("mapreduce")) { Object out = command.get("out"); if (out instanceof BSONObject) { BSONObject outMap = (BSONObject) out; primaryRequired = outMap.get("inline") == null; } else primaryRequired = true; } else { primaryRequired = !_obedientCommands.contains(comString.toLowerCase()); } if (primaryRequired) { return ReadPreference.primary(); } else if (requestedPreference == null) { return ReadPreference.primary(); } else { return requestedPreference; } }
// Only append $readPreference meta-operator if connected to a mongos, read preference is not // primary // or secondary preferred, // and command is an instance of BasicDBObject. The last condition is unfortunate, but necessary // in case // the encoder is not capable of encoding a BasicDBObject // Due to issues with compatibility between different versions of mongos, also wrap the command in // a // $query field, so that the $readPreference is not rejected private DBObject wrapCommand(DBObject cmd, final ReadPreference readPrefs) { if (getMongo().isMongosConnection() && !(ReadPreference.primary().equals(readPrefs) || ReadPreference.secondaryPreferred().equals(readPrefs)) && cmd instanceof BasicDBObject) { cmd = new BasicDBObject("$query", cmd) .append(QueryOpBuilder.READ_PREFERENCE_META_OPERATOR, readPrefs.toDBObject()); } return cmd; }
@Test @SuppressWarnings("deprecation") public void testTaggedPreference() { ReadPreference readPreference = new ReadPreference.TaggedReadPreference(new BasicDBObject("dc", "ny")); for (int i = 0; i < 1000; i++) { nodeSet.add(readPreference.getNode(_set)); } expectedNodeSet.addAll(Arrays.asList(_secondary1, _secondary2)); assertEquals(expectedNodeSet, nodeSet); }
private OutMessage( final DBCollection collection, final Mongo m, OpCode opCode, final DBEncoder enc, final DBObject query, final int options, final ReadPreference readPref) { _collection = collection; _mongo = m; _encoder = enc; _buffer = _mongo._bufferPool.get(); _buffer.reset(); set(_buffer); _id = REQUEST_ID.getAndIncrement(); _opCode = opCode; writeMessagePrologue(opCode); if (query == null) { _query = null; _queryOptions = 0; } else { _query = query; int allOptions = options; if (readPref != null && readPref.isSlaveOk()) { allOptions |= Bytes.QUERYOPTION_SLAVEOK; } _queryOptions = allOptions; } }
@Test @SuppressWarnings("deprecation") public void testGetterSetters() throws Exception { MongoOptions options = new MongoOptions(); options.setConnectionsPerHost(100); options.setThreadsAllowedToBlockForConnectionMultiplier(101); options.setMaxWaitTime(102); options.setConnectTimeout(103); options.setSocketTimeout(104); options.setSocketKeepAlive(true); options.setSafe(true); options.setW(106); options.setWtimeout(107); options.setFsync(true); options.setJ(false); options.setDbDecoderFactory(null); options.setDbEncoderFactory(null); options.setDescription("very cool"); options.setReadPreference(ReadPreference.secondary()); options.setSocketFactory(SSLSocketFactory.getDefault()); options.setAlwaysUseMBeans(true); options.setCursorFinalizerEnabled(false); options.requiredReplicaSetName = "set1"; assertEquals(options.getConnectionsPerHost(), 100); assertEquals(options.getThreadsAllowedToBlockForConnectionMultiplier(), 101); assertEquals(options.getMaxWaitTime(), 102); assertEquals(options.getConnectTimeout(), 103); assertEquals(options.getSocketTimeout(), 104); assertEquals(options.isSocketKeepAlive(), true); assertEquals(options.isSafe(), true); assertEquals(options.getW(), 106); assertEquals(options.getWtimeout(), 107); assertEquals(options.isFsync(), true); assertEquals(options.isJ(), false); assertEquals(options.getDbDecoderFactory(), null); assertEquals(options.getDbEncoderFactory(), null); assertEquals(options.getDescription(), "very cool"); assertEquals(options.getReadPreference(), ReadPreference.secondary()); assertEquals(options.isAlwaysUseMBeans(), true); assertEquals(options.getSocketFactory(), options.socketFactory); assertEquals(options.isCursorFinalizerEnabled(), false); assertEquals(options.getRequiredReplicaSetName(), "set1"); }
@Test public void testPrimaryPreferredWithNoPrimary() { for (int i = 0; i < 1000; i++) { nodeSet.add(ReadPreference.primaryPreferred().getNode(_setNoPrimary)); } expectedNodeSet.addAll(Arrays.asList(_secondary1, _secondary2)); assertEquals(expectedNodeSet, nodeSet); }
@Test public void testNearest() { for (int i = 0; i < 1000; i++) { nodeSet.add(ReadPreference.nearest().getNode(_set)); } expectedNodeSet.addAll(Arrays.asList(_primary, _secondary1)); assertEquals(expectedNodeSet, nodeSet); }
static OutMessage query( DBCollection collection, int options, int numToSkip, int batchSize, DBObject query, DBObject fields) { return query( collection, options, numToSkip, batchSize, query, fields, ReadPreference.primary()); }
@Test public void testTaggedNearest() { final TaggableReadPreference taggedNearestReadPreference = ReadPreference.nearest(new BasicDBObject("dc", "ny")); for (int i = 0; i < 1000; i++) { nodeSet.add(taggedNearestReadPreference.getNode(_set)); } expectedNodeSet.addAll(Arrays.asList(_primary, _secondary1)); assertEquals(expectedNodeSet, nodeSet); }
@Test public void testTaggedPrimaryPreferredWithNoPrimary() { final TaggableReadPreference readPreference = ReadPreference.primaryPreferred(new BasicDBObject("dc", "ny")); for (int i = 0; i < 1000; i++) { nodeSet.add(readPreference.getNode(_setNoPrimary)); } expectedNodeSet.addAll(Arrays.asList(_secondary1, _secondary2)); assertEquals(expectedNodeSet, nodeSet); }
@Override protected MongoClient createInstance() throws Exception { MongoClient mongo = initMongo(); // 设定主从分离 if (readSecondary) { mongo.setReadPreference(ReadPreference.secondaryPreferred()); } // 设定写策略 mongo.setWriteConcern(writeConcern); return mongo; }
private ReadPreference buildReadPreference( final String readPreferenceType, final DBObject firstTagSet, final List<DBObject> remainingTagSets, final Boolean slaveOk) { if (readPreferenceType != null) { if (firstTagSet == null) { return ReadPreference.valueOf(readPreferenceType); } else { return ReadPreference.valueOf( readPreferenceType, firstTagSet, remainingTagSets.toArray(new DBObject[remainingTagSets.size()])); } } else if (slaveOk != null) { if (slaveOk.equals(Boolean.TRUE)) { return ReadPreference.secondaryPreferred(); } } return null; }
@Test public void testTaggedSecondaryPreferredWithNoSecondaryMatch() { final TaggableReadPreference nonMatchingReadPreference = ReadPreference.secondaryPreferred(new BasicDBObject("dc", "ca")); for (int i = 0; i < 1000; i++) { nodeSet.add(nonMatchingReadPreference.getNode(_set)); } expectedNodeSet.addAll(Arrays.asList(_primary)); assertEquals(expectedNodeSet, nodeSet); }
@SuppressWarnings("deprecation") @Test public void testApplyOptions() throws UnknownHostException { MongoOptions options = new MongoOptions(); // test defaults Mongo m = new Mongo("localhost", options); assertEquals(ReadPreference.primary(), m.getReadPreference()); assertEquals(WriteConcern.NORMAL, m.getWriteConcern()); assertEquals(0, m.getOptions() & Bytes.QUERYOPTION_SLAVEOK); m.close(); // test setting options options.setReadPreference(ReadPreference.nearest()); options.slaveOk = true; options.safe = true; m = new Mongo("localhost", options); assertEquals(ReadPreference.nearest(), m.getReadPreference()); assertEquals(WriteConcern.SAFE, m.getWriteConcern()); assertEquals(Bytes.QUERYOPTION_SLAVEOK, m.getOptions() & Bytes.QUERYOPTION_SLAVEOK); m.close(); }
@Test @SuppressWarnings("deprecation") public void testCopy() throws Exception { MongoOptions options = new MongoOptions(); options.connectionsPerHost = 100; options.threadsAllowedToBlockForConnectionMultiplier = 101; options.maxWaitTime = 102; options.connectTimeout = 103; options.socketTimeout = 104; options.socketKeepAlive = true; options.safe = true; options.w = 106; options.wtimeout = 107; options.fsync = true; options.j = false; options.dbDecoderFactory = null; options.dbEncoderFactory = null; options.description = "cool"; options.readPreference = ReadPreference.secondary(); options.cursorFinalizerEnabled = true; options.socketFactory = SSLSocketFactory.getDefault(); options.alwaysUseMBeans = true; options.requiredReplicaSetName = "set1"; MongoOptions copy = options.copy(); assertEquals(options.connectionsPerHost, copy.connectionsPerHost); assertEquals( options.threadsAllowedToBlockForConnectionMultiplier, copy.threadsAllowedToBlockForConnectionMultiplier); assertEquals(options.maxWaitTime, copy.maxWaitTime); assertEquals(options.connectTimeout, copy.connectTimeout); assertEquals(options.socketTimeout, copy.socketTimeout); assertEquals(options.socketKeepAlive, copy.socketKeepAlive); assertEquals(options.safe, copy.safe); assertEquals(options.w, copy.w); assertEquals(options.wtimeout, copy.wtimeout); assertEquals(options.fsync, copy.fsync); assertEquals(options.j, copy.j); assertEquals(options.dbDecoderFactory, copy.dbDecoderFactory); assertEquals(options.dbEncoderFactory, copy.dbEncoderFactory); assertEquals(options.description, copy.description); assertEquals(options.readPreference, copy.readPreference); assertEquals(options.alwaysUseMBeans, copy.alwaysUseMBeans); assertEquals(options.socketFactory, copy.socketFactory); assertEquals(options.requiredReplicaSetName, copy.requiredReplicaSetName); }
@Test public void testGetCollectionNamesToSecondary() throws MongoException, UnknownHostException { if (!isReplicaSet(cleanupMongo)) { return; } Mongo mongo = new MongoClient( Arrays.asList(new ServerAddress("127.0.0.1"), new ServerAddress("127.0.0.1", 27018))); try { String secondary = getASecondaryAsString(mongo); mongo.close(); mongo = new MongoClient(secondary); DB db = mongo.getDB("secondaryTest"); db.setReadPreference(ReadPreference.secondary()); db.getCollectionNames(); } finally { mongo.close(); } }
/** * A database connection with internal connection pooling. For most applications, you should have * one Mongo instance for the entire JVM. * * <p>The following are equivalent, and all connect to the local database running on the default * port: * * <pre> * Mongo mongo1 = new Mongo(); * Mongo mongo1 = new Mongo("localhost"); * Mongo mongo2 = new Mongo("localhost", 27017); * Mongo mongo4 = new Mongo(new ServerAddress("localhost")); * </pre> * * <p>You can connect to a <a href="http://www.mongodb.org/display/DOCS/Replica+Sets">replica * set</a> using the Java driver by passing a ServerAddress list to the Mongo constructor. For * example: * * <pre> * Mongo mongo = new Mongo(Arrays.asList( * new ServerAddress("localhost", 27017), * new ServerAddress("localhost", 27018), * new ServerAddress("localhost", 27019))); * </pre> * * 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. * * <p>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: * * <p> * * <pre> * mongo.setReadPreference(ReadPreference.secondary()); * </pre> * * By default, write operations will not throw exceptions on failure, but that is easily changed * too: * * <p> * * <pre> * mongo.setWriteConcern(WriteConcern.SAFE); * </pre> * * 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 <code>Mongo.getMajorVersion()</code> */ @Deprecated public static final int MAJOR_VERSION = 2; /** @deprecated Replaced by <code>Mongo.getMinorVersion()</code> */ @Deprecated public static final int MINOR_VERSION = 13; private static final String FULL_VERSION = "2.13.0-SNAPSHOT"; 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 * @throws MongoException * @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 if the database host cannot be resolved * @throws MongoException * @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 if the database host cannot be resolved * @throws MongoException * @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 if the database host cannot be resolved * @throws MongoException * @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 * * @see com.mongodb.ServerAddress * @param addr the database address * @throws MongoException * @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 * * @see com.mongodb.ServerAddress * @param addr the database address * @param options default query options * @throws MongoException * @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. <br> * This will also work for a replica set and will find all members (the master will be used by * default). * * @see com.mongodb.ServerAddress * @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. <br> * This will also work for a replica set and will find all members (the master will be used by * default). * * @see com.mongodb.ServerAddress * @param left left side of the pair * @param right right side of the pair * @param options the optional settings for the Mongo instance * @throws MongoException * @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. * * <p>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. * * @see com.mongodb.ServerAddress * @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. * @throws MongoException * @deprecated Replaced by {@link MongoClient#MongoClient(java.util.List)} */ @Deprecated public Mongo(List<ServerAddress> 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. * * <p>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. * * @see com.mongodb.ServerAddress * @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 * @throws MongoException * @deprecated Replaced by {@link MongoClient#MongoClient(java.util.List, MongoClientOptions)} */ @Deprecated public Mongo(List<ServerAddress> 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. * * @param uri the URI to connect to. * <p>examples: * <ul> * <li>mongodb://localhost * <li>mongodb://fred:foobar@localhost/ * </ul> * * @throws MongoException * @throws UnknownHostException * @dochub connections * @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. * * <p>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<DB> 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<String> 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<String> list = new ArrayList<String>(); 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" */ 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<ServerAddress> getAllAddress() { List<ServerAddress> 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<ServerAddress> 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 * * @deprecated Replaced with {@code ReadPreference.secondaryPreferred()} * @see 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. * * @deprecated Please use {@link MongoClient} and corresponding {@link * com.mongodb.MongoClient#getMongoClientOptions()} * @return A {@link com.mongodb.MongoOptions} containing the settings for this MongoDB instance. */ @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. If the size is not known yet, a * request may be sent to the master server * * @return the maximum size * @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<ServerAddress> replicaSetSeeds = new ArrayList<ServerAddress>(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<String, DB> _dbs = new ConcurrentHashMap<String, DB>(); 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<PoolOutputBuffer> _bufferPool = new org.bson.util.SimplePool<PoolOutputBuffer>(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<String, Mongo> _mongos = new ConcurrentHashMap<String, Mongo>(); } 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; } }
@Test public void testSecondaryPreferredWithNoPrimaryOrSecondary() { assertNull(ReadPreference.secondaryPreferred().getNode(_emptySet)); }
@Test public void testPrimaryWithNoPrimary() { assertNull(ReadPreference.primary().getNode(_setNoPrimary)); }
@Test public void testTaggedSecondaryWithNoSecondary() { final TaggableReadPreference taggedSecondaryReadPreference = ReadPreference.secondary(new BasicDBObject("dc", "ny")); assertNull(taggedSecondaryReadPreference.getNode(_setNoSecondary)); }
@Test public void testSecondaryWithNoSecondary() { assertNull(ReadPreference.secondary().getNode(_setNoSecondary)); }
@Test public void testTaggedSecondaryPreferredWithNoPrimaryOrSecondary() { final TaggableReadPreference readPreference = ReadPreference.secondaryPreferred(new BasicDBObject("dc", "ny")); assertNull(readPreference.getNode(_emptySet)); }