Uploaded image for project: 'Java Driver'
  1. Java Driver
  2. JAVA-2421

When setting readPreference=nearest arbiter can be selected and operation errors out

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 3.4.2
    • Affects Version/s: 3.4.0
    • Component/s: Cluster Management
    • None

      When setting readPreference to nearest the driver can pick an arbiter and error out.

      We have gotten this to happen using Java driver 3.4.0 and MongoDB 3.2.11. On my local mac running a replica set PSA, regardless of connection string I can get the arbiter to be used:

      Start up PSA with mlaunch:

      mlaunch init --dir ./repl --replicaset --arbiter 1 --nodes 2 --auth
      

      Java code:

      package mongodbjava;
      
      import com.mongodb.MongoClient;
      import com.mongodb.MongoClientURI;
      import com.mongodb.ReadPreference;
      import com.mongodb.client.MongoCollection;
      import com.mongodb.client.MongoCursor;
      import com.mongodb.client.MongoDatabase;
      import static com.mongodb.client.model.Filters.eq;
      import org.bson.Document;
      
      public class MongoDBJava {
      
          public static void main(String[] args) {
      
              MongoClientURI uri = new MongoClientURI( args[0] );
              MongoClient mongoClient = new MongoClient( uri );
              MongoDatabase database = mongoClient.getDatabase("foo");
              MongoCollection collection = database.getCollection("blah").withReadPreference(ReadPreference.nearest());
              MongoCursor<Document> cursor = collection.find( eq( "name", "roy" ) ).iterator();
              try {
                  while ( cursor.hasNext() ) {
                      System.out.println( cursor.next().toJson() );
                  }
              }
              finally {
                  cursor.close();
              }
          }
          
      }
      

      Run java code with the primary and secondary in connection string:

      java -cp lib/*:dist/MongoDBJava.jar mongodbjava.MongoDBJava "mongodb://user:password@localhost:27017,localhost:27018/?authSource=admin"
      

      Error:

      INFO: Monitor thread successfully connected to server with description ServerDescription{address=roys-macbook-pro-2.local:27018, type=REPLICA_SET_SECONDARY, state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 2, 4]}, minWireVersion=0, maxWireVersion=4, maxDocumentSize=16777216, roundTripTimeNanos=1126490, setName='replset', canonicalAddress=Roys-MacBook-Pro-2.local:27018, hosts=[Roys-MacBook-Pro-2.local:27017, Roys-MacBook-Pro-2.local:27018], passives=[], arbiters=[Roys-MacBook-Pro-2.local:27019], primary='Roys-MacBook-Pro-2.local:27017', tagSet=TagSet{[]}, electionId=null, setVersion=1, lastWriteDate=null, lastUpdateTimeNanos=248383248908752}
      Exception in thread "main" com.mongodb.MongoQueryException: Query failed with error code 13 and error message 'not authorized on foo to execute command { find: "blah", filter: { name: "roy" } }' on server roys-macbook-pro-2.local:27019
      	at com.mongodb.operation.FindOperation$1.call(FindOperation.java:521)
      	at com.mongodb.operation.FindOperation$1.call(FindOperation.java:510)
      	at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:431)
      	at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:404)
      	at com.mongodb.operation.FindOperation.execute(FindOperation.java:510)
      	at com.mongodb.operation.FindOperation.execute(FindOperation.java:81)
      	at com.mongodb.Mongo.execute(Mongo.java:836)
      	at com.mongodb.Mongo$2.execute(Mongo.java:823)
      	at com.mongodb.OperationIterable.iterator(OperationIterable.java:47)
      	at com.mongodb.FindIterableImpl.iterator(FindIterableImpl.java:151)
      	at mongodbjava.MongoDBJava.main(MongoDBJava.java:48)
      

      Weirdly I get a different error when running a PSA in Amazon using Cloud Manager. This setup has the arbiter on the west coast and the data bearing nodes on the east coast.
      https://cloud.mongodb.com/v2/570551eee4b0360b09261739#deployment/topology

      Running the code on the west coast server:

      java -cp lib/*:MongoDBJava.jar mongodbjava.MongoDBJava "mongodb://joe:password@royrim-0.royrim.9512.mongodbdns.com:27000,royrim-1.royrim.9512.mongodbdns.com:27000,royrim-3.royrim.9512.mongodbdns.com:27000/?authSource=admin"
      

      Error:

      INFO: Closed connection [connectionId{localValue:4, serverValue:2547}] to royrim-3.royrim.9512.mongodbdns.com:27000 because there was a socket exception raised on another connection from this pool.
      Exception in thread "main" com.mongodb.MongoNodeIsRecoveringException: The server is in recovery mode and did not execute the operation
      	at com.mongodb.connection.ProtocolHelper.createSpecialException(ProtocolHelper.java:173)
      	at com.mongodb.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:111)
      	at com.mongodb.connection.CommandProtocol.execute(CommandProtocol.java:114)
      	at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:168)
      	at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:289)
      	at com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:176)
      	at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:216)
      	at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:207)
      	at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:113)
      	at com.mongodb.operation.FindOperation$1.call(FindOperation.java:516)
      	at com.mongodb.operation.FindOperation$1.call(FindOperation.java:510)
      	at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:431)
      	at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:404)
      	at com.mongodb.operation.FindOperation.execute(FindOperation.java:510)
      	at com.mongodb.operation.FindOperation.execute(FindOperation.java:81)
      	at com.mongodb.Mongo.execute(Mongo.java:836)
      	at com.mongodb.Mongo$2.execute(Mongo.java:823)
      	at com.mongodb.OperationIterable.iterator(OperationIterable.java:47)
      	at com.mongodb.FindIterableImpl.iterator(FindIterableImpl.java:151)
      	at mongodbjava.MongoDBJava.main(MongoDBJava.java:31)
      

      Weirdly if I leave off the arbiter from the connection string I don't get an error:

      java -cp lib/*:MongoDBJava.jar mongodbjava.MongoDBJava "mongodb://joe:password@royrim-0.royrim.9512.mongodbdns.com:27000,royrim-1.royrim.9512.mongodbdns.com:27000/?authSource=admin"
      

      Regards,
      Roy

            Assignee:
            jeff.yemin@mongodb.com Jeffrey Yemin
            Reporter:
            roy.rim@mongodb.com Roy Rim (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: