/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
* Licensed 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
*******************************************************************************/
package org.ebayopensource.turmeric.runtime.sif.impl.internal.config;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import javax.wsdl.Definition;
import javax.xml.namespace.QName;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.ebayopensource.turmeric.common.v1.types.CommonErrorData;
import org.ebayopensource.turmeric.runtime.common.exceptions.ErrorDataFactory;
import org.ebayopensource.turmeric.runtime.common.exceptions.ServiceCreationException;
import org.ebayopensource.turmeric.runtime.common.exceptions.ServiceException;
import org.ebayopensource.turmeric.runtime.common.exceptions.ServiceNotFoundException;
import org.ebayopensource.turmeric.runtime.common.impl.internal.config.ConfigManager;
import org.ebayopensource.turmeric.runtime.common.impl.internal.config.DomParseUtils;
import org.ebayopensource.turmeric.runtime.common.impl.internal.config.GlobalConfigHolder;
import org.ebayopensource.turmeric.runtime.common.impl.internal.config.GlobalConfigMapper;
import org.ebayopensource.turmeric.runtime.common.impl.internal.config.MessageProcessorConfigHolder;
import org.ebayopensource.turmeric.runtime.common.impl.internal.config.MetadataPropertyConfigHolder;
import org.ebayopensource.turmeric.runtime.common.impl.internal.config.TypeMappingConfigHolder;
import org.ebayopensource.turmeric.runtime.common.impl.internal.service.BaseServiceDescFactory;
import org.ebayopensource.turmeric.runtime.common.impl.utils.ParseUtils;
import org.ebayopensource.turmeric.runtime.common.impl.utils.ReflectionUtils;
import org.ebayopensource.turmeric.runtime.common.pipeline.TransportOptions;
import org.ebayopensource.turmeric.runtime.common.service.ServiceId;
import org.ebayopensource.turmeric.runtime.common.types.SOAConstants;
import org.ebayopensource.turmeric.runtime.common.utils.Preconditions;
import org.ebayopensource.turmeric.runtime.common.utils.WsdlHelper;
import org.ebayopensource.turmeric.runtime.errorlibrary.ErrorConstants;
import org.ebayopensource.turmeric.runtime.sif.impl.internal.service.ClientServiceDescFactory;
import org.ebayopensource.turmeric.runtime.sif.impl.transport.http.HTTPSyncAsyncClientTransport;
import org.ebayopensource.turmeric.runtime.sif.service.ClientServiceId;
import com.ebay.kernel.logger.LogLevel;
import com.ebay.kernel.logger.Logger;
public class ClientConfigManager extends ConfigManager {
private static Logger LOGGER = Logger.getInstance( ClientConfigManager.class );
private static final String SYS_PROP_SOA_CLIENT_CONFIG_ROOT = "SOA_CLIENT_CONFIG_ROOT";
private static final String BASE_PATH = "META-INF/soa/client/";
private static final String BASE_PATH2 = "META-INF/soa/common/";
private static final String GLOBAL_FILENAME = "GlobalClientConfig.xml";
private static final String CLIENT_FILENAME = "ClientConfig.xml";
private static final String CLIENT_SCHEMA = "client/ClientConfig.xsd";
private static final String GLOBAL_SCHEMA = "client/GlobalClientConfig.xsd";
private static final String DEFUALT_CLIENT_FILENAME = "DefaultClientConfig.xml";
private static final QName DEFAULT_SERVICE = new QName("", "");
private static ConfigManager s_instance = null;
private static final char FILE_SEPERATOR = '/';
private static final String DEFAULT_BASE_PATH = BASE_PATH + "config/";
private String m_globalClientConfigRoot;
private Element m_globalData = null;
private Element m_groupData = null;
private Map<String, Map<String, ClientConfigHolder>> m_clientData = new HashMap<String, Map<String, ClientConfigHolder>>();
private GlobalConfigHolder m_globalConfig;
private boolean m_configLoaded = false;
private String m_configPath;
private String m_commonPath = BASE_PATH2 + "config/";
private boolean isInTestMode = false;
private Map<String, String> m_clientConfigPaths = new Hashtable<String,String>();
// Cache for Default Client Config
private Map<String, Document> defaultClientConfigTable = new HashMap<String, Document>(5);
private Map<String, Map<String, ClientConfigHolder>> m_defaultClientData = new HashMap<String, Map<String, ClientConfigHolder>>();
private Map<String, String> serviceLocationsFromWsdl = new HashMap<String, String>();
private static String getGlobalConfigPath()
{
return getConfigPath(null);
}
private static String getConfigPath(String clientName)
{
String configPath = DEFAULT_BASE_PATH;
StringBuffer configRootProperty = new StringBuffer(SYS_PROP_SOA_CLIENT_CONFIG_ROOT);
if(clientName != null)
{
configRootProperty.append(".").append(clientName);
}
String configRoot = System.getProperty(configRootProperty.toString());
if (configRoot != null) {
StringBuffer buf = new StringBuffer();
buf.append(configRoot);
if (!buf.toString().endsWith("/")) {
buf.append('/');
}
configPath = buf.toString();
}
return configPath;
}
public static ClientConfigManager getInstance() throws ServiceCreationException {
if (s_instance == null)
s_instance = new ClientConfigManager();
return (ClientConfigManager)s_instance;
}
private ClientConfigManager()
{
m_globalClientConfigRoot = getGlobalConfigPath();
m_configPath = m_globalClientConfigRoot;
}
public ClientConfigHolder getConfig(String serviceAdminName, String clientName)
throws ServiceCreationException, ServiceNotFoundException {
return getConfig(serviceAdminName, clientName, false);
}
public synchronized ClientConfigHolder getConfig(String serviceAdminName, String clientName, boolean rawMode)
throws ServiceCreationException, ServiceNotFoundException {
return getConfig(serviceAdminName, clientName, null, rawMode);
}
public synchronized ClientConfigHolder getConfig(String serviceAdminName, String clientName, String envName,boolean rawMode)
throws ServiceCreationException, ServiceNotFoundException {
return getConfig( serviceAdminName, clientName, envName, rawMode, false);
}
public synchronized ClientConfigHolder getConfig(String serviceAdminName, String clientName, String envName,boolean rawMode, boolean useDefaultClientConfig) throws ServiceCreationException, ServiceNotFoundException {
init();
Map<String, ClientConfigHolder> clientConfigMap = loadConfig(serviceAdminName, clientName,envName, false, rawMode, useDefaultClientConfig);
ClientConfigHolder outData = clientConfigMap.get(serviceAdminName);
if (outData == null) {
outData = clientConfigMap.get(DEFAULT_SERVICE.getLocalPart());
}
if (outData == null) {
throw new ServiceNotFoundException(ErrorDataFactory.createErrorData(ErrorConstants.CFG_NO_SUCH_SERVICE,
ErrorConstants.ERRORDOMAIN, new Object[] {serviceAdminName}));
}
return outData;
}
// TODO: Get the typemapping and construct CCH
public synchronized ClientConfigHolder getConfig(
ClientConfigHolder baseConfig, String serviceAdminName, String clientName,
String envName, QName svcQName,
Definition wsdlDefinition, boolean rawMode)
throws ServiceCreationException, ServiceNotFoundException {
init();
Map<String, ClientConfigHolder> clientConfigMap = loadConfig(
baseConfig, serviceAdminName, clientName, envName, svcQName,
wsdlDefinition, rawMode);
ClientConfigHolder outData = clientConfigMap.get(serviceAdminName);
if (outData == null) {
outData = clientConfigMap.get(DEFAULT_SERVICE.getLocalPart());
}
if (outData == null) {
throw new ServiceNotFoundException(ErrorDataFactory.createErrorData(ErrorConstants.CFG_NO_SUCH_SERVICE,
ErrorConstants.ERRORDOMAIN, new Object[] {serviceAdminName}));
}
return outData;
}
public synchronized Map<String, ClientConfigHolder> loadConfig(
ClientConfigHolder baseConfig, String serviceName, String clientName,
String envName, QName svcQName,
Definition wsdlDefinition, boolean rawMode)
throws ServiceCreationException {
String key = (envName == null) ? clientName : clientName + "."
+ serviceName + "." + envName;
Map<String, ClientConfigHolder> clientConfigMap = m_clientData.get(key);
if (clientConfigMap != null) {
return clientConfigMap;
}
TypeMappingConfigHolder typeMappingsCfg = ClientConfigManager
.getInstance().getTypeMappingConfigWithModifiedNS(
baseConfig.getAdminName(), baseConfig.getServiceQName(), svcQName, wsdlDefinition, rawMode);
clientConfigMap = new HashMap<String, ClientConfigHolder>();
ClientConfigHolder cch = ClientConfigMapper.getConfigFromBaseConfig(
baseConfig, serviceName, clientName, envName, svcQName,
typeMappingsCfg);
applyConfigBeanOverrides(cch);
clientConfigMap.put(serviceName, cch);
m_clientData.put(key, clientConfigMap);
return clientConfigMap;
}
private synchronized TypeMappingConfigHolder getTypeMappingConfigWithModifiedNS(
String adminName, QName oldSvcQName, QName svcQName, Definition wsdlDefinition, boolean rawMode)
throws ServiceCreationException {
return loadTypeMappingDataWithModifiedNS(m_commonPath + adminName
+ "/TypeMappings.xml", oldSvcQName, svcQName, wsdlDefinition, rawMode);
}
/**
* SOA2.4 onwards, Multiple ClientConfig (MCC) feature mandates env. Please see
* @link getConfigForUpdate(String serviceAdminName, String clientName, String envName)
*/
@Deprecated
public synchronized ClientConfigHolder getConfigForUpdate(String serviceAdminName, String clientName) throws ServiceCreationException, ServiceNotFoundException {
ClientConfigHolder outData = getConfig(serviceAdminName, clientName, BaseServiceDescFactory.getClientInstance().isInRawMode(serviceAdminName));
return outData.copy();
}
public synchronized ClientConfigHolder getConfigForUpdate(String serviceAdminName, String clientName, String envName) throws ServiceCreationException, ServiceNotFoundException {
ClientConfigHolder outData = getConfig(serviceAdminName, clientName, envName, BaseServiceDescFactory.getClientInstance().isInRawMode(serviceAdminName));
return outData.copy();
}
// ClientServiceId id = new ClientServiceId(serviceAdminName, clientName);
// This function is called by the bean manager, which must call ClientServiceDescFactory.reloadServiceDesc(id);
public synchronized void updateConfig(String serviceAdminName,
String clientName, ClientConfigHolder holder) {
// put the holder into the hashmap
holder.lockReadOnly();
Map<String, ClientConfigHolder> clientConfig = null;
if (holder.getEnvName() == null)
//key used in such cases is clientName
clientConfig = m_clientData.get(clientName);
else {
//Key would be based on <clientName>.<AdminName>.<envName>
String key = holder.getClientName() + "." + holder.getAdminName()
+ "." + holder.getEnvName();
clientConfig = m_clientData.get(key);
}
clientConfig.put(serviceAdminName, holder);
}
public synchronized GlobalConfigHolder getGlobalConfig() throws ServiceCreationException {
init();
return m_globalConfig;
}
public synchronized GlobalConfigHolder getGlobalConfigForUpdate() throws ServiceCreationException {
init();
if (m_globalConfig == null) {
return null;
}
return m_globalConfig.copy();
}
private synchronized void init() throws ServiceCreationException {
if (m_configLoaded)
return;
String globalFileName = getGlobalBasePath()+ GLOBAL_FILENAME;
loadGlobalData(globalFileName);
m_globalConfig = new GlobalConfigHolder();
GlobalConfigMapper.map(globalFileName, m_globalData, m_globalConfig);
// Get group element but delay looking into it until we see group references present (findGroup).
if (m_globalData != null) {
m_groupData = DomParseUtils.getSingleElement(globalFileName, m_globalData, "client-config-groups");
}
// No pre-initialization even of the default client. Too confusing to pre-init a service that is not
// being created by the service factory.
//loadConfig(SOAConstants.DEFAULT_CLIENT_NAME, true);
m_configLoaded = true;
}
private synchronized Map<String, ClientConfigHolder> loadConfig(String serviceName, String clientName, boolean isOptional,
boolean rawMode) throws ServiceCreationException {
return loadConfig(serviceName, clientName,null, isOptional, rawMode, false);
}
private String getHashKeyforDefaultConfig(String client, String admin, String env) {
if (env == null) {
env = "";
}
return client + "." + admin + "." + env;
}
private synchronized Map<String, ClientConfigHolder> loadConfig(
String serviceName, String clientName, String envName,
boolean isOptional, boolean rawMode, boolean useDefaultClientConfig)
throws ServiceCreationException {
if (clientName == null) {
clientName = SOAConstants.DEFAULT_CLIENT_NAME;
}
//key needs to be unique.
//key= <ClientName>.<AdminName>.<envName> we need to support switching between cc.xml for a service as well as
//calling diff services with same cc.xml
String key = (envName == null) ? clientName : clientName + "." + serviceName + "." + envName;
Map<String, ClientConfigHolder> clientConfigMap = m_clientData.get(key);
if (clientConfigMap != null) {
return clientConfigMap;
}
clientConfigMap = readClientConfigMap(serviceName, clientName, envName, isOptional, rawMode, useDefaultClientConfig);
m_clientData.put(key, clientConfigMap);
return clientConfigMap;
}
public Map<String, ClientConfigHolder> readClientConfigMap
(String serviceName, String clientName, String envName,
boolean isOptional, boolean rawMode, boolean useDefaultClientConfig)
throws ServiceCreationException
{
Map<String, ClientConfigHolder> clientConfigMap = new HashMap<String, ClientConfigHolder>();
String clientConfigFileName = this.getConfigFilePath(getBasePath(clientName), clientName, envName, serviceName);
String clientConfigSchemaName = s_schemaPath + CLIENT_SCHEMA;
String globalFileName = getGlobalBasePath() + GLOBAL_FILENAME;
Document configDoc = null;
String serviceLocation = null;
try{
configDoc = ParseUtils.parseConfig(clientConfigFileName, clientConfigSchemaName, isOptional, "client-config-list", ParseUtils.getSchemaCheckLevel());
}catch(ServiceCreationException servexc) {
try {
// try to load from default now
// need to log this
if (LOGGER.isLogEnabled(LogLevel.WARN)) {
LOGGER.log(LogLevel.WARN, "Unable to load ClientConfig.xml from config root " + clientConfigFileName
+ "(will use default : " + m_configPath + ")");
}
clientConfigFileName = this.getConfigFilePath(m_configPath, clientName, envName, serviceName);
configDoc = ParseUtils.parseConfig(clientConfigFileName, clientConfigSchemaName, isOptional,
"client-config-list", ParseUtils.getSchemaCheckLevel());
} catch (ServiceCreationException sce) {
if (!useDefaultClientConfig) {
throw sce;
}
CommonErrorData errorData = sce.getErrorMessage().getError().get(0);
if (errorData.getErrorId() != 4001) {
throw sce;
}
String hashkey = getHashKeyforDefaultConfig(clientName, serviceName, envName);
Map<String, ClientConfigHolder> defaultClientConfigMap = m_defaultClientData.get(hashkey);
if (defaultClientConfigMap != null) {
return defaultClientConfigMap;
}
configDoc = defaultClientConfigTable.get(envName);
if (configDoc == null) {
if (LOGGER.isLogEnabled(LogLevel.INFO)) {
LOGGER.log(LogLevel.INFO, "Loading DefaultClientConfig.xml from SOAConfig");
}
clientConfigFileName = getZeroClientConfigFilePath(envName);
configDoc = ParseUtils.parseConfig(clientConfigFileName, clientConfigSchemaName, isOptional,
"client-config-list", ParseUtils.getSchemaCheckLevel());
defaultClientConfigTable.put(envName, configDoc);
}
try {
serviceLocation = serviceLocationsFromWsdl.get(serviceName);
if (serviceLocation == null) {
serviceLocation = WsdlHelper.getServiceLocationPathInfo(serviceName);
serviceLocationsFromWsdl.put(serviceName, serviceLocation);
}
} catch (ServiceException e) {
throw new ServiceCreationException(ErrorDataFactory.createErrorData(ErrorConstants.CFG_VALIDATION_ERROR,
ErrorConstants.ERRORDOMAIN, new Object[] {
clientConfigFileName,
"Unable to get service location for default client config in WSDL for : '" + serviceName
+ "'" }));
}
}
}
if (configDoc == null) {
// if still null optional to load it; don't need the return value
return null;
}
Element clientConfigs = configDoc.getDocumentElement();
NodeList nodes = DomParseUtils.getImmediateChildrenByTagName(clientConfigs, "client-config");
MetadataPropertyConfigHolder metaDataHolder = null;
double metaDataVersion = -1d;
if(serviceName != null) {
metaDataHolder = getMetadataPropertyConfigHolder(serviceName);
metaDataVersion = metaDataHolder.getSmpVersion();
}
for (int i = 0; i < nodes.getLength(); i++) {
Element clientConfig = (Element)nodes.item(i);
String adminName;
QName serviceQName = DEFAULT_SERVICE;
// smp_version >= 1.1 implies metaDataHolder has admin name.
if (metaDataVersion >= 1.1d) {
adminName = metaDataHolder.getAdminName();
if (rawMode) {
if(i > 0) {
throwRawModeException(clientConfigFileName);
}
serviceQName = new QName(SOAConstants.DEFAULT_SERVICE_NAMESPACE, metaDataHolder.getServiceName());
}
}
else if (rawMode) {
// There should only be a single client-config when operating in raw mode
if (i > 0) {
throwRawModeException(clientConfigFileName);
}
adminName = serviceName;
serviceQName = new QName(SOAConstants.DEFAULT_SERVICE_NAMESPACE, serviceName);
}
else {
String serviceNameInCC = clientConfig.getAttribute("service-name");
if (serviceNameInCC != null && !serviceNameInCC.isEmpty()) {
serviceQName = DomParseUtils.getQName(clientConfigFileName, serviceNameInCC, SOAConstants.DEFAULT_SERVICE_NAMESPACE, "service-name");
adminName = serviceQName.getLocalPart();
}
else {
adminName = serviceName;
}
metaDataHolder = getMetadataPropertyConfigHolder(adminName);
}
String groupName = clientConfig.getAttribute("group");
Element clientGroup = null;
if (groupName != null && groupName.length() != 0) {
clientGroup = findGroup(clientConfigFileName, groupName);
}
ClientConfigHolder cch = ClientConfigMapper.applyConfigs(adminName, clientName, envName,
clientConfigFileName, globalFileName, clientGroup, clientConfig);
if (useDefaultClientConfig && serviceLocation != null) {
cch.setServiceInterfaceClassName(metaDataHolder.getServiceInterfaceClassName());
cch.setServiceLocation(cch.getServiceLocation() + serviceLocation);
String hashkey = getHashKeyforDefaultConfig(clientName, serviceName, envName);
Map<String, ClientConfigHolder> defaultClientConfigMap = new HashMap<String, ClientConfigHolder>();
defaultClientConfigMap.put(serviceName, cch);
m_defaultClientData.put(hashkey, defaultClientConfigMap);
}
//Process the transports defined in Config and add the default transports
processDefaultTransportsInConfig(cch);
applyConfigBeanOverrides(cch);
TypeMappingConfigHolder typeMappings = loadTypeMappingData(m_commonPath + adminName + "/TypeMappings.xml", rawMode);
cch.setTypeMappings(typeMappings);
cch.setMetaData(metaDataHolder);
if (rawMode) {
// Default config is generic, so we update the holder to use the service name passed by the caller
cch.setServiceQName(serviceQName);
}
cch.lockReadOnly();
if (clientConfigMap.get(adminName) != null) {
throw new ServiceCreationException(ErrorDataFactory.createErrorData(ErrorConstants.CFG_VALIDATION_ERROR,
ErrorConstants.ERRORDOMAIN, new Object[] {clientConfigFileName, "Duplicate definition of service: '" + adminName + "'"}));
}
clientConfigMap.put(adminName, cch);
}
return clientConfigMap;
}
public static String getZeroClientConfigFilePath(String envName) {
StringBuilder zeroConfigFilePath = new StringBuilder();
zeroConfigFilePath.append(DEFAULT_BASE_PATH);
zeroConfigFilePath.append(envName).append(FILE_SEPERATOR).append(DEFUALT_CLIENT_FILENAME);
return zeroConfigFilePath.toString();
}
private void throwRawModeException(String fileName) throws ServiceCreationException {
throw new ServiceCreationException(ErrorDataFactory.createErrorData(ErrorConstants.CFG_VALIDATION_ERROR,
ErrorConstants.ERRORDOMAIN, new Object[] {fileName, "Only a single default client-config section is allowed when operating in Raw Mode"}));
}
private String getConfigFilePath(String configLoc,String clientName,String envName,String serviceName){
StringBuilder ccfilename = new StringBuilder();
ccfilename.append(configLoc).append(clientName).append(FILE_SEPERATOR);
if (envName != null) {
ccfilename.append(envName).append(FILE_SEPERATOR).append(serviceName).append(FILE_SEPERATOR);
}
ccfilename.append(CLIENT_FILENAME);
String clientConfigFileName = ccfilename.toString();
return clientConfigFileName;
}
private void applyConfigBeanOverrides(ClientConfigHolder cch) {
ClientServiceConfigBeanManager.initConfigBean(cch);
}
private Element findGroup(String filename, String groupName) throws ServiceCreationException {
if (m_groupData == null) {
throw new ServiceCreationException(ErrorDataFactory.createErrorData(ErrorConstants.CFG_VALIDATION_ERROR,
ErrorConstants.ERRORDOMAIN, new Object[] {filename, "Group '" + groupName + " 'is referenced but no groups are defined"}));
}
NodeList nodes = DomParseUtils.getImmediateChildrenByTagName(m_groupData, "client-group");
for (int i=0; i < nodes.getLength(); i++) {
Element clientGroup = (Element)nodes.item(i);
String nameAttr = clientGroup.getAttribute("name");
if (nameAttr != null && nameAttr.equals(groupName)) {
return clientGroup;
}
}
throw new ServiceCreationException(ErrorDataFactory.createErrorData(ErrorConstants.CFG_VALIDATION_ERROR,
ErrorConstants.ERRORDOMAIN, new Object[] {filename, "Cannot find group: " + groupName + ", global file=" + getGlobalFilePath()}));
}
/*
* The runtime by default creates HTTP11, HTTP10 transports with default options unless provided
* in the config. Similarly it attempts to create LOCAL transport if possible. Here we take care of
* merging the override options (if any) with provided transport options (if any).
*/
private void processDefaultTransportsInConfig(ClientConfigHolder cch) throws ServiceCreationException {
//
ClassLoader cl = Thread.currentThread().getContextClassLoader();
MessageProcessorConfigHolder processorConfig = cch.getMessageProcessorConfig();
String defTransportName = cch.getPreferredTransport();
TransportOptions transportOverrideOptions = cch.getTransportOverrideOptions();
if (defTransportName == null) {
defTransportName = SOAConstants.TRANSPORT_HTTP_11;
}
Map<String,String> transportClassesCfg = processorConfig.getTransportClasses();
Map<String,TransportOptions> transportOptionsCfg = processorConfig.getTransportOptions();
// make validate config classnames
for (Map.Entry<String,String> e: transportClassesCfg.entrySet()) {
String name = e.getKey();
validateTransportName(name);
String className = e.getValue();
if (className == null) {
throw new ServiceCreationException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_FACTORY_INVALID_TRANSPORT_CONFIG,
ErrorConstants.ERRORDOMAIN, new Object[] { name }));
}
}
// add client transport names before creating transports to allow proper overrides
if (!transportClassesCfg.containsKey(SOAConstants.TRANSPORT_HTTP_10)) {
transportClassesCfg.put(SOAConstants.TRANSPORT_HTTP_10,
HTTPSyncAsyncClientTransport.class.getName());
}
if (!transportClassesCfg.containsKey(SOAConstants.TRANSPORT_HTTP_11)) {
transportClassesCfg.put(SOAConstants.TRANSPORT_HTTP_11,
HTTPSyncAsyncClientTransport.class.getName());
}
if (!transportClassesCfg.containsKey(SOAConstants.TRANSPORT_LOCAL)) {
String className = "org.ebayopensource.turmeric.runtime.spf.impl.transport.local.LocalTransport";
try {
ReflectionUtils.loadClass(className, null, cl);
// only add if the class can be successfully loaded
transportClassesCfg.put(SOAConstants.TRANSPORT_LOCAL, className);
} catch (ServiceException e) {
// ignore, do not add this class by default
} catch (NoClassDefFoundError e) {
// ignore, do not add this class by default
}
}
for (Map.Entry<String,String> e: transportClassesCfg.entrySet()) {
String name = e.getKey();
boolean isUpdated = false;
// get a non-null copy of the options
TransportOptions options = transportOptionsCfg.get(name);
if (options == null) {
options = new TransportOptions();
options.setHttpTransportClassName(e.getValue()); // set the classname
isUpdated = true;
}
if (defTransportName != null && transportOverrideOptions != null && defTransportName.equals(name)) {
options = options.getMergedCopy(transportOverrideOptions);
isUpdated = true;
}
if (name.equals(SOAConstants.TRANSPORT_HTTP_11)) {
options.getProperties().put(SOAConstants.HTTP_VERSION, SOAConstants.TRANSPORT_HTTP_11);
} else if (name.equals(SOAConstants.TRANSPORT_HTTP_10)) {
options.getProperties().put(SOAConstants.HTTP_VERSION, SOAConstants.TRANSPORT_HTTP_10);
}
if (isUpdated)
transportOptionsCfg.put(name, options);
}
}
private void validateTransportName(String name) throws ServiceCreationException {
if (name == null) {
throw new ServiceCreationException(ErrorDataFactory.createErrorData(ErrorConstants.SVC_FACTORY_INVALID_TRANSPORT_NAME,
ErrorConstants.ERRORDOMAIN, new Object[] { "***null***" }));
}
}
private String getGlobalBasePath()
{
if(isInTestMode)
{
return m_configPath;
}
return m_globalClientConfigRoot;
}
private String getBasePath(String clientName){
if(isInTestMode)
{
return m_configPath;
}
String basePath = DEFAULT_BASE_PATH;
if(clientName != null)
{
basePath = m_clientConfigPaths.get(clientName);
if(basePath == null)
{
basePath = getConfigPath(clientName);
m_clientConfigPaths.put(clientName, basePath);
}
}
return basePath;
}
private String getGlobalFilePath() {
URL glabalFileURL = getClassLoader().getResource(getGlobalBasePath() + GLOBAL_FILENAME);
return (glabalFileURL != null ? glabalFileURL.getPath() : " ");
}
private void loadGlobalData(String globalFileName) throws ServiceCreationException {
if (m_globalData != null)
return;
String globalSchemaName = s_schemaPath + GLOBAL_SCHEMA;
Document globalDoc = ParseUtils.parseConfig(globalFileName, globalSchemaName, true, "global-client-config", ParseUtils.getSchemaCheckLevel());
if (globalDoc != null) {
m_globalData = globalDoc.getDocumentElement();
}
}
private synchronized void setConfigPath(String path) {
m_configPath = path;
}
private synchronized void setCommonPath(String path) {
m_commonPath = path;
}
public static ClientConfigManager newInstanceForTestCase() throws ServiceException
{
s_instance = new ClientConfigManager();
return (ClientConfigManager)s_instance;
}
public synchronized void setConfigTestCase(String relativePath, String commonPath, boolean force) throws ServiceException {
String newPath = BASE_PATH + relativePath + "/";
if (!force && m_configPath != null && m_configPath.equals(newPath)) {
LOGGER.log(LogLevel.WARN, "ClientConfigManager TestCase path of \"" + newPath + "\" already set.");
return;
}
m_configLoaded = false;
m_globalConfig = null;
m_clientData = new HashMap<String, Map<String,ClientConfigHolder>>();
m_globalData = null;
m_groupData = null;
isInTestMode = true;
setConfigPath(newPath);
String newPath2 = BASE_PATH2 + commonPath + "/";
setCommonPath(newPath2);
init();
ClientServiceDescFactory.getInstance().resetFactoryForUnitTest();
}
public void setConfigTestCase(String relativePath) throws ServiceException {
setConfigTestCase(relativePath, relativePath);
}
public void setConfigTestCase(String relativePath, boolean force) throws ServiceException {
setConfigTestCase(relativePath, relativePath, force);
}
public void setConfigTestCase(String relativePath, String commonPath) throws ServiceException {
setConfigTestCase(relativePath, commonPath, false);
}
// This returns all known client names, i.e. names of configurations that have either been pre-initialized
// (currently only the configuration "default"), or accessed by a getConfig() call. We expect this
// to be called at system init (e.g. by BaseServiceDescFactory), and only the value "default" will be
// available at that time.
//
// Continued calls to this function after init will return the set of all accessed client names
// (configurations).
//
// Since ClientConfigManager is a singleton per appserver, the registration process is global to the
// appserver. This means that if multiple clients are deployed as multiple wars, each with their own
// config, such configs will have to have unique client names in order to be registered unambiguously
// into the ClientConfigManager.
//
public Collection<String> getAllClientNames() throws ServiceCreationException {
init();
//since m_clientdata also contains adminName and envName in the key hence need to seperate the client keySet
//"." is not a valid character for envName,clientname or AdminName given by user.
Set<String> clientkeySet = new HashSet<String>();
Set<String> keySet = m_clientData.keySet();
for (String currentkey : keySet) {
String clientName = currentkey;
if (currentkey.contains("."))
clientName = currentkey.substring(0,
currentkey.indexOf('.'));
clientkeySet.add(clientName);
}
return Collections.unmodifiableCollection(clientkeySet);
}
public Collection<String> getAllServiceAdminNames(String clientName) throws ServiceCreationException {
return getAllServiceAdminNames(clientName, false);
}
public Collection<String> getAllServiceAdminNames(String clientName, boolean rawMode) throws ServiceCreationException {
Map<String, ClientConfigHolder> clientConfigMap = loadConfig(null, clientName, false, rawMode);
return Collections.unmodifiableCollection(clientConfigMap.keySet());
}
/**
* Returns the Service Meta data Properties
*
* @param adminName
* @return MetadataPropertyConfigHolder a non-null ConfigHolder
* @throws ServiceCreationException
* @throws ServiceException
*/
public MetadataPropertyConfigHolder getMetadataPropertyConfigHolder(String adminName)
throws ServiceCreationException {
Preconditions.checkNotNull(adminName);
StringBuilder fileName = new StringBuilder().append(m_commonPath);
fileName.append(adminName).append("/service_metadata.properties");
return loadMetadataPropertyData(fileName.toString(), getGlobalConfig().getServiceLayerNames());
}
/**
* Creates a new ClientServiceId instance.
*
* @param adminName
* @param clientName
* @param env
* @return
* @throws ServiceCreationException
* @throws ServiceNotFoundException
*/
public static ServiceId createClientServiceId(String adminName, String clientName, String env, boolean rawMode) {
ClientServiceId clientServiceId = null;
boolean configFound = true;
try {
ClientConfigHolder config = ClientConfigManager.getInstance().getConfig(adminName, clientName, env, rawMode);
MetadataPropertyConfigHolder metadata = config.getMetaData();
if (metadata != null) {
String serviceName = metadata.getServiceName();
String version = metadata.getVersion();
String namespace = metadata.getServiceNamespace();
clientServiceId =
new ClientServiceId(adminName, serviceName, version, namespace, clientName, env);
}
} catch (Exception e) {
configFound = false;
}
// Fallback code for backward compatibility. If config is not
// found, the client is prehistoric or it is test case related
if(!configFound) {
clientServiceId = new ClientServiceId(adminName, clientName);
}
return clientServiceId;
}
}