001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.camel;
018
019 import java.util.ArrayList;
020 import java.util.Collection;
021 import java.util.List;
022
023 import javax.jbi.management.DeploymentException;
024
025 import org.apache.camel.Endpoint;
026 import org.apache.camel.component.bean.BeanComponent;
027 import org.apache.camel.spring.SpringCamelContext;
028 import org.apache.servicemix.common.ServiceUnit;
029 import org.apache.servicemix.common.xbean.AbstractXBeanDeployer;
030 import org.apache.xbean.kernel.Kernel;
031 import org.apache.xbean.server.spring.loader.PureSpringLoader;
032 import org.apache.xbean.server.spring.loader.SpringLoader;
033 import org.apache.xbean.spring.context.FileSystemXmlApplicationContext;
034 import org.springframework.context.ApplicationContext;
035 import org.springframework.context.support.AbstractXmlApplicationContext;
036 import org.springframework.context.support.GenericApplicationContext;
037
038 /**
039 * A deployer of the spring XML file
040 *
041 * @version $Revision: 1.1 $
042 */
043 public class CamelSpringDeployer extends AbstractXBeanDeployer {
044 private final CamelJbiComponent component;
045
046 private PureSpringLoader springLoader = new PureSpringLoader() {
047 @Override
048 protected AbstractXmlApplicationContext createXmlApplicationContext(String configLocation) {
049 ApplicationContext parentAppContext = createParentApplicationContext(getXmlPreprocessors());
050 return new FileSystemXmlApplicationContext(new String[] {configLocation}, false,
051 parentAppContext, getXmlPreprocessors());
052 }
053 };
054
055 private List<CamelProviderEndpoint> activatedEndpoints = new ArrayList<CamelProviderEndpoint>();
056
057 private String serviceUnitName;
058
059 public CamelSpringDeployer(CamelJbiComponent component) {
060 super(component);
061 this.component = component;
062 }
063
064 @Override
065 protected String getXBeanFile() {
066 return "camel-context";
067 }
068
069 public void undeploy(ServiceUnit su) throws DeploymentException {
070 // Remove the jbiComponent form CamelJbiComponent
071 component.removeJbiComponent(su.getName());
072 super.undeploy(su);
073 }
074
075 /*
076 * (non-Javadoc)
077 *
078 * @see org.apache.servicemix.common.Deployer#deploy(java.lang.String,
079 * java.lang.String)
080 */
081 @Override
082 public ServiceUnit deploy(String suName, String serviceUnitRootPath) throws DeploymentException {
083 // lets register the deployer so that any endpoints activated are added
084 // to this SU
085 component.deployer = this;
086
087 this.serviceUnitName = suName;
088
089 // lets install the context class loader
090 ServiceUnit serviceUnit = super.deploy(suName, serviceUnitRootPath);
091 // Thread.currentThread().setContextClassLoader(serviceUnit.getConfigurationClassLoader());
092 return serviceUnit;
093 }
094
095 public void addService(CamelProviderEndpoint endpoint) {
096 activatedEndpoints.add(endpoint);
097 }
098
099 @Override
100 protected List getServices(Kernel kernel) {
101 try {
102 List<org.apache.servicemix.common.Endpoint> services =
103 new ArrayList<org.apache.servicemix.common.Endpoint>(activatedEndpoints);
104 activatedEndpoints.clear();
105
106 ApplicationContext applicationContext = springLoader.getApplicationContext();
107 SpringCamelContext camelContext = SpringCamelContext.springCamelContext(applicationContext);
108
109 JbiComponent jbiComponent = camelContext.getComponent("jbi", JbiComponent.class);
110 // now lets iterate through all the endpoints
111 Collection<Endpoint> endpoints = camelContext.getSingletonEndpoints();
112
113 if (jbiComponent != null) {
114 // set the SU Name
115 jbiComponent.setSuName(serviceUnitName);
116 for (Endpoint endpoint : endpoints) {
117 if (component.isEndpointExposedOnNmr(endpoint)) {
118 services.add(jbiComponent.createJbiEndpointFromCamel(endpoint));
119 }
120 }
121 // lets add a control bus endpoint to ensure we have at least
122 // one endpoint to deploy
123 BeanComponent beanComponent = camelContext.getComponent("bean", BeanComponent.class);
124 Endpoint endpoint = beanComponent.createEndpoint(new CamelControlBus(camelContext),
125 "camel:" + serviceUnitName + "-controlBus");
126 services.add(jbiComponent.createJbiEndpointFromCamel(endpoint));
127 }
128 return services;
129 } catch (Exception e) {
130 throw new RuntimeException(e);
131 }
132 }
133
134 @Override
135 protected SpringLoader createSpringLoader() {
136 return springLoader;
137 }
138
139 /**
140 * Returns the parent application context which can be used to auto-wire any
141 * JBI based components using the jbi prefix
142 */
143 protected ApplicationContext createParentApplicationContext(List xmlProcessors) {
144 GenericApplicationContext answer = new GenericApplicationContext();
145 answer.getBeanFactory().registerSingleton("servicemix-camel", component);
146 answer.getBeanFactory().registerSingleton("jbi", new JbiComponent(component));
147 answer.setClassLoader(Thread.currentThread().getContextClassLoader());
148 answer.start();
149 answer.refresh();
150 return answer;
151 }
152
153 }