Skip to content

Commit 2c6eb77

Browse files
committed
[JAVA-270]: If authentication is on for a replica set, then most likely all writes will always fail once primary server dies
1 parent 4bc9220 commit 2c6eb77

File tree

4 files changed

+35
-30
lines changed

4 files changed

+35
-30
lines changed

src/main/com/mongodb/DBPort.java

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
/**
3030
* represents a Port to the database, which is effectively a single connection to a server
31+
* Methods implemented at the port level should throw the raw exceptions like IOException,
32+
* so that the connector above can make appropriate decisions on how to handle.
3133
* @author antoine
3234
*/
3335
public class DBPort {
@@ -117,29 +119,23 @@ private synchronized Response go( OutMessage msg , DBCollection coll , boolean f
117119
}
118120
}
119121

120-
synchronized CommandResult getLastError( DB db , WriteConcern concern){
122+
synchronized CommandResult getLastError( DB db , WriteConcern concern) throws IOException {
121123
DBApiLayer dbAL = (DBApiLayer) db;
122124
return runCommand( dbAL , concern.getCommand() );
123125
}
124126

125-
synchronized DBObject findOne( DB db , String coll , DBObject q ){
127+
synchronized DBObject findOne( DB db , String coll , DBObject q ) throws IOException {
126128
OutMessage msg = OutMessage.query( db._mongo , 0 , db.getName() + "." + coll , 0 , -1 , q , null );
127129

128-
try {
129-
Response res = go( msg , db.getCollection( coll ) );
130-
if ( res.size() == 0 )
131-
return null;
132-
if ( res.size() > 1 )
133-
throw new MongoInternalException( "something is wrong. size:" + res.size() );
134-
return res.get(0);
135-
}
136-
catch ( IOException ioe ){
137-
throw new MongoException.Network( "DBPort.findOne failed" , ioe );
138-
}
139-
130+
Response res = go( msg , db.getCollection( coll ) );
131+
if ( res.size() == 0 )
132+
return null;
133+
if ( res.size() > 1 )
134+
throw new MongoInternalException( "something is wrong. size:" + res.size() );
135+
return res.get(0);
140136
}
141137

142-
synchronized CommandResult runCommand( DB db , DBObject cmd ) {
138+
synchronized CommandResult runCommand( DB db , DBObject cmd ) throws IOException {
143139
DBObject res = findOne( db , "$cmd" , cmd );
144140
if ( res == null )
145141
throw new MongoInternalException( "something is wrong, no command result" );
@@ -173,7 +169,7 @@ synchronized CommandResult runCommand( String db , DBObject cmd ) {
173169
}
174170

175171

176-
synchronized CommandResult tryGetLastError( DB db , long last, WriteConcern concern){
172+
synchronized CommandResult tryGetLastError( DB db , long last, WriteConcern concern) throws IOException {
177173
if ( last != _calls )
178174
return null;
179175

@@ -281,7 +277,7 @@ protected void close(){
281277
_socket = null;
282278
}
283279

284-
void checkAuth( DB db ){
280+
void checkAuth( DB db ) throws IOException {
285281
if ( db._username == null ){
286282
if ( db._name.equals( "admin" ) )
287283
return;

src/main/com/mongodb/DBTCPConnector.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,12 @@ void _checkClosed(){
118118

119119
WriteResult _checkWriteError( DB db , MyPort mp , DBPort port , WriteConcern concern )
120120
throws MongoException {
121-
122-
CommandResult e = port.runCommand( db , concern.getCommand() );
121+
CommandResult e = null;
122+
try {
123+
e = port.runCommand( db , concern.getCommand() );
124+
} catch ( IOException ioe ){
125+
throw new MongoException.Network( ioe.getMessage() , ioe );
126+
}
123127
mp.done( port );
124128

125129
Object foo = e.get( "err" );
@@ -150,9 +154,9 @@ public WriteResult say( DB db , OutMessage m , WriteConcern concern , ServerAddr
150154

151155
MyPort mp = _myPort.get();
152156
DBPort port = mp.get( true , false , hostNeeded );
153-
port.checkAuth( db );
154157

155158
try {
159+
port.checkAuth( db );
156160
port.say( m );
157161
if ( concern.callGetLastError() ){
158162
return _checkWriteError( db , mp , port , concern );
@@ -204,11 +208,10 @@ public Response call( DB db , DBCollection coll , OutMessage m , ServerAddress h
204208

205209
final MyPort mp = _myPort.get();
206210
final DBPort port = mp.get( false , slaveOk, hostNeeded );
207-
208-
port.checkAuth( db );
209-
211+
210212
Response res = null;
211213
try {
214+
port.checkAuth( db );
212215
res = port.call( m , coll );
213216
mp.done( port );
214217
if ( res._responseTo != m.getId() )
@@ -398,8 +401,9 @@ void testMaster()
398401
try {
399402
p = _masterPortPool.get();
400403
p.runCommand( _mongo.getDB("admin") , new BasicDBObject( "nonce" , 1 ) );
401-
}
402-
finally {
404+
} catch ( IOException ioe ){
405+
throw new MongoException.Network( ioe.getMessage() , ioe );
406+
} finally {
403407
_masterPortPool.done( p );
404408
}
405409
}

src/main/com/mongodb/ReplicaSetStatus.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,14 +192,12 @@ else if ( !_setName.equals( setName ) ){
192192

193193
// TODO: look at members
194194
}
195-
}
196-
197-
catch ( MongoException e ){
195+
} catch ( MongoException e ){
198196
if ( _setName != null ){
199197
// this probably means the master is busy, so going to ignore
200198
}
201199
else {
202-
_logger.log( Level.SEVERE , "can't get intial config from node: " + _addr , e );
200+
_logger.log( Level.SEVERE , "can't get initial config from node: " + _addr , e );
203201
}
204202
}
205203
catch ( Exception e ){

src/main/com/mongodb/WriteResult.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
package com.mongodb;
44

5+
import java.io.IOException;
6+
57

68
/**
79
* Copyright (C) 2008 10gen Inc.
@@ -86,7 +88,12 @@ public synchronized CommandResult getLastError(WriteConcern concern){
8688

8789
// here we dont have a satisfying result
8890
if ( _port != null ){
89-
_lastErrorResult = _port.tryGetLastError( _db , _lastCall , (concern == null) ? new WriteConcern() : concern );
91+
try {
92+
_lastErrorResult = _port.tryGetLastError( _db , _lastCall , (concern == null) ? new WriteConcern() : concern );
93+
} catch ( IOException ioe ){
94+
throw new MongoException.Network( ioe.getMessage() , ioe );
95+
}
96+
9097
if (_lastErrorResult == null)
9198
throw new IllegalStateException( "The connection may have been used since this write, cannot obtain a result" );
9299
_lastConcern = concern;

0 commit comments

Comments
 (0)