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 }