| /* |
| * Copyright (c) 2011, 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 |
| package org.eclipse.persistence.nosql.adapters.mongo; |
| |
| import java.util.Properties; |
| |
| import jakarta.resource.cci.Connection; |
| import jakarta.resource.cci.ConnectionFactory; |
| |
| import org.eclipse.persistence.eis.EISAccessor; |
| import org.eclipse.persistence.eis.EISConnectionSpec; |
| import org.eclipse.persistence.eis.EISException; |
| import org.eclipse.persistence.exceptions.DatabaseException; |
| import org.eclipse.persistence.exceptions.ValidationException; |
| import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoConnectionFactory; |
| import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoDatabaseConnectionFactory; |
| import org.eclipse.persistence.internal.nosql.adapters.mongo.MongoJCAConnectionSpec; |
| |
| import com.mongodb.ReadPreference; |
| import com.mongodb.WriteConcern; |
| |
| /** |
| * Provides connection information to the Mongo database. |
| * |
| * @author James |
| * @since EclipseLink 2.4 |
| */ |
| public class MongoConnectionSpec extends EISConnectionSpec { |
| |
| /** Connection spec properties. */ |
| public static final String HOST = "mongo.host"; |
| public static final String PORT = "mongo.port"; |
| public static final String DB = "mongo.db"; |
| public static final String OPTIONS = "mongo.options"; |
| public static final String READ_PREFERENCE = "mongo.read-preference"; |
| public static final String WRITE_CONCERN = "mongo.write-concern"; |
| public static final String SERVER_SELECTION_TIMEOUT = "mongo.server-selection-timeout"; |
| |
| /** |
| * PUBLIC: |
| * Default constructor. |
| */ |
| public MongoConnectionSpec() { |
| super(); |
| } |
| |
| /** |
| * Connect with the specified properties and return the Connection. |
| */ |
| @Override |
| public Connection connectToDataSource(EISAccessor accessor, Properties properties) throws DatabaseException, ValidationException { |
| if ((this.connectionFactory == null) && (this.name == null)) { |
| this.connectionFactory = createMongoConnectionFactory(); |
| } |
| if (!properties.isEmpty()) { |
| if (this.connectionSpec == null) { |
| this.connectionSpec = new MongoJCAConnectionSpec(); |
| } |
| MongoJCAConnectionSpec spec = (MongoJCAConnectionSpec)this.connectionSpec; |
| String host = (String)properties.get(HOST); |
| String port = (String)properties.get(PORT); |
| String db = (String)properties.get(DB); |
| if (host != null) { |
| if (host.indexOf(',') == -1) { |
| spec.getHosts().add(host); |
| if (port != null) { |
| spec.getPorts().add(Integer.valueOf(port)); |
| } |
| } else { |
| int startIndex = 0; |
| while (startIndex < (host.length() - 1)) { |
| int endIndex = host.indexOf(',', startIndex); |
| if (endIndex == -1) { |
| endIndex = host.length(); |
| } |
| String nextHost = host.substring(startIndex, endIndex); |
| spec.getHosts().add(nextHost); |
| startIndex = endIndex + 1; |
| } |
| while (startIndex < (port.length() - 1)) { |
| int endIndex = port.indexOf(',', startIndex); |
| if (endIndex == -1) { |
| endIndex = port.length(); |
| } |
| String nextPort = port.substring(startIndex, endIndex); |
| spec.getPorts().add(Integer.valueOf(nextPort)); |
| startIndex = endIndex + 1; |
| } |
| } |
| } |
| if (db != null) { |
| spec.setDB(db); |
| } |
| |
| String user = (String)properties.get("user"); |
| Object password = properties.get("password"); |
| if (password instanceof String) { |
| password = ((String) password).toCharArray(); |
| } |
| if ((user != null) && (user.length() != 0)) { |
| spec.setUser(user); |
| spec.setPassword((char[])password); |
| } |
| |
| // Allows setting of read preference as a property. |
| Object preference = properties.get(READ_PREFERENCE); |
| if (preference instanceof ReadPreference) { |
| spec.setReadPreference((ReadPreference)preference); |
| } else if (preference instanceof String) { |
| String constant = (String)preference; |
| if (constant.equals("PRIMARY")) { |
| spec.setReadPreference(ReadPreference.primary()); |
| } else if (constant.equals("SECONDARY")) { |
| spec.setReadPreference(ReadPreference.secondary()); |
| } else { |
| throw new EISException("Invalid read preference property value: " + constant); |
| } |
| } |
| |
| // Allows setting of write concern as a property. |
| Object concern = properties.get(WRITE_CONCERN); |
| if (concern instanceof WriteConcern) { |
| spec.setWriteConcern((WriteConcern)concern); |
| } else if (concern instanceof String) { |
| String constant = (String)concern; |
| if (constant.equals("FSYNC_SAFE")) { |
| spec.setWriteConcern(WriteConcern.FSYNC_SAFE); |
| } else if (constant.equals("JOURNAL_SAFE")) { |
| spec.setWriteConcern(WriteConcern.JOURNAL_SAFE); |
| } else if (constant.equals("MAJORITY")) { |
| spec.setWriteConcern(WriteConcern.MAJORITY); |
| } else if (constant.equals("NONE")) { |
| spec.setWriteConcern(/*FIXME: WriteConcern.NONE*/ new WriteConcern("none")); |
| } else if (constant.equals("NORMAL")) { |
| spec.setWriteConcern(WriteConcern.NORMAL); |
| } else if (constant.equals("REPLICAS_SAFE")) { |
| spec.setWriteConcern(WriteConcern.REPLICAS_SAFE); |
| } else if (constant.equals("SAFE")) { |
| spec.setWriteConcern(WriteConcern.SAFE); |
| } else { |
| throw new EISException("Invalid read preference property value: " + constant); |
| } |
| } |
| |
| // Allows setting of options as a property. |
| Object options = properties.get(OPTIONS); |
| if (options instanceof Number) { |
| spec.setOptions(((Number)options).intValue()); |
| } else if (options instanceof String) { |
| spec.setOptions(Integer.parseInt(((String)options))); |
| } |
| |
| // Allows setting of serverSelectionTimeout as a property. |
| Object serverSelectionTimeout = properties.get(SERVER_SELECTION_TIMEOUT); |
| if (serverSelectionTimeout instanceof Number) { |
| spec.setServerSelectionTimeout(((Number)serverSelectionTimeout).intValue()); |
| } else if (serverSelectionTimeout instanceof String) { |
| spec.setServerSelectionTimeout(Integer.parseInt(((String)serverSelectionTimeout))); |
| } |
| } |
| |
| return super.connectToDataSource(accessor, properties); |
| } |
| |
| protected ConnectionFactory createMongoConnectionFactory() { |
| try { |
| Class.forName("com.mongodb.client.MongoDatabase"); |
| return new MongoDatabaseConnectionFactory(); |
| } catch (ClassNotFoundException e) { |
| return new MongoConnectionFactory(); |
| } |
| } |
| |
| } |