Skip to content

Commit

Permalink
MongoDB Java driver upgrade (#1989)
Browse files Browse the repository at this point in the history
MongoDB Java driver upgrade from mongo-java-driver to mongodb-driver-sync
This change needs some changes in MongoDB platform related classes.
Classes which used mongo-java-driver API were removed.
There is one incompatible change in native query as new driver accept different structure of the queries.
There is updated eclipselink-testbuild-plugin 1.1.0 with extended functionality to automatically download, start and stop MongoDB during tests.
Target test DB version was upgraded from 3.4.24 to 7.0.0.

Signed-off-by: Radek Felcman <radek.felcman@oracle.com>
  • Loading branch information
rfelcman committed Dec 22, 2023
1 parent e758900 commit 7f3ea19
Show file tree
Hide file tree
Showing 20 changed files with 261 additions and 841 deletions.
2 changes: 1 addition & 1 deletion bundles/others/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@
<!--Mongo DB-->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<artifactId>mongodb-driver-sync</artifactId>
</dependency>
<!--Oracle NoSQL DB-->
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion bundles/p2site/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@
<!--Mongo DB-->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<artifactId>mongodb-driver-sync</artifactId>
</dependency>
<!--Oracle NoSQL DB-->
<dependency>
Expand Down
2 changes: 1 addition & 1 deletion foundation/org.eclipse.persistence.nosql/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
<!--Mongo DB-->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<artifactId>mongodb-driver-sync</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -32,7 +32,7 @@
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientSettings;

/**
* Provides java.sql.Timestamp, java.sql.Date and java.sql.Time codecs.
Expand Down Expand Up @@ -64,7 +64,7 @@ public static CodecRegistry codecRegistry() {
new DateCodec(),
new TimeCodec()),
CodecRegistries.fromProviders(documentCodecProvider),
MongoClient.getDefaultCodecRegistry());
MongoClientSettings.getDefaultCodecRegistry());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -15,12 +15,17 @@
// Gunnar Wagenknecht - isExternal support
package org.eclipse.persistence.internal.nosql.adapters.mongo;

import jakarta.resource.*;
import jakarta.resource.cci.*;
import jakarta.resource.ResourceException;
import jakarta.resource.cci.Connection;
import jakarta.resource.cci.ConnectionMetaData;
import jakarta.resource.cci.Interaction;
import jakarta.resource.cci.LocalTransaction;
import jakarta.resource.cci.ResultSetInfo;

import org.eclipse.persistence.exceptions.ValidationException;

import com.mongodb.DB;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoDatabase;

/**
* Connection to Mongo
Expand All @@ -32,31 +37,41 @@
public class MongoConnection implements Connection {
protected MongoJCAConnectionSpec spec;
protected MongoTransaction transaction;
protected DB db;
protected MongoClient mongo;
protected String databaseName;
protected boolean isExternal;

/**
* Create the connection on a native AQ session.
* The session must be connected to a JDBC connection.
*/
public MongoConnection(DB db, boolean isExternal, MongoJCAConnectionSpec spec) {
this.db = db;
public MongoConnection(MongoClient mongo, String databaseName, boolean isExternal, MongoJCAConnectionSpec spec) {
this.mongo = mongo;
this.databaseName = databaseName;
this.transaction = new MongoTransaction(this);
this.spec = spec;
this.isExternal = isExternal;
}

public DB getDB() {
return db;
public MongoDatabase getDB() {
return mongo.getDatabase(databaseName);
}

public MongoClient getClient() {
return this.mongo;
}

public String getDatabaseName() {
return databaseName;
}

/**
* Close the AQ native session and the database connection.
* Close MongoDB client with all underlying cached resources.
*/
@Override
public void close() throws ResourceException {
try {
this.db.getMongo().close();
this.mongo.close();
} catch (Exception exception) {
ResourceException resourceException = new ResourceException(exception.toString());
resourceException.initCause(exception);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,25 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.naming.Reference;

import jakarta.resource.ResourceException;
import jakarta.resource.cci.Connection;
import jakarta.resource.cci.ConnectionFactory;
import jakarta.resource.cci.ConnectionSpec;
import jakarta.resource.cci.RecordFactory;
import jakarta.resource.cci.ResourceAdapterMetaData;

import com.mongodb.DB;
import com.mongodb.Mongo;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoClient;
import org.bson.Document;

/**
* Connection factory for Mongo JCA adapter.
Expand All @@ -38,8 +45,8 @@
* @since EclipseLink 2.4
*/
public class MongoConnectionFactory implements ConnectionFactory {
protected transient Mongo mongo;
protected transient DB db;
protected transient MongoClient mongo;
protected transient MongoDatabase db;

/**
* Default constructor.
Expand All @@ -50,14 +57,14 @@ public MongoConnectionFactory() {
/**
* Create a factory from an external mongo instance.
*/
public MongoConnectionFactory(Mongo mongo) {
public MongoConnectionFactory(MongoClient mongo) {
this.mongo = mongo;
}

/**
* Create a factory from an external mongo instance.
*/
public MongoConnectionFactory(DB db) {
public MongoConnectionFactory(MongoDatabase db) {
this.db = db;
}

Expand All @@ -69,11 +76,11 @@ public Connection getConnection() throws ResourceException {
@Override
public Connection getConnection(ConnectionSpec spec) throws ResourceException {
MongoJCAConnectionSpec connectionSpec = (MongoJCAConnectionSpec)spec;
DB db = this.db;
MongoDatabase db = this.db;
boolean isExternal = true;
if (db == null) {
try {
List<ServerAddress> servers = new ArrayList<ServerAddress>();
List<ServerAddress> servers = new ArrayList<>();
for (int index = 0; index < connectionSpec.getHosts().size(); index++) {
String host = connectionSpec.getHosts().get(index);
int port = ServerAddress.defaultPort();
Expand All @@ -87,43 +94,66 @@ public Connection getConnection(ConnectionSpec spec) throws ResourceException {
ServerAddress server = new ServerAddress("localhost", ServerAddress.defaultPort());
servers.add(server);
}
Mongo mongo = this.mongo;
MongoClient mongo = this.mongo;
if (mongo == null) {
isExternal = false;
MongoCredential credential = null;
if ((connectionSpec.getUser() != null) && (connectionSpec.getUser().length() > 0)) {
if ( connectionSpec.getAuthSource() != null ) {
credential = MongoCredential.createCredential(connectionSpec.getUser(), connectionSpec.getAuthSource(), connectionSpec.getPassword());
}
else {
credential = MongoCredential.createCredential(connectionSpec.getUser(), connectionSpec.getDB(), connectionSpec.getPassword());
}
}
MongoClientSettings.Builder settingsBuilder = MongoClientSettings.builder();
settingsBuilder.applyToClusterSettings(builder ->
builder.serverSelectionTimeout(connectionSpec.getServerSelectionTimeout(), TimeUnit.MILLISECONDS));
if (connectionSpec.getReadPreference() != null) {
settingsBuilder.readPreference(connectionSpec.getReadPreference());
}
if (connectionSpec.getWriteConcern() != null) {
settingsBuilder.writeConcern(connectionSpec.getWriteConcern());
}
settingsBuilder.codecRegistry(MongoCodecs.codecRegistry());
MongoClientSettings settings = null;
if (credential != null) {
settingsBuilder.credential(credential);
}
if (servers.isEmpty()) {
mongo = new Mongo();
ServerAddress serverAddress = new ServerAddress();
settings = settingsBuilder
.applyConnectionString(new ConnectionString("mongodb+srv://" + serverAddress.getHost() + ":" + serverAddress.getPort()))
.build();
mongo = MongoClients.create(settings);
} else {
mongo = new Mongo(servers);
settings = settingsBuilder
.applyToClusterSettings(builder ->
builder.hosts(servers))
.build();
mongo = MongoClients.create(settings);
}
this.mongo = mongo;
}
db = mongo.getDB(connectionSpec.getDB());
db = mongo.getDatabase(connectionSpec.getDB());
db.runCommand(new Document("ping", 1)); // check connection
if ((connectionSpec.getUser() != null) && (connectionSpec.getUser().length() > 0)) {
try {
Method method = DB.class.getMethod("authenticate", String.class, char[].class);
Method method = MongoDatabase.class.getMethod("authenticate", String.class, char[].class);
if (!(Boolean) method.invoke(db, connectionSpec.getUser(), connectionSpec.getPassword())) {
throw new ResourceException("authenticate failed for user: " + connectionSpec.getUser());
}
} catch (ReflectiveOperationException e) {
throw new ResourceException("authenticate method not supported: " + e.getMessage(), e);
}
}
if (connectionSpec.getOptions() > 0) {
db.setOptions(connectionSpec.getOptions());
}
if (connectionSpec.getReadPreference() != null) {
db.setReadPreference(connectionSpec.getReadPreference());
}
if (connectionSpec.getWriteConcern() != null) {
db.setWriteConcern(connectionSpec.getWriteConcern());
}
} catch (/*UnknownHost*/Exception exception) {
ResourceException resourceException = new ResourceException(exception.toString());
resourceException.initCause(exception);
throw resourceException;
}
}

return new MongoConnection(db, isExternal, connectionSpec);
return new MongoConnection(mongo, connectionSpec.getDB(), isExternal, connectionSpec);
}

@Override
Expand All @@ -145,19 +175,19 @@ public Reference getReference() {
public void setReference(Reference reference) {
}

public Mongo getMongo() {
public MongoClient getMongo() {
return mongo;
}

public void setMongo(Mongo mongo) {
public void setMongo(MongoClient mongo) {
this.mongo = mongo;
}

public DB getDb() {
public MongoDatabase getDb() {
return db;
}

public void setDb(DB db) {
public void setDb(MongoDatabase db) {
this.db = db;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -14,11 +14,11 @@
// Oracle - initial API and implementation
package org.eclipse.persistence.internal.nosql.adapters.mongo;

import jakarta.resource.*;
import jakarta.resource.cci.*;
import jakarta.resource.ResourceException;
import jakarta.resource.cci.ConnectionMetaData;

import com.mongodb.BasicDBObject;
import com.mongodb.CommandResult;
import org.bson.BsonDocument;
import org.bson.BsonString;

/**
* Defines the meta-data for the Mongo adaptor
Expand All @@ -43,9 +43,11 @@ protected MongoConnectionMetaData() {
}

protected String getVersion() {
BasicDBObject command = new BasicDBObject("buildInfo", null);
CommandResult buildInfo = this.connection.getDB().command(command);
return buildInfo.getString("version");
String version = this.connection.getClient().getDatabase(this.connection.getDatabaseName())
.runCommand(new BsonDocument("buildinfo", new BsonString("")))
.get("version")
.toString();
return version;
}

@Override
Expand All @@ -69,7 +71,7 @@ public String getEISProductVersion() throws ResourceException {
@Override
public String getUserName() throws ResourceException {
try {
return "";
return this.connection.getConnectionSpec().getUser();
} catch (Exception exception) {
throw new ResourceException(exception.toString());
}
Expand Down

0 comments on commit 7f3ea19

Please sign in to comment.