Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.synapse.commons.datasource.JNDIBasedDataSourceRepository Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* To change this template use File | Settings | File Templates.
*/
package org.apache.synapse.commons.datasource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.commons.SynapseCommonsException;
import org.apache.synapse.commons.util.MiscellaneousUtil;
import org.apache.synapse.commons.util.RMIRegistryController;
import org.apache.synapse.securevault.SecurityConstants;
import javax.naming.*;
import javax.sql.DataSource;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
/**
* Keep all DataSources in the JNDI Tree
*/
public class JNDIBasedDataSourceRepository implements DataSourceRepository {
private static Log log = LogFactory.getLog(JNDIBasedDataSourceRepository.class);
private InitialContext initialContext;
private Properties jndiProperties;
private final Map perDataSourceICMap
= new HashMap();
private final List cachedNameList = new ArrayList();
private final List cachedPorts = new ArrayList();
private boolean initialized = false;
public void init(Properties jndiEnv) {
initialized = true;
if (jndiEnv == null || jndiEnv.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("Provided global JNDI environment properties is empty or null.");
}
return;
}
if (isValid(jndiEnv)) {
jndiProperties = createJNDIEnvironment(jndiEnv, null);
initialContext = createInitialContext(jndiProperties);
}
}
/**
* Register a DataSource in the JNDI tree
*
* @see DataSourceRepository#register(DataSourceInformation)
*/
public void register(DataSourceInformation information) {
validateInitialized();
String dataSourceName = information.getDatasourceName();
validateDSName(dataSourceName);
Properties properties = information.getProperties();
InitialContext context = null;
Properties jndiEvn = null;
if (properties == null || properties.isEmpty()) {
if (initialContext != null) {
context = initialContext;
if (log.isDebugEnabled()) {
log.debug("Empty JNDI properties for datasource " + dataSourceName);
log.debug("Using system-wide jndi properties : " + jndiProperties);
}
jndiEvn = jndiProperties;
}
}
if (context == null) {
jndiEvn = createJNDIEnvironment(properties, information.getAlias());
context = createInitialContext(jndiEvn);
if (context == null) {
validateInitialContext(initialContext);
context = initialContext;
if (log.isDebugEnabled()) {
log.debug("Cannot create a name context with provided jndi properties : " +
jndiEvn);
log.debug("Using system-wide JNDI properties : " + jndiProperties);
}
jndiEvn = jndiProperties;
} else {
perDataSourceICMap.put(dataSourceName, context);
}
}
String dsType = information.getType();
String driver = information.getDriver();
String url = information.getUrl();
String user = information.getSecretInformation().getUser();
String password = information.getSecretInformation().getResolvedSecret();
String maxActive = String.valueOf(information.getMaxActive());
String maxIdle = String.valueOf(information.getMaxIdle());
String maxWait = String.valueOf(information.getMaxWait());
//populates context tree
populateContextTree(context, dataSourceName);
if (DataSourceInformation.BASIC_DATA_SOURCE.equals(dsType)) {
Reference ref = new Reference("javax.sql.DataSource",
"org.apache.commons.dbcp.BasicDataSourceFactory", null);
ref.add(new StringRefAddr(DataSourceConstants.PROP_DRIVER_CLS_NAME,
driver));
ref.add(new StringRefAddr(DataSourceConstants.PROP_URL, url));
ref.add(new StringRefAddr(SecurityConstants.PROP_USER_NAME, user));
ref.add(new StringRefAddr(SecurityConstants.PROP_PASSWORD, password));
ref.add(new StringRefAddr(DataSourceConstants.PROP_MAX_ACTIVE, maxActive));
ref.add(new StringRefAddr(DataSourceConstants.PROP_MAX_IDLE, maxIdle));
ref.add(new StringRefAddr(DataSourceConstants.PROP_MAX_WAIT, maxWait));
// set BasicDataSource specific parameters
setBasicDataSourceParameters(ref, information);
//set default jndiProperties for reference
setCommonParameters(ref, information);
try {
if (log.isDebugEnabled()) {
log.debug("Registering a DataSource with name : " +
dataSourceName + " in the JNDI tree with jndiProperties : " + jndiEvn);
}
context.rebind(dataSourceName, ref);
} catch (NamingException e) {
String msg = " Error binding name ' " + dataSourceName + " ' to " +
"the DataSource(BasicDataSource) reference";
throw new SynapseCommonsException(msg, e, log);
}
} else if (DataSourceInformation.PER_USER_POOL_DATA_SOURCE.equals(dsType)) {
// Construct DriverAdapterCPDS reference
String className = (String) information.getParameter(
DataSourceConstants.PROP_CPDS_ADAPTER +
DataSourceConstants.DOT_STRING +
DataSourceConstants.PROP_CPDS_CLASS_NAME);
String factory = (String) information.getParameter(
DataSourceConstants.PROP_CPDS_ADAPTER +
DataSourceConstants.DOT_STRING +
DataSourceConstants.PROP_CPDS_FACTORY);
String name = (String) information.getParameter(
DataSourceConstants.PROP_CPDS_ADAPTER +
DataSourceConstants.DOT_STRING +
DataSourceConstants.PROP_CPDS_NAME);
Reference cpdsRef =
new Reference(className, factory, null);
cpdsRef.add(new StringRefAddr(DataSourceConstants.PROP_DRIVER, driver));
cpdsRef.add(new StringRefAddr(DataSourceConstants.PROP_URL, url));
cpdsRef.add(new StringRefAddr(DataSourceConstants.PROP_USER, user));
cpdsRef.add(new StringRefAddr(SecurityConstants.PROP_PASSWORD,
password));
try {
context.rebind(name, cpdsRef);
} catch (NamingException e) {
String msg = "Error binding name '" + name + "' to " +
"the DriverAdapterCPDS reference";
throw new SynapseCommonsException(msg, e, log);
}
// Construct PerUserPoolDataSource reference
Reference ref =
new Reference("org.apache.commons.dbcp.datasources.PerUserPoolDataSource",
"org.apache.commons.dbcp.datasources.PerUserPoolDataSourceFactory",
null);
ref.add(new BinaryRefAddr(
DataSourceConstants.PROP_JNDI_ENV,
MiscellaneousUtil.serialize(jndiEvn)));
ref.add(new StringRefAddr(
DataSourceConstants.PROP_DATA_SOURCE_NAME, name));
ref.add(new StringRefAddr(
DataSourceConstants.PROP_DEFAULT_MAX_ACTIVE, maxActive));
ref.add(new StringRefAddr(
DataSourceConstants.PROP_DEFAULT_MAX_IDLE, maxIdle));
ref.add(new StringRefAddr(
DataSourceConstants.PROP_DEFAULT_MAX_WAIT, maxWait));
//set default jndiProperties for reference
setCommonParameters(ref, information);
try {
if (log.isDebugEnabled()) {
log.debug("Registering a DataSource with name : " +
dataSourceName + " in the JNDI tree with jndiProperties : " + jndiEvn);
}
context.rebind(dataSourceName, ref);
} catch (NamingException e) {
String msg = "Error binding name ' " + dataSourceName + " ' to " +
"the PerUserPoolDataSource reference";
throw new SynapseCommonsException(msg, e, log);
}
} else {
throw new SynapseCommonsException("Unsupported data source type : " + dsType, log);
}
cachedNameList.add(dataSourceName);
}
public void unRegister(String name) {
InitialContext context = getCachedInitialContext(name);
try {
context.unbind(name);
} catch (NamingException e) {
throw new SynapseCommonsException("Error removing a Datasource with name : " +
name + " from the JNDI context : " + initialContext, e);
}
cachedNameList.remove(name);
}
/**
* Get a DatSource which has been registered in the JNDI tree
*
* @see DataSourceRepository#lookUp(String)
*/
public DataSource lookUp(String dsName) {
validateInitialized();
validateDSName(dsName);
if (!cachedNameList.contains(dsName)) {
if (log.isDebugEnabled()) {
log.debug("There is no Datasource with name " + dsName +
" in JNDI Datasource Repository");
}
return null;
}
if (log.isDebugEnabled()) {
log.debug("Getting a DataSource with name : " + dsName + " from the JNDI tree.");
}
InitialContext context = getCachedInitialContext(dsName);
return DataSourceFinder.find(dsName, context);
}
public void clear() {
initialized = false;
initialContext = null;
jndiProperties.clear();
perDataSourceICMap.clear();
cachedNameList.clear();
for (int port : cachedPorts) {
RMIRegistryController.getInstance().removeLocalRegistry(port);
}
cachedPorts.clear();
}
private InitialContext getCachedInitialContext(String name) {
InitialContext context = perDataSourceICMap.get(name);
if (context == null) {
validateInitialContext(initialContext);
context = initialContext;
}
return context;
}
/**
* Helper method to set all default parameter for naming reference of data source
*
* @param reference The naming reference instance
* @param information DataSourceInformation instance
*/
private static void setCommonParameters(Reference reference, DataSourceInformation information) {
reference.add(new StringRefAddr(DataSourceConstants.PROP_DEFAULT_AUTO_COMMIT,
String.valueOf(information.isDefaultAutoCommit())));
reference.add(new StringRefAddr(DataSourceConstants.PROP_DEFAULT_READ_ONLY,
String.valueOf(information.isDefaultReadOnly())));
reference.add(new StringRefAddr(DataSourceConstants.PROP_TEST_ON_BORROW,
String.valueOf(information.isTestOnBorrow())));
reference.add(new StringRefAddr(DataSourceConstants.PROP_TEST_ON_RETURN,
String.valueOf(information.isTestOnReturn())));
reference.add(new StringRefAddr(
DataSourceConstants.PROP_TIME_BETWEEN_EVICTION_RUNS_MILLIS,
String.valueOf(information.getTimeBetweenEvictionRunsMillis())));
reference.add(new StringRefAddr(
DataSourceConstants.PROP_NUM_TESTS_PER_EVICTION_RUN,
String.valueOf(information.getNumTestsPerEvictionRun())));
reference.add(new StringRefAddr(
DataSourceConstants.PROP_MIN_EVICTABLE_IDLE_TIME_MILLIS,
String.valueOf(information.getMinEvictableIdleTimeMillis())));
reference.add(new StringRefAddr(
DataSourceConstants.PROP_TEST_WHILE_IDLE,
String.valueOf(information.isTestWhileIdle())));
String validationQuery = information.getValidationQuery();
if (validationQuery != null && !"".equals(validationQuery)) {
reference.add(new StringRefAddr(
DataSourceConstants.PROP_VALIDATION_QUERY, validationQuery));
}
}
/**
* Helper method to set all BasicDataSource specific parameter
*
* @param ref The naming reference instance
* @param information DataSourceInformation instance
*/
private static void setBasicDataSourceParameters(Reference ref,
DataSourceInformation information) {
int defaultTransactionIsolation = information.getDefaultTransactionIsolation();
String defaultCatalog = information.getDefaultCatalog();
if (defaultTransactionIsolation != -1) {
ref.add(new StringRefAddr(
DataSourceConstants.PROP_DEFAULT_TRANSACTION_ISOLATION,
String.valueOf(defaultTransactionIsolation)));
}
ref.add(new StringRefAddr(DataSourceConstants.PROP_MIN_IDLE,
String.valueOf(information.getMaxIdle())));
ref.add(new StringRefAddr(
DataSourceConstants.PROP_ACCESS_TO_UNDERLYING_CONNECTION_ALLOWED,
String.valueOf(information.isAccessToUnderlyingConnectionAllowed())));
ref.add(new StringRefAddr(
DataSourceConstants.PROP_REMOVE_ABANDONED,
String.valueOf(information.isRemoveAbandoned())));
ref.add(new StringRefAddr(DataSourceConstants.PROP_REMOVE_ABANDONED_TIMEOUT,
String.valueOf(information.getRemoveAbandonedTimeout())));
ref.add(new StringRefAddr(
DataSourceConstants.PROP_LOG_ABANDONED,
String.valueOf(information.isLogAbandoned())));
ref.add(new StringRefAddr(
DataSourceConstants.PROP_POOL_PREPARED_STATEMENTS,
String.valueOf(information.isPoolPreparedStatements())));
ref.add(new StringRefAddr(DataSourceConstants.PROP_MAX_OPEN_PREPARED_STATEMENTS,
String.valueOf(information.getMaxOpenPreparedStatements())));
ref.add(new StringRefAddr(
DataSourceConstants.PROP_INITIAL_SIZE, String.valueOf(
information.getInitialSize())));
if (defaultCatalog != null && !"".equals(defaultCatalog)) {
ref.add(new StringRefAddr
(DataSourceConstants.PROP_DEFAULT_CATALOG, defaultCatalog));
}
}
/**
* Helper method to create context tree for a given path
*
* @param initialContext The root context
* @param path The path of the resource
*/
private static void populateContextTree(InitialContext initialContext, String path) {
String[] paths = path.split("/");
if (paths != null && paths.length > 1) {
Context context = initialContext;
for (String path1 : paths) {
try {
assert context != null;
context = context.createSubcontext(path1);
if (context == null) {
throw new SynapseCommonsException("sub context " + path1 + " could not" +
" be created", log);
}
} catch (NamingException e) {
throw new SynapseCommonsException("Unable to create sub context : " + path1,
e, log);
}
}
}
}
private Properties createJNDIEnvironment(Properties dsProperties, String name) {
String namingFactory = DataSourceConstants.DEFAULT_IC_FACTORY;
String providerUrl = null;
int port = DataSourceConstants.DEFAULT_PROVIDER_PORT;
String providerPort = null;
// setting naming provider
Properties jndiEvn = new Properties(); //This is needed for PerUserPoolDatasource
if (dsProperties != null && !dsProperties.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("Using properties " + dsProperties + " to create JNDI Environment");
}
StringBuffer buffer = new StringBuffer();
buffer.append(DataSourceConstants.PROP_SYNAPSE_PREFIX_DS);
buffer.append(DataSourceConstants.DOT_STRING);
if (name != null && !"".equals(name)) {
buffer.append(name);
buffer.append(DataSourceConstants.DOT_STRING);
}
// The prefix for root level jndiProperties
String rootPrefix = buffer.toString();
namingFactory = MiscellaneousUtil.getProperty(
dsProperties, rootPrefix + DataSourceConstants.PROP_IC_FACTORY,
DataSourceConstants.DEFAULT_IC_FACTORY);
//Provider URL
providerUrl = MiscellaneousUtil.getProperty(
dsProperties, rootPrefix + DataSourceConstants.PROP_PROVIDER_URL,
null);
providerPort =
MiscellaneousUtil.getProperty(dsProperties, rootPrefix +
DataSourceConstants.PROP_PROVIDER_PORT,
String.valueOf(DataSourceConstants.DEFAULT_PROVIDER_PORT));
}
jndiEvn.put(Context.INITIAL_CONTEXT_FACTORY, namingFactory);
if (providerUrl != null && !"".equals(providerUrl)) {
if (log.isDebugEnabled()) {
log.debug("Using provided initial context provider url :" + providerUrl);
}
} else {
if (log.isDebugEnabled()) {
log.debug("No initial context provider url...creaeting a new one");
}
String providerHost = "localhost";
try {
InetAddress addr = InetAddress.getLocalHost();
if (addr != null) {
String hostname = addr.getHostName();
if (hostname == null) {
String ipAddr = addr.getHostAddress();
if (ipAddr != null) {
providerHost = ipAddr;
}
} else {
providerHost = hostname;
}
}
} catch (UnknownHostException e) {
log.warn("Unable to determine hostname or IP address.. Using localhost", e);
}
// default port for RMI registry
if (providerPort != null) {
try {
port = Integer.parseInt(providerPort);
} catch (NumberFormatException ignored) {
}
}
// Create a RMI local registry
RMIRegistryController.getInstance().createLocalRegistry(port);
cachedPorts.add(port);
providerUrl = "rmi://" + providerHost + ":" + port;
}
jndiEvn.put(Context.PROVIDER_URL, providerUrl);
log.info("DataSources will be registered in the JNDI context with provider PROP_URL : " +
providerUrl);
return jndiEvn;
}
public boolean isInitialized() {
return initialized;
}
private void validateInitialized() {
if (!isInitialized()) {
throw new SynapseCommonsException("Datasource repository has not been initialized " +
"yet", log);
}
}
private void validateDSName(String dataSourceName) {
if (dataSourceName == null || "".equals(dataSourceName)) {
throw new SynapseCommonsException("Invalid DataSource configuration !! -" +
"DataSource Name cannot be found ", log);
}
}
private void validateInitialContext(InitialContext initialContext) {
if (initialContext == null) {
throw new SynapseCommonsException("InitialContext cannot be found.", log);
}
}
private InitialContext createInitialContext(Properties jndiEnv) {
if (jndiEnv == null || jndiEnv.isEmpty()) {
return null;
}
try {
if (log.isDebugEnabled()) {
log.debug("Initiating a Naming context with JNDI " +
"environment jndiProperties : " + jndiEnv);
}
return new InitialContext(jndiEnv);
} catch (NamingException e) {
throw new SynapseCommonsException("Error creating a InitialContext" +
" with JNDI env jndiProperties : " + jndiEnv, log);
}
}
private boolean isValid(Properties dsProperties) {
String dataSources = MiscellaneousUtil.getProperty(dsProperties,
DataSourceConstants.PROP_SYNAPSE_PREFIX_DS, null);
if (dataSources != null && !"".equals(dataSources)) {
String[] dataSourcesNames = dataSources.split(",");
return !(dataSourcesNames == null || dataSourcesNames.length == 0);
}
return false;
}
}