@ FFDCIgnore ( InvocationTargetException . class ) Object getDB ( String databaseName ) throws Exception { final boolean trace = TraceComponent . isAnyTracingEnabled ( ) ; lock . readLock ( ) . lock ( ) ; try { if ( mongoClient == null ) { // Switch to write lock for lazy initialization lock . readLock ( ) . unlock ( ) ; lock . writeLock ( ) . lock ( ) ; try { if ( mongoClient == null ) init ( ) ; } finally { // Downgrade to read lock for rest of method lock . readLock ( ) . lock ( ) ; lock . writeLock ( ) . unlock ( ) ; } } Object db = MongoClient_getDB . invoke ( mongoClient , databaseName ) ; // authentication String user = ( String ) props . get ( USER ) ; if ( user != null ) { if ( ( Boolean ) DB_isAuthenticated . invoke ( db ) ) { if ( trace && tc . isDebugEnabled ( ) ) Tr . debug ( this , tc , "already authenticated" ) ; } else { if ( trace && tc . isDebugEnabled ( ) ) Tr . debug ( this , tc , "authenticate as: " + user ) ; SerializableProtectedString password = ( SerializableProtectedString ) props . get ( PASSWORD ) ; String pwdStr = password == null ? null : String . valueOf ( password . getChars ( ) ) ; pwdStr = PasswordUtil . getCryptoAlgorithm ( pwdStr ) == null ? pwdStr : PasswordUtil . decode ( pwdStr ) ; char [ ] pwdChars = pwdStr == null ? null : pwdStr . toCharArray ( ) ; try { if ( ! ( Boolean ) DB_authenticate . invoke ( db , user , pwdChars ) ) if ( ( Boolean ) DB_isAuthenticated . invoke ( db ) ) { if ( trace && tc . isDebugEnabled ( ) ) Tr . debug ( this , tc , "another thread must have authenticated first" ) ; } else throw new IllegalArgumentException ( Tr . formatMessage ( tc , "CWKKD0012.authentication.error" , MONGO , id , databaseName ) ) ; } catch ( InvocationTargetException x ) { // If already authenticated, Mongo raises: // IllegalStateException: can't authenticate twice on the same database // Maybe another thread did the authentication right after we checked, so check again. Throwable cause = x . getCause ( ) ; if ( cause instanceof IllegalStateException && ( Boolean ) DB_isAuthenticated . invoke ( db ) ) { if ( trace && tc . isDebugEnabled ( ) ) Tr . debug ( this , tc , "another thread must have authenticated first" , cause ) ; } else throw cause ; } } } else if ( useCertAuth ) { // If we specified a certificate we will already have used the client constructor that // specified the credential so if we have got to here we are already authenticated and // JIT should remove this so it will not be an overhead. } return db ; } catch ( Throwable x ) { // rethrowing the exception allows it to be captured in FFDC and traced automatically x = x instanceof InvocationTargetException ? x . getCause ( ) : x ; if ( x instanceof Exception ) throw ( Exception ) x ; else if ( x instanceof Error ) throw ( Error ) x ; else throw new RuntimeException ( x ) ; } finally { lock . readLock ( ) . unlock ( ) ; } }
Get a Mongo DB instance authenticated with the specified user and password if specified .