blob: a605ae7f65b03f888264497d8931cc49e2c23d7a [file] [log] [blame]
/*
* Copyright (c) 2015, 2020 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
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation
// Gunnar Wagenknecht - external support
package org.eclipse.persistence.internal.nosql.adapters.mongo;
import java.util.ArrayList;
import java.util.List;
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 org.bson.Document;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoClientOptions.Builder;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoDatabase;
/**
* Connection factory for Mongo JCA adapter.
*
* @author James
* @since EclipseLink 2.4
*/
public class MongoDatabaseConnectionFactory implements ConnectionFactory {
protected transient MongoClient mongo;
protected transient MongoDatabase db;
/**
* Default constructor.
*/
public MongoDatabaseConnectionFactory() {
}
/**
* Create a factory from an external mongo instance.
*/
public MongoDatabaseConnectionFactory(MongoClient mongo) {
this.mongo = mongo;
}
/**
* Create a factory from an external mongo instance.
*/
public MongoDatabaseConnectionFactory(MongoDatabase db) {
this.db = db;
}
@Override
public Connection getConnection() throws ResourceException {
return getConnection(new MongoJCAConnectionSpec());
}
@Override
public Connection getConnection(ConnectionSpec spec) throws ResourceException {
MongoJCAConnectionSpec connectionSpec = (MongoJCAConnectionSpec)spec;
MongoDatabase db = this.db;
boolean isExternal = true;
if (db == null) {
List<ServerAddress> servers = new ArrayList<ServerAddress>();
for (int index = 0; index < connectionSpec.getHosts().size(); index++) {
String host = connectionSpec.getHosts().get(index);
int port = ServerAddress.defaultPort();
if (connectionSpec.getPorts().size() > index) {
port = connectionSpec.getPorts().get(index);
}
ServerAddress server = new ServerAddress(host, port);
servers.add(server);
}
if (connectionSpec.getHosts().isEmpty()) {
ServerAddress server = new ServerAddress("localhost", ServerAddress.defaultPort());
servers.add(server);
}
MongoClient mongo = this.mongo;
if (mongo == null) {
isExternal = false;
List<MongoCredential> credentialsList = new ArrayList<>();
if ((connectionSpec.getUser() != null) && (connectionSpec.getUser().length() > 0)) {
MongoCredential credential = MongoCredential.createCredential(connectionSpec.getUser(), connectionSpec.getDB(), connectionSpec.getPassword());
credentialsList.add(credential);
}
Builder optionsBuilder = new MongoClientOptions.Builder();
optionsBuilder.serverSelectionTimeout(connectionSpec.getServerSelectionTimeout());
if (connectionSpec.getReadPreference() != null) {
optionsBuilder.readPreference(connectionSpec.getReadPreference());
}
if (connectionSpec.getWriteConcern() != null) {
optionsBuilder.writeConcern(connectionSpec.getWriteConcern());
}
optionsBuilder.codecRegistry(MongoCodecs.codecRegistry());
MongoClientOptions options = optionsBuilder.build();
if (servers.isEmpty()) {
mongo = new MongoClient(new ServerAddress(), credentialsList, options);
} else {
mongo = new MongoClient(servers, credentialsList, options);
}
}
db = mongo.getDatabase(connectionSpec.getDB());
try {
db.runCommand(new Document("ping", 1)); // check connection
} catch (Exception exception) {
ResourceException resourceException = new ResourceException(exception);
resourceException.initCause(exception);
throw resourceException;
}
}
return new MongoDatabaseConnection(mongo, db, isExternal, connectionSpec);
}
@Override
public ResourceAdapterMetaData getMetaData() {
return new MongoAdapterMetaData();
}
@Override
public RecordFactory getRecordFactory() {
return new MongoRecordFactory();
}
@Override
public Reference getReference() {
return new Reference(getClass().getName());
}
@Override
public void setReference(Reference reference) {
}
public MongoClient getMongo() {
return mongo;
}
public void setMongo(MongoClient mongo) {
this.mongo = mongo;
}
public MongoDatabase getDb() {
return db;
}
public void setDb(MongoDatabase db) {
this.db = db;
}
}