/*
* Hibernate OGM, Domain model persistence for NoSQL datastores
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.ogm.datastore.mongodb.test.datastore;
import static org.fest.assertions.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.ogm.cfg.OgmProperties;
import org.hibernate.ogm.datastore.mongodb.MongoDBProperties;
import org.hibernate.ogm.datastore.mongodb.configuration.impl.MongoDBConfiguration;
import org.hibernate.ogm.datastore.mongodb.impl.MongoDBDatastoreProvider;
import org.hibernate.ogm.datastore.mongodb.options.AuthenticationMechanismType;
import org.hibernate.ogm.datastore.spi.DatastoreProvider;
import org.hibernate.ogm.utils.SkippableTestRunner;
import org.hibernate.ogm.utils.TestHelper;
import org.hibernate.service.spi.ServiceException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
/**
* @author Emmanuel Bernard <emmanuel@hibernate.org>
* @author Hardy Ferentschik
*/
@RunWith(SkippableTestRunner.class)
public class DatastoreInitializationTest {
/**
* The IP address 203.0.113.1 has been chosen because of: "203.0.113.0/24 No Assigned as "TEST-NET-3" in RFC 5737
* for use solely in documentation and example source code and should not be used publicly."
*/
private static final String NON_EXISTENT_IP = "203.0.113.1";
@Rule
public ExpectedException error = ExpectedException.none();
private Map<String, Object> cfg;
@Before
public void setUp() {
cfg = new HashMap<String, Object>( TestHelper.getDefaultTestSettings() );
cfg.put( OgmProperties.DATABASE, "snafu" );
cfg.put( OgmProperties.USERNAME, "foo" );
cfg.put( OgmProperties.PASSWORD, "bar" );
cfg.put( "hibernate.ogm.mongodb.driver.serverSelectionTimeout", "1000" );
}
@Test
public void testAuthentication() throws Exception {
error.expect( ServiceException.class );
error.expectMessage( "OGM000071" );
// the timeout exception thrown by the driver will actually contain some information about the authentication
// error. Obviously quite fragile. Might change
error.expectCause( hasMessage( containsString( "Exception authenticating" ) ) );
StandardServiceRegistry serviceRegistry = TestHelper.getDefaultTestStandardServiceRegistry( cfg );
// will start the service
serviceRegistry.getService( DatastoreProvider.class );
}
@Test
public void testDefaultAuthenticationMechanism() throws Exception {
LeakingMongoDBDatastoreProvider provider = new LeakingMongoDBDatastoreProvider();
cfg.put( OgmProperties.DATASTORE_PROVIDER, provider );
// will start the service
TestHelper.getDefaultTestStandardServiceRegistry( cfg ).getService( DatastoreProvider.class );
assertThat( provider.leakingClient.getCredentialsList().get( 0 ).getMechanism() ).isEqualTo( null );
}
@Test
public void testSCRAMSHA1AuthenticationMechanism() throws Exception {
LeakingMongoDBDatastoreProvider provider = new LeakingMongoDBDatastoreProvider();
cfg.put( MongoDBProperties.AUTHENTICATION_MECHANISM, AuthenticationMechanismType.SCRAM_SHA_1.name() );
cfg.put( OgmProperties.DATASTORE_PROVIDER, provider );
// will start the service
TestHelper.getDefaultTestStandardServiceRegistry( cfg ).getService( DatastoreProvider.class );
assertThat(
provider.leakingClient.getCredentialsList()
.get( 0 )
.getMechanism()
).isEqualTo( MongoCredential.SCRAM_SHA_1_MECHANISM );
}
@Test
public void testX509AuthenticationMechanism() throws Exception {
LeakingMongoDBDatastoreProvider provider = new LeakingMongoDBDatastoreProvider();
cfg.put( MongoDBProperties.AUTHENTICATION_MECHANISM, AuthenticationMechanismType.MONGODB_X509.name() );
cfg.put( OgmProperties.DATASTORE_PROVIDER, provider );
// will start the service
TestHelper.getDefaultTestStandardServiceRegistry( cfg ).getService( DatastoreProvider.class );
assertThat(
provider.leakingClient.getCredentialsList()
.get( 0 )
.getMechanism()
).isEqualTo( MongoCredential.MONGODB_X509_MECHANISM );
}
@Test
public void testGSSAPIAuthenticationMechanism() throws Exception {
LeakingMongoDBDatastoreProvider provider = new LeakingMongoDBDatastoreProvider();
cfg.put( MongoDBProperties.AUTHENTICATION_MECHANISM, AuthenticationMechanismType.GSSAPI.name() );
cfg.put( OgmProperties.DATASTORE_PROVIDER, provider );
// will start the service
TestHelper.getDefaultTestStandardServiceRegistry( cfg ).getService( DatastoreProvider.class );
assertThat(
provider.leakingClient.getCredentialsList()
.get( 0 )
.getMechanism()
).isEqualTo( MongoCredential.GSSAPI_MECHANISM );
}
@Test
public void testPlainAuthenticationMechanism() throws Exception {
LeakingMongoDBDatastoreProvider provider = new LeakingMongoDBDatastoreProvider();
cfg.put( MongoDBProperties.AUTHENTICATION_MECHANISM, AuthenticationMechanismType.PLAIN.name() );
cfg.put( OgmProperties.DATASTORE_PROVIDER, provider );
// will start the service
TestHelper.getDefaultTestStandardServiceRegistry( cfg ).getService( DatastoreProvider.class );
assertThat(
provider.leakingClient.getCredentialsList()
.get( 0 )
.getMechanism()
).isEqualTo( MongoCredential.PLAIN_MECHANISM );
}
@Test
public void testNotRecognizedAuthenticationMechanism() throws Exception {
cfg.put( MongoDBProperties.AUTHENTICATION_MECHANISM, "alhdfoiehfnl" );
error.expect( ServiceException.class );
error.expectMessage( "OGM000072" );
//nested exception
error.expectCause( hasMessage( containsString( "OGM000051" ) ) );
// will start the service
TestHelper.getDefaultTestStandardServiceRegistry( cfg ).getService( DatastoreProvider.class );
}
@Test
public void testConnectionErrorWrappedInHibernateException() throws Exception {
cfg.put( OgmProperties.HOST, NON_EXISTENT_IP );
error.expect( ServiceException.class );
error.expectMessage( "OGM000071" );
//nested exception
error.expectCause( hasMessage( containsString( "OGM001214" ) ) );
// will start the service
TestHelper.getDefaultTestStandardServiceRegistry( cfg ).getService( DatastoreProvider.class );
}
@Test
public void testConnectionTimeout() {
cfg.put( OgmProperties.HOST, NON_EXISTENT_IP );
cfg.put( OgmProperties.DATABASE, "ogm_test_database" );
error.expect( ServiceException.class );
error.expectMessage( "OGM000071" );
// the timeout exception thrown by the driver will actually contain some information about the authentication
// error. Obviously quite fragile. Might change
error.expectCause( hasMessage( containsString( "Timed out" ) ) );
// will start the service
TestHelper.getDefaultTestStandardServiceRegistry( cfg ).getService( DatastoreProvider.class );
}
class LeakingMongoDBDatastoreProvider extends MongoDBDatastoreProvider {
public MongoClient leakingClient;
@Override
protected MongoClient createMongoClient(MongoDBConfiguration config) {
MongoClient mongoClient = super.createMongoClient( config );
this.leakingClient = mongoClient;
return mongoClient;
}
@Override
public void start() {
try {
super.start();
}
catch ( Exception e ) {
}
}
}
}