org.eclipse.persistence.platform.database.oracle.OracleJDBC_10_1_0_2ProxyConnectionCustomizer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction b7c997804f
/*
* Copyright (c) 1998, 2018 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.platform.database.oracle;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import oracle.jdbc.OracleConnection;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.databaseaccess.Accessor;
import org.eclipse.persistence.internal.databaseaccess.ConnectionCustomizer;
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.sessions.Session;
/**
* PUBLIC:
* This class allows connection to open proxy session.
*/
public class OracleJDBC_10_1_0_2ProxyConnectionCustomizer extends ConnectionCustomizer {
protected OracleConnection oracleConnection;
protected int proxyType;
protected Properties proxyProperties;
/**
* INTERNAL:
* Should be instantiated only if session.getProperty(PersistenceUnitProperties.ORACLE_PROXY_TYPE) != null.
*/
public OracleJDBC_10_1_0_2ProxyConnectionCustomizer(Accessor accessor, Session session) {
super(accessor, session);
}
/**
* INTERNAL:
* Applies customization to connection.
* Called only if connection is not already customized (isActive()==false).
* The method may throw SQLException wrapped into DatabaseException.
* isActive method called after this method should return true only in case
* the connection was actually customized.
*/
public void customize() {
// Lazily initialize proxy properties - customize method may be never called
// in case of ClientSession using external connection pooling.
if(proxyProperties == null) {
buildProxyProperties();
}
Connection connection = accessor.getConnection();
if(connection instanceof OracleConnection) {
oracleConnection = (OracleConnection)connection;
} else {
connection = session.getServerPlatform().unwrapConnection(connection);
if(connection instanceof OracleConnection) {
oracleConnection = (OracleConnection)connection;
} else {
throw ValidationException.oracleJDBC10_1_0_2ProxyConnectorRequiresOracleConnection();
}
}
try {
clearConnectionCache();
Object[] args = null;
if (this.session.shouldLog(SessionLog.FINEST, SessionLog.CONNECTION)) {
Properties logProperties = proxyProperties;
if(proxyProperties.containsKey(OracleConnection.PROXY_USER_PASSWORD)) {
logProperties = (Properties)proxyProperties.clone();
logProperties.setProperty(OracleConnection.PROXY_USER_PASSWORD, "******");
}
args = new Object[]{ oracleConnection, logProperties };
}
if(oracleConnection.isProxySession()) {
// Unexpectedly oracleConnection already has a proxy session - probably it was not closed when connection was returned back to connection pool.
// That may happen on jta transaction rollback (especially triggered outside of user's thread - such as timeout)
// when beforeCompletion is never issued
// and application server neither closes proxySession nor allows access to connection in afterCompletion.
try {
if (args != null) {
((AbstractSession)this.session).log(SessionLog.FINEST, SessionLog.CONNECTION, "proxy_connection_customizer_already_proxy_session", args);
}
oracleConnection.close(OracleConnection.PROXY_SESSION);
} catch (SQLException exception) {
// Ignore
this.session.getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.CONNECTION, exception);
}
}
oracleConnection.openProxySession(proxyType, proxyProperties);
// 12c driver will default to an autoCommit setting of true on calling openProxySession
oracleConnection.setAutoCommit(false);
if (args != null) {
((AbstractSession)this.session).log(SessionLog.FINEST, SessionLog.CONNECTION, "proxy_connection_customizer_opened_proxy_session", args);
}
} catch (SQLException exception) {
oracleConnection = null;
throw DatabaseException.sqlException(exception);
} catch (NoSuchMethodError noSuchMethodError) {
oracleConnection = null;
throw ValidationException.oracleJDBC10_1_0_2ProxyConnectorRequiresOracleConnectionVersion();
}
}
/**
* INTERNAL:
* Indicated whether the connection is currently customized.
*/
public boolean isActive() {
return oracleConnection != null;
}
/**
* INTERNAL:
* Clears customization from connection.
* Called only if connection is customized (isActive()==true).
* If the method fails due to SQLException it should "eat" it
* (just like DatasourceAccessor.closeConnection method).
* isActive method called after this method should always return false.
*/
public void clear() {
try {
clearConnectionCache();
if (this.session.shouldLog(SessionLog.FINEST, SessionLog.CONNECTION)) {
Properties logProperties = proxyProperties;
if(proxyProperties.containsKey(OracleConnection.PROXY_USER_PASSWORD)) {
logProperties = (Properties)proxyProperties.clone();
logProperties.setProperty(OracleConnection.PROXY_USER_PASSWORD, "******");
}
Object[] args = new Object[]{ oracleConnection, logProperties };
((AbstractSession)this.session).log(SessionLog.FINEST, SessionLog.CONNECTION, "proxy_connection_customizer_closing_proxy_session", args);
}
oracleConnection.close(OracleConnection.PROXY_SESSION);
} catch (SQLException exception) {
// Ignore
this.session.getSessionLog().logThrowable(SessionLog.WARNING, SessionLog.CONNECTION, exception);
} finally {
oracleConnection = null;
}
}
/**
* INTERNAL:
* Normally called only when customizer is in inactive state (isActive()==false)
* and followed by setAccessor call on the clone.
*/
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException exception) {
throw new InternalError("clone not supported");
}
}
/**
* INTERNAL:
* Two customizers considered equal if they produce the sane customization.
*/
public boolean equals(Object obj) {
if(obj instanceof OracleJDBC_10_1_0_2ProxyConnectionCustomizer) {
return equals((OracleJDBC_10_1_0_2ProxyConnectionCustomizer)obj);
} else {
return false;
}
}
/**
* INTERNAL:
* Two customizers considered equal if they produce the sane customization.
*/
public boolean equals(OracleJDBC_10_1_0_2ProxyConnectionCustomizer customizer) {
if(this == customizer) {
return true;
}
if(this.proxyProperties == null) {
buildProxyProperties();
}
if(customizer.proxyProperties == null) {
customizer.buildProxyProperties();
}
return this.proxyType == customizer.proxyType && this.proxyProperties.equals(customizer.proxyProperties);
}
/**
* INTERNAL:
* Precondition: session.getProperty(PersistenceUnitProperties.ORACLE_PROXY_TYPE) != null
*/
protected void buildProxyProperties() {
Object proxyTypeValue = session.getProperty(PersistenceUnitProperties.ORACLE_PROXY_TYPE);
try {
proxyType = ((Integer)session.getPlatform().getConversionManager().convertObject(proxyTypeValue, Integer.class)).intValue();
} catch (ConversionException conversionException) {
throw ValidationException.oracleJDBC10_1_0_2ProxyConnectorRequiresIntProxytype();
}
proxyProperties = new Properties();
if(proxyType == OracleConnection.PROXYTYPE_USER_NAME) {
String proxyUserName = (String)session.getProperty(OracleConnection.PROXY_USER_NAME);
if(proxyUserName != null) {
proxyProperties.setProperty(OracleConnection.PROXY_USER_NAME, proxyUserName);
} else {
ValidationException.expectedProxyPropertyNotFound("OracleConnection.PROXYTYPE_USER_NAME", OracleConnection.PROXY_USER_NAME);
}
} else if(proxyType == OracleConnection.PROXYTYPE_DISTINGUISHED_NAME) {
String distinguishedName = (String)session.getProperty(OracleConnection.PROXY_DISTINGUISHED_NAME);
if(distinguishedName != null) {
proxyProperties.setProperty(OracleConnection.PROXY_DISTINGUISHED_NAME, distinguishedName);
} else {
ValidationException.expectedProxyPropertyNotFound("OracleConnection.PROXYTYPE_DISTINGUISHED_NAME", OracleConnection.PROXY_DISTINGUISHED_NAME);
}
} else if(proxyType == OracleConnection.PROXYTYPE_CERTIFICATE) {
Object certificate = session.getProperty(OracleConnection.PROXY_CERTIFICATE);
if(certificate != null) {
proxyProperties.put(OracleConnection.PROXY_CERTIFICATE, certificate);
} else {
ValidationException.expectedProxyPropertyNotFound("OracleConnection.PROXYTYPE_CERTIFICATE", OracleConnection.PROXY_CERTIFICATE);
}
} else {
ValidationException.unknownProxyType(proxyType, "OracleConnection.PROXYTYPE_USER_NAME", "OracleConnection.PROXYTYPE_DISTINGUISHED_NAME", "OracleConnection.PROXYTYPE_CERTIFICATE");
}
String proxyUserPassword = (String)session.getProperty(OracleConnection.PROXY_USER_PASSWORD);
// set the value if it's not null and not an empty String
if(proxyUserPassword != null && proxyUserPassword.length() > 0) {
proxyProperties.setProperty(OracleConnection.PROXY_USER_PASSWORD, proxyUserPassword);
}
Object proxyRoles = session.getProperty(OracleConnection.PROXY_ROLES);
// set the value if it's not null and not an empty String
if(proxyRoles != null && !((proxyRoles instanceof String) && (((String)proxyRoles).length() == 0))) {
proxyProperties.put(OracleConnection.PROXY_ROLES, proxyRoles);
}
}
/**
* INTERNAL:
* Clears connection's both implicit and explicit caches.
*/
protected void clearConnectionCache() {
this.getSession().getServerPlatform().clearStatementCache(this.getAccessor().getConnection());
((DatabaseAccessor)this.getAccessor()).clearStatementCache((AbstractSession)this.getSession());
}
}