/******************************************************************************* * 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.beans.PropertyChangeEvent; import java.beans.PropertyVetoException; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import org.ebayopensource.turmeric.runtime.common.impl.internal.config.MessageProcessorConfigHolder; import com.ebay.kernel.bean.configuration.BeanPropertyInfo; import com.ebay.kernel.bean.configuration.DynamicBeanPropertyCreationException; import com.ebay.kernel.bean.configuration.DynamicConfigBean; import com.ebay.kernel.exception.BaseRuntimeException; import com.ebay.kernel.initialization.InitializationException; public class ClientServiceConfigBeanManager { private static Map<String, ClientServiceInvokerConfigBean> s_invokerConfigBeans = Collections .synchronizedMap(new HashMap<String, ClientServiceInvokerConfigBean>()); private static Map<String, ClientServiceTransportConfigBean> s_transportConfigBeans = Collections .synchronizedMap(new HashMap<String, ClientServiceTransportConfigBean>()); private static Map<String, DynamicConfigBean> s_transportDynaConfigBeans = Collections .synchronizedMap(new HashMap<String, DynamicConfigBean>()); private static Map<String, ClientServicePayloadLogConfigBean> s_payloadLogConfigBeans = Collections .synchronizedMap(new HashMap<String, ClientServicePayloadLogConfigBean>()); public static ClientServiceInvokerConfigBean getInvokerInstance( String adminName, String clientName,String envName) { ClientServiceInvokerConfigBean sBean = null; if (s_invokerConfigBeans == null) { throw new BaseRuntimeException( "ClientServiceInvokerConfigBean is not initialized"); } String svcClientName = adminName + "." + clientName; String lookupName = envName==null ? svcClientName : svcClientName + "." +envName; sBean = s_invokerConfigBeans.get(lookupName); if (sBean == null) { throw new BaseRuntimeException( "ClientServiceInvokerConfigBean is not initialized for " + lookupName); } return sBean; } //for backward compatibilty public static ClientServiceInvokerConfigBean getInvokerInstance( String adminName, String clientName) { return getInvokerInstance(adminName, clientName,null); } public static ClientServiceTransportConfigBean getTransportInstance( String adminName, String clientName, String envName, String transportName) { ClientServiceTransportConfigBean sBean = null; if (s_transportConfigBeans == null || s_transportDynaConfigBeans == null) { throw new BaseRuntimeException( "ClientServiceInvokerConfigBean is not initialized"); } String lookupName = getLookupTransportName(adminName, clientName,envName, transportName); sBean = s_transportConfigBeans.get(lookupName); if (sBean == null) { throw new BaseRuntimeException( "ClientServiceInvokerConfigBean is not initialized"); } return sBean; } //for backward compatibilty public static ClientServiceTransportConfigBean getTransportInstance( String adminName, String clientName, String transportName) { return getTransportInstance(adminName, clientName, null,transportName); } public static ClientServicePayloadLogConfigBean getPayloadLogInstance( String adminName, String clientName,String envName) { ClientServicePayloadLogConfigBean sBean = null; if (s_payloadLogConfigBeans == null) { throw new BaseRuntimeException( "ClientServicePayloadLogConfigBean is not initialized"); } String svcClientName = adminName + "." + clientName; String lookupName = envName==null ? svcClientName : svcClientName + "." +envName; sBean = s_payloadLogConfigBeans.get(lookupName); if (sBean == null) { throw new BaseRuntimeException( "ClientServicePayloadLogConfigBean is not initialized"); } return sBean; } //for backward compatibilty public static ClientServicePayloadLogConfigBean getPayloadLogInstance( String adminName, String clientName) { return getPayloadLogInstance(adminName, clientName,null); } public static void initConfigBean(ClientConfigHolder config) { initInvokerConfigBean(config); initTransportConfigBeans(config); initPayloadLogConfigBean(config); } private static void initInvokerConfigBean(ClientConfigHolder config) { ClientServiceInvokerConfigBean sBean = null; try { String lookupName = getLookupName(config); synchronized (s_invokerConfigBeans) { sBean = s_invokerConfigBeans.get(lookupName); if (sBean == null) { sBean = new ClientServiceInvokerConfigBean(config); ClientServiceInvokerConfigBeanListener listener = new ClientServiceInvokerConfigBeanListener( sBean); sBean.addVetoableChangeListener(listener); sBean.addPropertyChangeListener(listener); s_invokerConfigBeans.put(lookupName, sBean); } } } catch (Throwable e) { throw new InitializationException(e); } } private static void initTransportConfigBeans(ClientConfigHolder config) { ClientServiceTransportConfigBean sBean = null; final MessageProcessorConfigHolder msgProcConfig = config.getMessageProcessorConfig(); try { synchronized (s_transportConfigBeans) { for (Map.Entry<String,String> e : msgProcConfig.getTransportClasses().entrySet()) { String lookupName = getLookupTransportName(config.getAdminName(), config.getClientName(), config.getEnvName(), e.getKey()); sBean = s_transportConfigBeans.get(lookupName); if (sBean == null) { sBean = new ClientServiceTransportConfigBean(config, e.getKey()); ClientServiceTransportConfigBeanListener listener = new ClientServiceTransportConfigBeanListener( sBean); sBean.addVetoableChangeListener(listener); sBean.addPropertyChangeListener(listener); s_transportConfigBeans.put(lookupName, sBean); } } } synchronized (s_transportDynaConfigBeans) { for (String transportName : msgProcConfig.getTransportClasses().keySet()) { DynamicConfigBean dBean = null; dBean = s_transportDynaConfigBeans.get(transportName); if (dBean == null) { dBean = ClientServiceConfigBean.createDynamicConfigBean(config, transportName + ".TransportHeaders"); TransportHeadersConfigBeanListener listener = new TransportHeadersConfigBeanListener(dBean, config.getAdminName(), config.getClientName(), config.getEnvName(), transportName); listener.setNameValueMap(msgProcConfig.getTransportHeaderOptions().get(transportName)); dBean.addVetoableChangeListener(listener); dBean.addPropertyChangeListener(listener); s_transportDynaConfigBeans.put(transportName, dBean); } } } } catch (Throwable e) { throw new InitializationException(e); } } static class TransportHeadersConfigBeanListener extends DynamicConfigBeanListener { protected final String m_transportName; TransportHeadersConfigBeanListener(DynamicConfigBean bean, String adminName, String clientName, String envName, String transportName) { super(bean, adminName, clientName, envName); m_transportName = transportName; } @Override protected Map<String, String> extractMapFromConfig(ClientConfigHolder configHolder) { final Map<String, Map<String, String>> allTransportHeaderOptions = configHolder.getMessageProcessorConfig().getTransportHeaderOptions(); Map<String, String> transportHeaderOptions = allTransportHeaderOptions.get(m_transportName); if (transportHeaderOptions == null) { transportHeaderOptions = new HashMap<String, String>(); allTransportHeaderOptions.put(getAdminName(), transportHeaderOptions); } return transportHeaderOptions; } } private static void initPayloadLogConfigBean(ClientConfigHolder config) { ClientServicePayloadLogConfigBean sBean = null; try { String lookupName = getLookupName(config); synchronized (s_payloadLogConfigBeans) { sBean = s_payloadLogConfigBeans.get(lookupName); if (sBean == null) { sBean = new ClientServicePayloadLogConfigBean(config); ClientServicePayloadLogConfigBeanListener listener = new ClientServicePayloadLogConfigBeanListener( sBean); sBean.addVetoableChangeListener(listener); sBean.addPropertyChangeListener(listener); s_payloadLogConfigBeans.put(lookupName, sBean); } } } catch (Throwable e) { throw new InitializationException(e); } } private static String getLookupName(ClientConfigHolder config) { // lookUp name needs to use environment name as well if holder has it. String lookupName = config.getAdminName() + "." + config.getClientName(); return config.getEnvName() == null ? lookupName : lookupName + "." + config.getEnvName(); } private static String getLookupTransportName(String adminName, String clientName, String envName, String transportName) { String transportLookupName = adminName + "." + clientName; return envName == null ? transportLookupName + "." + transportName : transportLookupName + "." + envName + "." + transportName; } static abstract class DynamicConfigBeanListener extends ClientServiceConfigBeanListener { protected final String m_adminName; protected final String m_clientName; protected final String m_envName; DynamicConfigBeanListener(DynamicConfigBean bean, String adminName, String clientName, String envName) { super(bean); m_adminName = adminName; m_clientName = clientName; m_envName = envName; } @Override protected String getAdminName() { return m_adminName; } @Override public String getClientName() { return m_clientName; } @Override public String getEnvName() { return m_envName; } @Override protected void setValuesForUpdate(PropertyChangeEvent evt) throws Exception { String name = evt.getPropertyName(); if (name == null || name.equals(DynamicConfigBean.EXTERNAL_MUTABLE)) { return; } Object value = evt.getNewValue(); if (!m_dynamicBean.hasProperty(name)) m_dynamicBean.addProperty(name, value); else m_dynamicBean.setPropertyValue(name, value.toString()); } protected void setValuesForVeto(PropertyChangeEvent evt, Map<String, String> nameValueMap) throws PropertyVetoException { try { String name = evt.getPropertyName(); if (name == null || name.equals(DynamicConfigBean.EXTERNAL_MUTABLE)) { return; } Object value = evt.getNewValue(); validateStringValue(evt, name, value); synchronized(nameValueMap) { nameValueMap.put(name, value.toString()); } } catch (Exception e) { throw new PropertyVetoException(e.getMessage(), evt); } } protected void setNameValueMap(Map<String, String> nameValueMap) throws DynamicBeanPropertyCreationException { if (nameValueMap == null) return; Set<String> nameSet = nameValueMap.keySet(); for (String name : nameSet) { if (!m_dynamicBean.hasProperty(name)) { m_dynamicBean.addProperty(name, nameValueMap.get(name)); } } } protected Map<String, String> getNameValueMap() { Map<String, String> map = new LinkedHashMap<String, String>(); for (Iterator iter = m_dynamicBean.getAllPropertyInfos(); iter.hasNext(); ) { BeanPropertyInfo p = (BeanPropertyInfo) iter.next(); if (!DynamicConfigBean.EXTERNAL_MUTABLE.equals(p.getName())) { map.put(p.getName(), (String) p.getPropertyValue(m_dynamicBean)); } } return map; } @Override protected void setValuesForVeto(ClientConfigHolder configHolder, PropertyChangeEvent evt) throws PropertyVetoException { Map<String, String> nameValueMap = extractMapFromConfig(configHolder); setValuesForVeto(evt, nameValueMap); } abstract Map<String, String> extractMapFromConfig(ClientConfigHolder configHolder); } }