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.camel; 018 019 import java.util.HashMap; 020 import java.util.Map; 021 022 import org.apache.camel.impl.ServiceSupport; 023 import org.apache.camel.util.ObjectHelper; 024 import org.apache.camel.util.ProducerCache; 025 026 /** 027 * A client helper object (named like Spring's TransactionTemplate & JmsTemplate 028 * et al) for working with Camel and sending {@link Message} instances in an 029 * {@link Exchange} to an {@link Endpoint}. 030 * 031 * @version $Revision: 40987 $ 032 */ 033 public class CamelTemplate<E extends Exchange> extends ServiceSupport implements ProducerTemplate<E> { 034 private CamelContext context; 035 private ProducerCache<E> producerCache = new ProducerCache<E>(); 036 private boolean useEndpointCache = true; 037 private Map<String, Endpoint<E>> endpointCache = new HashMap<String, Endpoint<E>>(); 038 private Endpoint<E> defaultEndpoint; 039 040 public CamelTemplate(CamelContext context) { 041 this.context = context; 042 } 043 044 public CamelTemplate(CamelContext context, Endpoint defaultEndpoint) { 045 this(context); 046 this.defaultEndpoint = defaultEndpoint; 047 } 048 049 /** 050 * Sends the exchange to the given endpoint 051 * 052 * @param endpointUri the endpoint URI to send the exchange to 053 * @param exchange the exchange to send 054 */ 055 public E send(String endpointUri, E exchange) { 056 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 057 return send(endpoint, exchange); 058 } 059 060 /** 061 * Sends an exchange to an endpoint using a supplied 062 * 063 * @param endpointUri the endpoint URI to send the exchange to 064 * @param processor the transformer used to populate the new exchange 065 * {@link Processor} to populate the exchange 066 */ 067 public E send(String endpointUri, Processor processor) { 068 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 069 return send(endpoint, processor); 070 } 071 072 /** 073 * Sends an exchange to an endpoint using a supplied 074 * 075 * @param endpointUri the endpoint URI to send the exchange to 076 * @param processor the transformer used to populate the new exchange 077 * {@link Processor} to populate the exchange. The callback 078 * will be called when the exchange is completed. 079 */ 080 public E send(String endpointUri, Processor processor, AsyncCallback callback) { 081 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 082 return send(endpoint, processor, callback); 083 } 084 085 /** 086 * Sends an exchange to an endpoint using a supplied 087 * 088 * @param endpointUri the endpoint URI to send the exchange to 089 * @param pattern the message {@link ExchangePattern} such as 090 * {@link ExchangePattern#InOnly} or {@link ExchangePattern#InOut} 091 * @param processor the transformer used to populate the new exchange 092 * {@link Processor} to populate the exchange 093 */ 094 public E send(String endpointUri, ExchangePattern pattern, Processor processor) { 095 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 096 return send(endpoint, pattern, processor); 097 } 098 099 /** 100 * Sends the exchange to the given endpoint 101 * 102 * @param endpoint the endpoint to send the exchange to 103 * @param exchange the exchange to send 104 */ 105 public E send(Endpoint<E> endpoint, E exchange) { 106 //E convertedExchange = endpoint.createExchange(exchange); 107 E convertedExchange = exchange; 108 producerCache.send(endpoint, convertedExchange); 109 return convertedExchange; 110 } 111 112 /** 113 * Sends an exchange to an endpoint using a supplied 114 * 115 * @param endpoint the endpoint to send the exchange to 116 * @param processor the transformer used to populate the new exchange 117 * {@link Processor} to populate the exchange 118 */ 119 public E send(Endpoint<E> endpoint, Processor processor) { 120 return producerCache.send(endpoint, processor); 121 } 122 123 /** 124 * Sends an exchange to an endpoint using a supplied 125 * 126 * @param endpoint the endpoint to send the exchange to 127 * @param processor the transformer used to populate the new exchange 128 * {@link Processor} to populate the exchange. The callback 129 * will be called when the exchange is completed. 130 */ 131 public E send(Endpoint<E> endpoint, Processor processor, AsyncCallback callback) { 132 return producerCache.send(endpoint, processor, callback); 133 } 134 135 /** 136 * Sends an exchange to an endpoint using a supplied 137 * 138 * @param endpoint the endpoint to send the exchange to 139 * @param pattern the message {@link ExchangePattern} such as 140 * {@link ExchangePattern#InOnly} or {@link ExchangePattern#InOut} 141 * @param processor the transformer used to populate the new exchange 142 * {@link Processor} to populate the exchange 143 */ 144 public E send(Endpoint<E> endpoint, ExchangePattern pattern, Processor processor) { 145 return producerCache.send(endpoint, pattern, processor); 146 } 147 148 /** 149 * Send the body to an endpoint with the given {@link ExchangePattern} 150 * returning any result output body 151 * 152 * @param endpoint 153 * @param body = the payload 154 * @param pattern the message {@link ExchangePattern} such as 155 * {@link ExchangePattern#InOnly} or {@link ExchangePattern#InOut} 156 * @return the result 157 */ 158 public Object sendBody(Endpoint<E> endpoint, ExchangePattern pattern, Object body) { 159 E result = send(endpoint, pattern, createSetBodyProcessor(body)); 160 return extractResultBody(result); 161 } 162 163 /** 164 * Send the body to an endpoint returning any result output body 165 * 166 * @param endpoint 167 * @param body = the payload 168 * @return the result 169 */ 170 public Object sendBody(Endpoint<E> endpoint, Object body) { 171 E result = send(endpoint, createSetBodyProcessor(body)); 172 return extractResultBody(result); 173 } 174 175 /** 176 * Send the body to an endpoint 177 * 178 * @param endpointUri 179 * @param body = the payload 180 * @return the result 181 */ 182 public Object sendBody(String endpointUri, Object body) { 183 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 184 return sendBody(endpoint, body); 185 } 186 187 /** 188 * Send the body to an endpoint 189 * 190 * @param endpointUri 191 * @param pattern the message {@link ExchangePattern} such as 192 * {@link ExchangePattern#InOnly} or {@link ExchangePattern#InOut} 193 * @param body = the payload 194 * @return the result 195 */ 196 public Object sendBody(String endpointUri, ExchangePattern pattern, Object body) { 197 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 198 return sendBody(endpoint, pattern, body); 199 } 200 201 /** 202 * Sends the body to an endpoint with a specified header and header value 203 * 204 * @param endpointUri the endpoint URI to send to 205 * @param body the payload send 206 * @param header the header name 207 * @param headerValue the header value 208 * @return the result 209 */ 210 public Object sendBodyAndHeader(String endpointUri, final Object body, final String header, 211 final Object headerValue) { 212 return sendBodyAndHeader(resolveMandatoryEndpoint(endpointUri), body, header, headerValue); 213 } 214 215 /** 216 * Sends the body to an endpoint with a specified header and header value 217 * 218 * @param endpoint the Endpoint to send to 219 * @param body the payload send 220 * @param header the header name 221 * @param headerValue the header value 222 * @return the result 223 */ 224 public Object sendBodyAndHeader(Endpoint endpoint, final Object body, final String header, 225 final Object headerValue) { 226 E result = send(endpoint, createBodyAndHeaderProcessor(body, header, headerValue)); 227 return extractResultBody(result); 228 } 229 230 /** 231 * Sends the body to an endpoint with a specified header and header value 232 * 233 * @param endpoint the Endpoint to send to 234 * @param pattern the message {@link ExchangePattern} such as 235 * {@link ExchangePattern#InOnly} or {@link ExchangePattern#InOut} 236 * @param body the payload send 237 * @param header the header name 238 * @param headerValue the header value 239 * @return the result 240 */ 241 public Object sendBodyAndHeader(Endpoint endpoint, ExchangePattern pattern, final Object body, final String header, 242 final Object headerValue) { 243 E result = send(endpoint, pattern, createBodyAndHeaderProcessor(body, header, headerValue)); 244 return extractResultBody(result); 245 } 246 247 /** 248 * Sends the body to an endpoint with a specified header and header value 249 * 250 * @param endpoint the Endpoint URI to send to 251 * @param pattern the message {@link ExchangePattern} such as 252 * {@link ExchangePattern#InOnly} or {@link ExchangePattern#InOut} 253 * @param body the payload send 254 * @param header the header name 255 * @param headerValue the header value 256 * @return the result 257 */ 258 public Object sendBodyAndHeader(String endpoint, ExchangePattern pattern, final Object body, final String header, 259 final Object headerValue) { 260 E result = send(endpoint, pattern, createBodyAndHeaderProcessor(body, header, headerValue)); 261 return extractResultBody(result); 262 } 263 264 /** 265 * Sends the body to an endpoint with the specified headers and header 266 * values 267 * 268 * @param endpointUri the endpoint URI to send to 269 * @param body the payload send 270 * @return the result 271 */ 272 public Object sendBodyAndHeaders(String endpointUri, final Object body, final Map<String, Object> headers) { 273 return sendBodyAndHeaders(resolveMandatoryEndpoint(endpointUri), body, headers); 274 } 275 276 /** 277 * Sends the body to an endpoint with the specified headers and header 278 * values 279 * 280 * @param endpoint the endpoint URI to send to 281 * @param body the payload send 282 * @return the result 283 */ 284 public Object sendBodyAndHeaders(Endpoint endpoint, final Object body, final Map<String, Object> headers) { 285 E result = send(endpoint, new Processor() { 286 public void process(Exchange exchange) { 287 Message in = exchange.getIn(); 288 for (Map.Entry<String, Object> header : headers.entrySet()) { 289 in.setHeader(header.getKey(), header.getValue()); 290 } 291 in.setBody(body); 292 } 293 }); 294 return extractResultBody(result); 295 } 296 297 // Methods using an InOut ExchangePattern 298 // ----------------------------------------------------------------------- 299 300 /** 301 * Send the body to an endpoint returning any result output body 302 * 303 * @param endpoint 304 * @param processor the processor which will populate the exchange before sending 305 * @return the result 306 */ 307 public E request(Endpoint<E> endpoint, Processor processor) { 308 return send(endpoint, ExchangePattern.InOut, processor); 309 } 310 311 /** 312 * Send the body to an endpoint returning any result output body 313 * 314 * @param endpoint 315 * @param body = the payload 316 * @return the result 317 */ 318 public Object requestBody(Endpoint<E> endpoint, Object body) { 319 return sendBody(endpoint, ExchangePattern.InOut, body); 320 } 321 322 /** 323 * Send the body to an endpoint returning any result output body 324 * 325 * @param endpoint 326 * @param body = the payload 327 * @param header 328 * @param headerValue 329 * @return the result 330 */ 331 public Object requestBodyAndHeader(Endpoint<E> endpoint, Object body, String header, Object headerValue) { 332 return sendBodyAndHeader(endpoint, ExchangePattern.InOut, body, header, headerValue); 333 } 334 335 /** 336 * Send the body to an endpoint returning any result output body 337 * 338 * @param endpoint 339 * @param processor the processor which will populate the exchange before sending 340 * @return the result 341 */ 342 public E request(String endpoint, Processor processor) { 343 return send(endpoint, ExchangePattern.InOut, processor); 344 } 345 346 /** 347 * Send the body to an endpoint returning any result output body 348 * 349 * @param endpoint 350 * @param body = the payload 351 * @return the result 352 */ 353 public Object requestBody(String endpoint, Object body) { 354 return sendBody(endpoint, ExchangePattern.InOut, body); 355 } 356 357 /** 358 * Send the body to an endpoint returning any result output body 359 * 360 * @param endpoint 361 * @param body = the payload 362 * @param header 363 * @param headerValue 364 * @return the result 365 */ 366 public Object requestBodyAndHeader(String endpoint, Object body, String header, Object headerValue) { 367 return sendBodyAndHeader(endpoint, ExchangePattern.InOut, body, header, headerValue); 368 } 369 370 // Methods using the default endpoint 371 // ----------------------------------------------------------------------- 372 373 /** 374 * Sends the body to the default endpoint and returns the result content 375 * 376 * @param body the body to send 377 * @return the returned message body 378 */ 379 public Object sendBody(Object body) { 380 return sendBody(getMandatoryDefaultEndpoint(), body); 381 } 382 383 /** 384 * Sends the exchange to the default endpoint 385 * 386 * @param exchange the exchange to send 387 */ 388 public E send(E exchange) { 389 return send(getMandatoryDefaultEndpoint(), exchange); 390 } 391 392 /** 393 * Sends an exchange to the default endpoint using a supplied 394 * 395 * @param processor the transformer used to populate the new exchange 396 * {@link Processor} to populate the exchange 397 */ 398 public E send(Processor processor) { 399 return send(getMandatoryDefaultEndpoint(), processor); 400 } 401 402 public Object sendBodyAndHeader(Object body, String header, Object headerValue) { 403 return sendBodyAndHeader(getMandatoryDefaultEndpoint(), body, header, headerValue); 404 } 405 406 public Object sendBodyAndHeaders(Object body, Map<String, Object> headers) { 407 return sendBodyAndHeaders(getMandatoryDefaultEndpoint(), body, headers); 408 } 409 410 // Properties 411 // ----------------------------------------------------------------------- 412 public Producer<E> getProducer(Endpoint<E> endpoint) { 413 return producerCache.getProducer(endpoint); 414 } 415 416 public CamelContext getContext() { 417 return context; 418 } 419 420 public Endpoint<E> getDefaultEndpoint() { 421 return defaultEndpoint; 422 } 423 424 public void setDefaultEndpoint(Endpoint<E> defaultEndpoint) { 425 this.defaultEndpoint = defaultEndpoint; 426 } 427 428 /** 429 * Sets the default endpoint to use if none is specified 430 */ 431 public void setDefaultEndpointUri(String endpointUri) { 432 setDefaultEndpoint(getContext().getEndpoint(endpointUri)); 433 } 434 435 public boolean isUseEndpointCache() { 436 return useEndpointCache; 437 } 438 439 public void setUseEndpointCache(boolean useEndpointCache) { 440 this.useEndpointCache = useEndpointCache; 441 } 442 443 public <T extends Endpoint<?>> T getResolvedEndpoint(String endpointUri, Class<T> expectedClass) { 444 Endpoint<?> e = null; 445 synchronized (endpointCache) { 446 e = endpointCache.get(endpointUri); 447 } 448 if (e != null && expectedClass.isAssignableFrom(e.getClass())) { 449 return expectedClass.asSubclass(expectedClass).cast(e); 450 } 451 return null; 452 } 453 454 // Implementation methods 455 // ----------------------------------------------------------------------- 456 457 protected Processor createBodyAndHeaderProcessor(final Object body, final String header, final Object headerValue) { 458 return new Processor() { 459 public void process(Exchange exchange) { 460 Message in = exchange.getIn(); 461 in.setHeader(header, headerValue); 462 in.setBody(body); 463 } 464 }; 465 } 466 467 protected Processor createSetBodyProcessor(final Object body) { 468 return new Processor() { 469 public void process(Exchange exchange) { 470 Message in = exchange.getIn(); 471 in.setBody(body); 472 } 473 }; 474 } 475 476 protected Endpoint resolveMandatoryEndpoint(String endpointUri) { 477 Endpoint endpoint = null; 478 479 if (isUseEndpointCache()) { 480 synchronized (endpointCache) { 481 endpoint = endpointCache.get(endpointUri); 482 if (endpoint == null) { 483 endpoint = context.getEndpoint(endpointUri); 484 if (endpoint != null) { 485 endpointCache.put(endpointUri, endpoint); 486 } 487 } 488 } 489 } else { 490 endpoint = context.getEndpoint(endpointUri); 491 } 492 if (endpoint == null) { 493 throw new NoSuchEndpointException(endpointUri); 494 } 495 return endpoint; 496 } 497 498 protected Endpoint<E> getMandatoryDefaultEndpoint() { 499 Endpoint<E> answer = getDefaultEndpoint(); 500 ObjectHelper.notNull(answer, "defaultEndpoint"); 501 return answer; 502 } 503 504 protected void doStart() throws Exception { 505 producerCache.start(); 506 } 507 508 protected void doStop() throws Exception { 509 producerCache.stop(); 510 } 511 512 protected Object extractResultBody(E result) { 513 Object answer = null; 514 if (result != null) { 515 Message out = result.getOut(false); 516 if (out != null) { 517 answer = out.getBody(); 518 } else { 519 answer = result.getIn().getBody(); 520 } 521 } 522 return answer; 523 } 524 }