/** * Copyright (c) 2009, WSO2 Inc. (http://www.wso2.org) 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 * * 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. */ package org.wso2.carbon.mediation.initializer; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNode; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.synapse.Startup; import org.apache.synapse.SynapseException; import org.apache.synapse.config.Entry; import org.apache.synapse.config.SynapseConfigUtils; import org.apache.synapse.config.SynapseConfiguration; import org.apache.synapse.config.xml.MultiXMLConfigurationBuilder; import org.apache.synapse.config.xml.SynapseXMLConfigurationFactory; import org.apache.synapse.config.xml.XMLConfigConstants; import org.apache.synapse.config.xml.XMLConfigurationBuilder; import org.apache.synapse.core.axis2.ProxyService; import org.apache.synapse.endpoints.Endpoint; import org.apache.synapse.eventing.SynapseEventSource; import org.apache.synapse.mediators.base.SequenceMediator; import org.apache.synapse.rest.API; import org.wso2.carbon.mediation.initializer.persistence.registry.*; import org.wso2.carbon.registry.core.session.UserRegistry; import org.wso2.carbon.registry.core.jdbc.utils.Transaction; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import java.io.File; import java.util.Properties; /** * Builds the {@link org.apache.synapse.config.SynapseConfiguration} by using a registry space, * which defaults to <em>/carbon/synapse-config</em></p> * * <p>The configuration element hierarchy has assumed to be; * <ul> * <li>CONFIG_REGISTRY/repository/synapse/sequences</li> * <li>CONFIG_REGISTRY/repository/synapse/endpoints</li> * <li>CONFIG_REGISTRY/repository/synapse/local-entries</li> * <li>CONFIG_REGISTRY/repository/synapse/proxy-services</li> * <li>CONFIG_REGISTRY/repository/synapse/event-sources</li> * <li>CONFIG_REGISTRY/repository/synapse/synapse-startups</li> * <li>CONFIG_REGISTRY/repository/synapse/synapse-registry</li> * </ul> * * The above resource paths corresponds to the relevant elements, and if there is no <em>main</em> * and <em>fault</em> sequences the builder will add a default sequence for those.</p> * * @see org.wso2.carbon.mediation.initializer.ServiceBusConstants.RegistryStore * @see org.wso2.carbon.mediation.initializer.RegistryBasedSynapseConfigSerializer */ public class RegistryBasedSynapseConfigBuilder { Log log = LogFactory.getLog(RegistryBasedSynapseConfigBuilder.class); /** * Holds the registry instance to build the * {@link org.apache.synapse.config.SynapseConfiguration} by looking at the configuration * elements in the <em>/carbon/synapse-config</em> collection. */ private UserRegistry registry; /** QName that will be used to extract the filename from the registry */ private static final QName FILE_NAME_ATTR = new QName(ServiceBusConstants.DEFINITION_FILE_NAME); private String configName; private String synapseXMLLocation; private Properties properties; private boolean failSafeConfigurationLoading; /** * Constructs the builder and sets the registry to be used * * @param registry to be used to retrieve the configuration elements * @param configName configuration name * @param synapseXMLLocation location of the synapse xml * @param properties the properties from the synapse.properties file * @param failSafeConfigurationLoading to load configurations in a fail safe way */ public RegistryBasedSynapseConfigBuilder(UserRegistry registry, String configName, String synapseXMLLocation, Properties properties, boolean failSafeConfigurationLoading) { this.registry = registry; this.configName = configName; this.synapseXMLLocation = synapseXMLLocation; this.properties = properties; this.failSafeConfigurationLoading = failSafeConfigurationLoading; } /** * Builds the {@link org.apache.synapse.config.SynapseConfiguration} from the registry space. * If the <b>synapse registry</b> has been specified and there are no content in the rest * of the config space, this method looks for the registry configured in the synapse-registry * to find a synapse.xml file....</p> * * <p>If non of the above is able to provide the configuration fall back to the default * configuration * * @return configuration constructed from the registry config space */ public SynapseConfiguration getConfiguration() { SynapseConfiguration configuration = SynapseConfigUtils.newConfiguration(); configuration.setDefaultQName(XMLConfigConstants.DEFINITIONS_ELT); // load the configuration from the registry boolean transactionStarted = Transaction.isStarted(); try { if (!transactionStarted) { registry.beginTransaction(); } buildSynapseRegistryFromRegistry(configuration, properties); buildLocalEntriesFromRegistry(configuration, properties); buildEndpointsFromRegistry(configuration, properties); buildSequencesFromRegistry(configuration, properties); buildProxyServicesFromRegistry(configuration, properties); buildTasksFromRegistry(configuration, properties); buildEvenSourcesFromRegistry(configuration, properties); buildExecutorsFromRegistry(configuration, properties); buildAPIsFromRegistry(configuration, properties); buildMessageStoresFromRegistry(configuration, properties); buildMessageProcessorsFromRegistry(configuration, properties); if (!transactionStarted) { registry.commitTransaction(); } } catch (Exception e) { try { if (!transactionStarted) { registry.rollbackTransaction(); } } catch (Exception ex) { throw new SynapseException("Unable to rollback transaction", ex); } throw new SynapseException("Unable to perform registry operation", e); } // if there are no content in the configuration unless for the registry declaration // try to find a synapse.xml file at the root of the declared synapse registry if (configuration.getLocalRegistry().isEmpty() && configuration.getProxyServices().isEmpty() && configuration.getRegistry() != null) { OMNode remoteConfigNode = configuration.getRegistry().lookup("synapse.xml"); try { configuration = XMLConfigurationBuilder.getConfiguration( SynapseConfigUtils.getStreamSource(remoteConfigNode).getInputStream(), properties); } catch (XMLStreamException xse) { throw new SynapseException("Problem loading remote synapse.xml", xse); } } // after all, if there is no sequence named main defined attach a default one if (configuration.getMainSequence() == null) { SynapseConfigUtils.setDefaultMainSequence(configuration); } // after all, if there is no sequence named fault defined attach a default one if (configuration.getFaultSequence() == null) { SynapseConfigUtils.setDefaultFaultSequence(configuration); } return configuration; } private void buildSynapseRegistryFromRegistry(SynapseConfiguration configuration, Properties properties) { SynapseRegistriesRegistryStore synapseRegistryStore = new SynapseRegistriesRegistryStore(registry, configName); OMElement registryElem = synapseRegistryStore.getElement(); if (registryElem != null) { if (log.isDebugEnabled()) { log.debug("Building the synapse registry declaration from the carbon registry"); } SynapseXMLConfigurationFactory.defineRegistry(configuration, registryElem, properties); } else if (log.isDebugEnabled()) { log.debug("No synapse registry is defined in the carbon registry"); } } private void buildSequencesFromRegistry(SynapseConfiguration configuration, Properties properties) { if (log.isDebugEnabled()) { log.debug("Building the sequences from the carbon registry"); } SequenceRegistryStore sequenceStore = new SequenceRegistryStore(registry, configName); for (OMElement sequenceElem : sequenceStore.getElements()) { try { SequenceMediator seq = (SequenceMediator) SynapseXMLConfigurationFactory.defineSequence(configuration, sequenceElem, properties); String fileName = sequenceElem.getAttributeValue(FILE_NAME_ATTR); if (fileName != null) { seq.setFileName(fileName); fileName = synapseXMLLocation + File.separator + MultiXMLConfigurationBuilder.SEQUENCES_DIR + File.separator + fileName; configuration.getArtifactDeploymentStore().addArtifact(fileName, seq.getName()); } } catch (SynapseException e) { handleErrorGracefully("sequence", e); } } } private void buildEndpointsFromRegistry(SynapseConfiguration configuration, Properties properties) { if (log.isDebugEnabled()) { log.debug("Building the endpoints from the carbon registry"); } EndpointRegistryStore endpointStore = new EndpointRegistryStore(registry, configName); for (OMElement endpointElem : endpointStore.getElements()) { try { Endpoint ep = SynapseXMLConfigurationFactory.defineEndpoint( configuration, endpointElem, properties); String fileName = endpointElem.getAttributeValue(FILE_NAME_ATTR); if (fileName != null) { ep.setFileName(fileName); fileName = synapseXMLLocation + File.separator + MultiXMLConfigurationBuilder.ENDPOINTS_DIR + File.separator + fileName; configuration.getArtifactDeploymentStore().addArtifact(fileName, ep.getName()); } } catch (SynapseException e) { handleErrorGracefully("endpoint", e); } } } private void buildLocalEntriesFromRegistry(SynapseConfiguration configuration, Properties properties) { if (log.isDebugEnabled()) { log.debug("Building the local entries from the carbon registry"); } LocalEntryRegistryStore localEntryStore = new LocalEntryRegistryStore(registry, configName); for (OMElement localEntryElem : localEntryStore.getElements()) { try { Entry e = SynapseXMLConfigurationFactory.defineEntry( configuration, localEntryElem, properties); String fileName = localEntryElem.getAttributeValue(FILE_NAME_ATTR); if (fileName != null) { e.setFileName(fileName); fileName = synapseXMLLocation + File.separator + MultiXMLConfigurationBuilder.LOCAL_ENTRY_DIR + File.separator + fileName; configuration.getArtifactDeploymentStore().addArtifact(fileName, e.getKey()); } } catch (SynapseException e) { handleErrorGracefully("local-entry", e); } } } private void buildProxyServicesFromRegistry(SynapseConfiguration configuration, Properties properties) { if (log.isDebugEnabled()) { log.debug("Building the proxy services from the carbon registry"); } ProxyServiceRegistryStore proxyServiceStore = new ProxyServiceRegistryStore(registry, configName); for (OMElement proxyServiceElem : proxyServiceStore.getElements()) { try { ProxyService proxy = SynapseXMLConfigurationFactory.defineProxy( configuration, proxyServiceElem, properties); String fileName = proxyServiceElem.getAttributeValue(FILE_NAME_ATTR); if (fileName != null) { proxy.setFileName(fileName); fileName = synapseXMLLocation + File.separator + MultiXMLConfigurationBuilder.PROXY_SERVICES_DIR + File.separator + fileName; configuration.getArtifactDeploymentStore().addArtifact(fileName, proxy.getName()); } } catch (SynapseException e) { handleErrorGracefully("proxy", e); } } } private void buildTasksFromRegistry(SynapseConfiguration configuration, Properties properties) { if (log.isDebugEnabled()) { log.debug("Building the startup tasks from the carbon registry"); } StartupRegistryStore startupStore = new StartupRegistryStore(registry, configName); for (OMElement startupElem : startupStore.getElements()) { try { Startup st = SynapseXMLConfigurationFactory.defineStartup( configuration, startupElem, properties); String fileName = startupElem.getAttributeValue(FILE_NAME_ATTR); if (fileName != null) { st.setFileName(fileName); fileName = synapseXMLLocation + File.separator + MultiXMLConfigurationBuilder.TASKS_DIR + File.separator + st.getFileName(); configuration.getArtifactDeploymentStore().addArtifact(fileName, st.getName()); } } catch (SynapseException e) { handleErrorGracefully("task", e); } } } private void buildEvenSourcesFromRegistry(SynapseConfiguration configuration, Properties properties) { if (log.isDebugEnabled()) { log.debug("Building the event sources from the carbon registry"); } EventSourceRegistryStore eventSourceStore = new EventSourceRegistryStore(registry, configName); for (OMElement eventSourceElem : eventSourceStore.getElements()) { try { SynapseEventSource ses = SynapseXMLConfigurationFactory.defineEventSource( configuration, eventSourceElem, properties); String fileName = eventSourceElem.getAttributeValue(FILE_NAME_ATTR); if (fileName != null) { ses.setFileName(fileName); fileName = synapseXMLLocation + File.separator + MultiXMLConfigurationBuilder.EVENTS_DIR + File.separator + ses.getFileName(); configuration.getArtifactDeploymentStore().addArtifact(fileName, ses.getName()); } } catch (SynapseException e) { handleErrorGracefully("event source", e); } } } private void buildExecutorsFromRegistry(SynapseConfiguration configuration, Properties properties) { if (log.isDebugEnabled()) { log.debug("Building the executors from the carbon registry"); } ExecutorRegistryStore executorRegistryStore = new ExecutorRegistryStore(registry, configName); for (OMElement executorElem : executorRegistryStore.getElements()) { try { SynapseXMLConfigurationFactory.defineExecutor(configuration, executorElem, properties); } catch (SynapseException e) { handleErrorGracefully("executor", e); } } } private void buildAPIsFromRegistry(SynapseConfiguration configuration, Properties properties) { if (log.isDebugEnabled()) { log.debug("Building the APIs from the carbon registry"); } APIRegistryStore apiStore = new APIRegistryStore(registry, configName); for (OMElement apiElem : apiStore.getElements()) { try { API api = SynapseXMLConfigurationFactory.defineAPI(configuration, apiElem); String fileName = apiElem.getAttributeValue(FILE_NAME_ATTR); if (fileName != null) { api.setFileName(fileName); fileName = synapseXMLLocation + File.separator + MultiXMLConfigurationBuilder.REST_API_DIR + File.separator + fileName; configuration.getArtifactDeploymentStore().addArtifact(fileName, api.getName()); } } catch (SynapseException e) { handleErrorGracefully("API", e); } } } private void buildMessageStoresFromRegistry(SynapseConfiguration configuration, Properties properties) { if (log.isDebugEnabled()) { log.debug("Build the message stores from the carbon registry"); } MessageStoreRegistryStore messageStoreRegistryStore = new MessageStoreRegistryStore(registry, configName); for (OMElement messageStoreElement : messageStoreRegistryStore.getElements()) { try { SynapseXMLConfigurationFactory.defineMessageStore (configuration, messageStoreElement, properties); } catch (SynapseException e) { handleErrorGracefully("messagestore", e); } } } private void buildMessageProcessorsFromRegistry(SynapseConfiguration configuration, Properties properties) { if (log.isDebugEnabled()) { log.debug("Build the message processors from the carbon registry"); } MessageProcessorRegistryStore messageProcessorRegistryStore = new MessageProcessorRegistryStore(registry, configName); for (OMElement messageProcessorElement : messageProcessorRegistryStore.getElements()) { try { SynapseXMLConfigurationFactory.defineMessageProcessor(configuration, messageProcessorElement, properties); } catch (SynapseException e) { handleErrorGracefully("messageprocessor", e); } } } public void handleErrorGracefully(String component, SynapseException e) { if (failSafeConfigurationLoading) { log.warn("Error occurred while loading a " + component + " configuration from the registry.", e); } else { throw e; } } }