001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
003 * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
004 * to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
005 * License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
010 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011 * specific language governing permissions and limitations under the License.
012 */
013 package org.apache.camel.component.jbi;
014
015 import org.apache.camel.CamelContext;
016 import org.apache.camel.Component;
017 import org.apache.camel.Endpoint;
018 import org.apache.camel.Exchange;
019 import org.apache.camel.FailedToCreateProducerException;
020 import org.apache.camel.Processor;
021 import org.apache.servicemix.common.BaseServiceUnitManager;
022 import org.apache.servicemix.common.DefaultComponent;
023 import org.apache.servicemix.common.Deployer;
024 import org.apache.servicemix.id.IdGenerator;
025 import org.apache.servicemix.jbi.resolver.URIResolver;
026 import org.apache.servicemix.jbi.util.IntrospectionSupport;
027 import org.apache.servicemix.jbi.util.URISupport;
028
029 import javax.jbi.servicedesc.ServiceEndpoint;
030 import javax.xml.namespace.QName;
031 import java.net.URI;
032 import java.net.URISyntaxException;
033 import java.util.ArrayList;
034 import java.util.List;
035 import java.util.Map;
036 import java.util.concurrent.ScheduledExecutorService;
037 import java.util.concurrent.ScheduledThreadPoolExecutor;
038
039 /**
040 * Deploys the camel endpoints within JBI
041 *
042 * @version $Revision: 426415 $
043 */
044 public class CamelJbiComponent extends DefaultComponent implements Component<Exchange> {
045 private JbiBinding binding;
046 private CamelContext camelContext;
047 private ScheduledExecutorService executorService;
048 private IdGenerator idGenerator;
049 protected CamelSpringDeployer deployer;
050
051 /* (non-Javadoc)
052 * @see org.servicemix.common.BaseComponent#createServiceUnitManager()
053 */
054 public BaseServiceUnitManager createServiceUnitManager() {
055 Deployer[] deployers = new Deployer[]{new CamelSpringDeployer(this)};
056 return new BaseServiceUnitManager(this, deployers);
057 }
058
059 /**
060 * @return List of endpoints
061 * @see org.apache.servicemix.common.DefaultComponent#getConfiguredEndpoints()
062 */
063 @Override
064 protected List<CamelJbiEndpoint> getConfiguredEndpoints() {
065 List<CamelJbiEndpoint> answer = new ArrayList<CamelJbiEndpoint>();
066 return answer;
067 }
068
069 /**
070 * @return Class[]
071 * @see org.apache.servicemix.common.DefaultComponent#getEndpointClasses()
072 */
073 @Override
074 protected Class[] getEndpointClasses() {
075 return new Class[]{CamelJbiEndpoint.class};
076 }
077
078 /**
079 * @return the binding
080 */
081 public JbiBinding getBinding() {
082 if (binding == null) {
083 binding = new JbiBinding();
084 }
085 return binding;
086 }
087
088 /**
089 * @param binding the binding to set
090 */
091 public void setBinding(JbiBinding binding) {
092 this.binding = binding;
093 }
094
095 @Override
096 protected String[] getEPRProtocols() {
097 return new String[]{"camel"};
098 }
099
100 protected org.apache.servicemix.common.Endpoint getResolvedEPR(ServiceEndpoint ep) throws Exception {
101 CamelJbiEndpoint endpoint = createEndpoint(ep);
102 endpoint.activate();
103 return endpoint;
104 }
105
106 public CamelJbiEndpoint createEndpoint(ServiceEndpoint ep) throws URISyntaxException {
107 URI uri = new URI(ep.getEndpointName());
108 Map map = URISupport.parseQuery(uri.getQuery());
109 String camelUri = uri.getSchemeSpecificPart();
110 Endpoint camelEndpoint = getCamelContext().getEndpoint(camelUri);
111 Processor processor = createCamelProcessor(camelEndpoint);
112 CamelJbiEndpoint endpoint = new CamelJbiEndpoint(getServiceUnit(), camelEndpoint, getBinding(), processor);
113
114 IntrospectionSupport.setProperties(endpoint, map);
115
116 // TODO
117 //endpoint.setRole(MessageExchange.Role.PROVIDER);
118
119 return endpoint;
120 }
121
122 // Resolve Camel Endpoints
123 //-------------------------------------------------------------------------
124 public Endpoint<Exchange> createEndpoint(String uri) {
125 if (uri.startsWith("jbi:")) {
126 uri = uri.substring("jbi:".length());
127 return new JbiEndpoint(this, uri);
128 }
129 return null;
130 }
131
132 public CamelContext getCamelContext() {
133 return camelContext;
134 }
135
136 public void setCamelContext(CamelContext camelContext) {
137 this.camelContext = camelContext;
138 }
139
140 public ScheduledExecutorService getExecutorService() {
141 if (executorService == null) {
142 executorService = new ScheduledThreadPoolExecutor(5);
143 }
144 return executorService;
145 }
146
147 /**
148 * Activating a JBI endpoint created by a camel consumer.
149 *
150 * @returns a JBI endpoint created for the given Camel endpoint
151 */
152 public CamelJbiEndpoint activateJbiEndpoint(Endpoint camelEndpoint, Processor processor) throws Exception {
153 CamelJbiEndpoint jbiEndpoint = createJbiEndpointFromCamel(camelEndpoint, processor);
154
155 // the following method will activate the new dynamic JBI endpoint
156 if (deployer != null) {
157 // lets add this to the current service unit being deployed
158 deployer.addService(jbiEndpoint);
159 }
160 else {
161 addEndpoint(jbiEndpoint);
162 }
163 return jbiEndpoint;
164 }
165
166 public void deactivateJbiEndpoint(CamelJbiEndpoint jbiEndpoint) throws Exception {
167 // this will be done by the ServiceUnit
168 //jbiEndpoint.deactivate();
169 }
170
171 protected CamelJbiEndpoint createJbiEndpointFromCamel(Endpoint camelEndpoint, Processor processor) {
172 CamelJbiEndpoint jbiEndpoint;
173 String endpointUri = camelEndpoint.getEndpointUri();
174 if (camelEndpoint instanceof JbiEndpoint) {
175 QName service = null;
176 String endpoint = null;
177 if (endpointUri.startsWith("name:")) {
178 endpoint = endpointUri.substring("name:".length());
179 service = CamelJbiEndpoint.SERVICE_NAME;
180 }
181 else if (endpointUri.startsWith("endpoint:")) {
182 String uri = endpointUri.substring("endpoint:".length());
183 // lets decode "serviceNamespace sep serviceName sep endpointName
184 String[] parts;
185 try {
186 parts = URIResolver.split3(uri);
187 }
188 catch (IllegalArgumentException e) {
189 throw new IllegalArgumentException("Expected syntax jbi:endpoint:[serviceNamespace][sep][serviceName][sep][endpointName] where sep = '/' or ':' depending on the serviceNamespace, but was given: " + endpointUri + ". Cause: " + e, e);
190 }
191 service = new QName(parts[0], parts[1]);
192 endpoint = parts[2];
193 }
194 else if (endpointUri.startsWith("service:")) {
195 String uri = endpointUri.substring("service:".length());
196 // lets decode "serviceNamespace sep serviceName
197 String[] parts;
198 try {
199 parts = URIResolver.split2(uri);
200 }
201 catch (IllegalArgumentException e) {
202 throw new IllegalArgumentException("Expected syntax jbi:endpoint:[serviceNamespace][sep][serviceName] where sep = '/' or ':' depending on the serviceNamespace, but was given: " + endpointUri + ". Cause: " + e, e);
203 }
204 service = new QName(parts[0], parts[1]);
205 endpoint = createEndpointName();
206 }
207 else {
208 throw new IllegalArgumentException("Expected syntax jbi:endpoint:[serviceNamespace][sep][serviceName][sep][endpointName] or jbi:service:[serviceNamespace][sep][serviceName or jbi:name:[endpointName] but was given: " + endpointUri);
209 }
210 jbiEndpoint = new CamelJbiEndpoint(getServiceUnit(), service, endpoint, camelEndpoint, getBinding(), processor);
211 }
212 else {
213 jbiEndpoint = new CamelJbiEndpoint(getServiceUnit(), camelEndpoint, getBinding(), processor);
214 }
215 return jbiEndpoint;
216 }
217
218 protected String createEndpointName() {
219 if (idGenerator == null) {
220 idGenerator = new IdGenerator("camel");
221 }
222 return idGenerator.generateSanitizedId();
223 }
224
225 /**
226 * Returns a JBI endpoint created for the given Camel endpoint
227 */
228 public CamelJbiEndpoint createJbiEndpointFromCamel(Endpoint camelEndpoint) {
229 Processor processor = createCamelProcessor(camelEndpoint);
230 return createJbiEndpointFromCamel(camelEndpoint, processor);
231 }
232
233 protected Processor createCamelProcessor(Endpoint camelEndpoint) {
234 Processor processor = null;
235 try {
236 processor = camelEndpoint.createProducer();
237 }
238 catch (Exception e) {
239 throw new FailedToCreateProducerException(camelEndpoint, e);
240 }
241 return processor;
242 }
243
244 /**
245 * Should we expose the Camel JBI onto the NMR.
246 * <p/>
247 * We may wish to add some policy stuff etc.
248 *
249 * @param endpoint the camel endpoint
250 * @return true if the endpoint should be exposed in the NMR
251 */
252 public boolean isEndpointExposedOnNmr(Endpoint endpoint) {
253 // TODO we should only expose consuming endpoints
254 return !(endpoint instanceof JbiEndpoint);
255 }
256 }