| /* |
| * Copyright (c) 1998, 2022 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: |
| // 05/28/2008-1.0M8 Andrei Ilitchev |
| // - New file introduced for bug 224964: Provide support for Proxy Authentication through JPA. |
| package org.eclipse.persistence.testing.framework.oracle; |
| |
| import java.sql.SQLException; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| import oracle.ucp.jdbc.PoolDataSource; |
| import oracle.ucp.jdbc.PoolDataSourceFactory; |
| |
| import org.eclipse.persistence.sessions.JNDIConnector; |
| import org.eclipse.persistence.sessions.DatabaseLogin; |
| import org.eclipse.persistence.sessions.DatabaseSession; |
| import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl; |
| import org.eclipse.persistence.sessions.server.ServerSession; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| |
| import org.eclipse.persistence.testing.framework.TestProblemException; |
| |
| // Intended usage: |
| // 1.1 Obtains a session from the TestExecutor, logs it out, and keeps; |
| // 1.2 Using the original session's login and the passed parameters |
| // creates session that uses externalConnectionPools; |
| // 1.3 Logs the new session into TestExecutor so that it could be used by tests. |
| // 2.1 After done with the new session - kill it, shutdown all the data sources created for it; |
| // 2.2 Login the original session and set it back into TestExecutor. |
| //// Example: to create a new DatabaseSession that use externalConnectionPooling: |
| // SessionExchange exchange = new SessionExchange(); |
| // testExecutor.setSession(exchange.createDatabaseSession((DatabaseSession)testExecutor.getSession()), true); |
| //// after the testing with the new session is completed: |
| // testExecutor.setSession(exchange.returnOriginalSession()); |
| |
| public class SessionExchanger { |
| // indicates whether the original session should be disconnected |
| public boolean shouldLogoutOriginalSession = true; |
| // indicates whether the new session should be connected |
| public boolean shouldLoginNewSession = true; |
| |
| DatabaseSession originalSession; |
| DatabaseSession newSession; |
| boolean hasLoggedOutOriginalSession; |
| PoolDataSource dataSource; |
| |
| // pass the original session and params for the new one: |
| // useDatabaseSession - "true" means new session is DatabaseSession; "false" - ServerSession; |
| // useExternalConnectionPooling - indicates whether the new session use external connection pooling or not. |
| // returns the new session |
| public DatabaseSession createNewSession(DatabaseSession originalSession, boolean useDatabaseSession, boolean useExternalConnectionPooling) { |
| return createNewSession(originalSession, useDatabaseSession, useExternalConnectionPooling, null, null); |
| } |
| |
| // additional property parameters: |
| // loginProperties - if not null set into the new session's login; |
| // propertyProperties - if not null set into the new session; |
| // returns the new session |
| public DatabaseSession createNewSession(DatabaseSession originalSession, boolean useDatabaseSession, boolean useExternalConnectionPooling, Properties loginProperties, Map sessionProperties) { |
| if(useExternalConnectionPooling) { |
| return createNewSession(originalSession, useDatabaseSession, useExternalConnectionPooling, loginProperties, sessionProperties, -1, -1, -1, -1); |
| } else { |
| return createNewSession(originalSession, useDatabaseSession, useExternalConnectionPooling, loginProperties, sessionProperties, 2, 2, 2, 2); |
| } |
| } |
| |
| // additional min / max parameters used only in case of ServerSession: |
| // in external pooling case only minWriteConnection and maxWriteConnection used - they determine the min / max number of connections in the created data source, |
| // pass -1 value for minWriteConnection and/or maxWriteConnection if no min and/or max number of connections should be set in the data source. |
| // in internal pooling case the min / max values used for write and read connection pools. |
| // returns the new session |
| public DatabaseSession createNewSession(DatabaseSession originalSession, boolean useDatabaseSession, boolean useExternalConnectionPooling, Properties loginProperties, Map sessionProperties, |
| int minWriteConnections, int maxWriteConnections, int minReadConnections, int maxReadConnections) |
| { |
| setup(originalSession); |
| DatabaseLogin login = cloneAndSetDataSource(originalSession.getLogin(), useExternalConnectionPooling, minWriteConnections, maxWriteConnections); |
| if(useDatabaseSession) { |
| newSession = new DatabaseSessionImpl(login); |
| } else { |
| if(useExternalConnectionPooling) { |
| newSession = new ServerSession(login); |
| } else { |
| newSession = new ServerSession(login, minWriteConnections, minWriteConnections); |
| } |
| if(!useExternalConnectionPooling) { |
| ServerSession ss = (ServerSession)newSession; |
| if(ss.getReadConnectionPool().getMaxNumberOfConnections() != maxReadConnections) { |
| ss.getReadConnectionPool().setMaxNumberOfConnections(maxReadConnections); |
| } |
| if(ss.getReadConnectionPool().getMinNumberOfConnections() != minReadConnections) { |
| ss.getReadConnectionPool().setMinNumberOfConnections(minReadConnections); |
| } |
| } |
| } |
| setProperties(loginProperties, sessionProperties); |
| newSession.setSessionLog(originalSession.getSessionLog()); |
| newSession.setLogLevel(originalSession.getLogLevel()); |
| if(shouldLoginNewSession) { |
| newSession.login(); |
| } |
| return newSession; |
| } |
| |
| // disconnects the temporary session, closes its datasource (if any); |
| // in case the original session was disconnected in setup - reconnects it; |
| // returns the original session |
| public DatabaseSession returnOriginalSession() { |
| try { |
| clearNewSession(); |
| return originalSession; |
| } finally { |
| try { |
| if(originalSession != null && hasLoggedOutOriginalSession) { |
| hasLoggedOutOriginalSession = false; |
| originalSession.login(); |
| } |
| } finally { |
| originalSession = null; |
| } |
| } |
| } |
| |
| public boolean isBusy() { |
| return newSession != null; |
| } |
| |
| void setup(DatabaseSession originalSession) { |
| if(isBusy()) { |
| throw new TestProblemException("SessionExchanger: new session has been already created"); |
| } |
| this.originalSession = originalSession; |
| if(shouldLogoutOriginalSession) { |
| if(originalSession.isConnected()) { |
| originalSession.logout(); |
| hasLoggedOutOriginalSession = true; |
| } |
| } |
| } |
| |
| void clearNewSession() { |
| try { |
| if(newSession != null) { |
| if(newSession.isConnected()) { |
| newSession.logout(); |
| } |
| } |
| } finally { |
| newSession = null; |
| if(dataSource != null) { |
| dataSource = null; |
| } |
| } |
| } |
| |
| DatabaseLogin cloneAndSetDataSource(DatabaseLogin login, boolean useExternalConnectionPooling, int minConnections, int maxConnections) { |
| DatabaseLogin cloneLogin = (DatabaseLogin)login.clone(); |
| if(useExternalConnectionPooling) { |
| createDataSource(login.getConnectionString(), minConnections, maxConnections); |
| cloneLogin.setConnector(new JNDIConnector(dataSource)); |
| cloneLogin.setUsesExternalConnectionPooling(true); |
| } |
| return cloneLogin; |
| } |
| |
| void setProperties(Properties loginProperties, Map sessionProperties) { |
| if(loginProperties != null) { |
| newSession.getLogin().setProperties(loginProperties); |
| } |
| if(sessionProperties != null) { |
| ((AbstractSession)newSession).setProperties(sessionProperties); |
| } |
| } |
| |
| // create a data source using the supplied connection string |
| void createDataSource(String connectionString, int minConnections, int maxConnections) { |
| try { |
| dataSource = PoolDataSourceFactory.getPoolDataSource(); |
| dataSource.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); |
| Properties props = new Properties(); |
| if(minConnections >= 0) { |
| dataSource.setMinPoolSize(minConnections); |
| dataSource.setInitialPoolSize(minConnections); |
| } |
| if(maxConnections >= 0) { |
| dataSource.setMaxPoolSize(maxConnections); |
| } |
| dataSource.setURL(connectionString); |
| } catch (SQLException ex) { |
| throw new TestProblemException("Failed to create OracleDataSource with " + connectionString + ".\n", ex); |
| } |
| } |
| } |