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: 642753 $ 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 producerCache.send(endpoint, convertedExchange); 108 return convertedExchange; 109 } 110 111 /** 112 * Sends an exchange to an endpoint using a supplied 113 * 114 * @param endpoint the endpoint to send the exchange to 115 * @param processor the transformer used to populate the new exchange 116 * {@link Processor} to populate the exchange 117 */ 118 public E send(Endpoint<E> endpoint, Processor processor) { 119 return producerCache.send(endpoint, processor); 120 } 121 122 /** 123 * Sends an exchange to an endpoint using a supplied 124 * 125 * @param endpoint the endpoint to send the exchange to 126 * @param processor the transformer used to populate the new exchange 127 * {@link Processor} to populate the exchange. The callback 128 * will be called when the exchange is completed. 129 */ 130 public E send(Endpoint<E> endpoint, Processor processor, AsyncCallback callback) { 131 return producerCache.send(endpoint, processor, callback); 132 } 133 134 /** 135 * Sends an exchange to an endpoint using a supplied 136 * 137 * @param endpoint the endpoint to send the exchange to 138 * @param pattern the message {@link ExchangePattern} such as 139 * {@link ExchangePattern#InOnly} or {@link ExchangePattern#InOut} 140 * @param processor the transformer used to populate the new exchange 141 * {@link Processor} to populate the exchange 142 */ 143 public E send(Endpoint<E> endpoint, ExchangePattern pattern, Processor processor) { 144 return producerCache.send(endpoint, pattern, processor); 145 } 146 147 /** 148 * Send the body to an endpoint with the given {@link ExchangePattern} 149 * returning any result output body 150 * 151 * @param endpoint 152 * @param body = the payload 153 * @param pattern the message {@link ExchangePattern} such as 154 * {@link ExchangePattern#InOnly} or {@link ExchangePattern#InOut} 155 * @return the result 156 */ 157 public Object sendBody(Endpoint<E> endpoint, ExchangePattern pattern, Object body) { 158 E result = send(endpoint, pattern, createSetBodyProcessor(body)); 159 return extractResultBody(result); 160 } 161 162 /** 163 * Send the body to an endpoint returning any result output body 164 * 165 * @param endpoint 166 * @param body = the payload 167 * @return the result 168 */ 169 public Object sendBody(Endpoint<E> endpoint, Object body) { 170 E result = send(endpoint, createSetBodyProcessor(body)); 171 return extractResultBody(result); 172 } 173 174 /** 175 * Send the body to an endpoint 176 * 177 * @param endpointUri 178 * @param body = the payload 179 * @return the result 180 */ 181 public Object sendBody(String endpointUri, Object body) { 182 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 183 return sendBody(endpoint, body); 184 } 185 186 /** 187 * Send the body to an endpoint 188 * 189 * @param endpointUri 190 * @param pattern the message {@link ExchangePattern} such as 191 * {@link ExchangePattern#InOnly} or {@link ExchangePattern#InOut} 192 * @param body = the payload 193 * @return the result 194 */ 195 public Object sendBody(String endpointUri, ExchangePattern pattern, Object body) { 196 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 197 return sendBody(endpoint, pattern, body); 198 } 199 200 /** 201 * Sends the body to an endpoint with a specified header and header value 202 * 203 * @param endpointUri the endpoint URI to send to 204 * @param body the payload send 205 * @param header the header name 206 * @param headerValue the header value 207 * @return the result 208 */ 209 public Object sendBodyAndHeader(String endpointUri, final Object body, final String header, 210 final Object headerValue) { 211 return sendBodyAndHeader(resolveMandatoryEndpoint(endpointUri), body, header, headerValue); 212 } 213 214 /** 215 * Sends the body to an endpoint with a specified header and header value 216 * 217 * @param endpoint the Endpoint to send to 218 * @param body the payload send 219 * @param header the header name 220 * @param headerValue the header value 221 * @return the result 222 */ 223 public Object sendBodyAndHeader(Endpoint endpoint, final Object body, final String header, 224 final Object headerValue) { 225 E result = send(endpoint, createBodyAndHeaderProcessor(body, header, headerValue)); 226 return extractResultBody(result); 227 } 228 229 /** 230 * Sends the body to an endpoint with a specified header and header value 231 * 232 * @param endpoint the Endpoint to send to 233 * @param pattern the message {@link ExchangePattern} such as 234 * {@link ExchangePattern#InOnly} or {@link ExchangePattern#InOut} 235 * @param body the payload send 236 * @param header the header name 237 * @param headerValue the header value 238 * @return the result 239 */ 240 public Object sendBodyAndHeader(Endpoint endpoint, ExchangePattern pattern, final Object body, final String header, 241 final Object headerValue) { 242 E result = send(endpoint, pattern, createBodyAndHeaderProcessor(body, header, headerValue)); 243 return extractResultBody(result); 244 } 245 246 /** 247 * Sends the body to an endpoint with a specified header and header value 248 * 249 * @param endpoint the Endpoint URI to send to 250 * @param pattern the message {@link ExchangePattern} such as 251 * {@link ExchangePattern#InOnly} or {@link ExchangePattern#InOut} 252 * @param body the payload send 253 * @param header the header name 254 * @param headerValue the header value 255 * @return the result 256 */ 257 public Object sendBodyAndHeader(String endpoint, ExchangePattern pattern, final Object body, final String header, 258 final Object headerValue) { 259 E result = send(endpoint, pattern, createBodyAndHeaderProcessor(body, header, headerValue)); 260 return extractResultBody(result); 261 } 262 263 /** 264 * Sends the body to an endpoint with the specified headers and header 265 * values 266 * 267 * @param endpointUri the endpoint URI to send to 268 * @param body the payload send 269 * @return the result 270 */ 271 public Object sendBodyAndHeaders(String endpointUri, final Object body, final Map<String, Object> headers) { 272 return sendBodyAndHeaders(resolveMandatoryEndpoint(endpointUri), body, headers); 273 } 274 275 /** 276 * Sends the body to an endpoint with the specified headers and header 277 * values 278 * 279 * @param endpoint the endpoint URI to send to 280 * @param body the payload send 281 * @return the result 282 */ 283 public Object sendBodyAndHeaders(Endpoint endpoint, final Object body, final Map<String, Object> headers) { 284 E result = send(endpoint, new Processor() { 285 public void process(Exchange exchange) { 286 Message in = exchange.getIn(); 287 for (Map.Entry<String, Object> header : headers.entrySet()) { 288 in.setHeader(header.getKey(), header.getValue()); 289 } 290 in.setBody(body); 291 } 292 }); 293 return extractResultBody(result); 294 } 295 296 // Methods using an InOut ExchangePattern 297 // ----------------------------------------------------------------------- 298 299 /** 300 * Send the body to an endpoint returning any result output body 301 * 302 * @param endpoint 303 * @param processor the processor which will populate the exchange before sending 304 * @return the result 305 */ 306 public E request(Endpoint<E> endpoint, Processor processor) { 307 return send(endpoint, ExchangePattern.InOut, processor); 308 } 309 310 /** 311 * Send the body to an endpoint returning any result output body 312 * 313 * @param endpoint 314 * @param body = the payload 315 * @return the result 316 */ 317 public Object requestBody(Endpoint<E> endpoint, Object body) { 318 return sendBody(endpoint, ExchangePattern.InOut, body); 319 } 320 321 /** 322 * Send the body to an endpoint returning any result output body 323 * 324 * @param endpoint 325 * @param body = the payload 326 * @param header 327 * @param headerValue 328 * @return the result 329 */ 330 public Object requestBodyAndHeader(Endpoint<E> endpoint, Object body, String header, Object headerValue) { 331 return sendBodyAndHeader(endpoint, ExchangePattern.InOut, body, header, headerValue); 332 } 333 334 /** 335 * Send the body to an endpoint returning any result output body 336 * 337 * @param endpoint 338 * @param processor the processor which will populate the exchange before sending 339 * @return the result 340 */ 341 public E request(String endpoint, Processor processor) { 342 return send(endpoint, ExchangePattern.InOut, processor); 343 } 344 345 /** 346 * Send the body to an endpoint returning any result output body 347 * 348 * @param endpoint 349 * @param body = the payload 350 * @return the result 351 */ 352 public Object requestBody(String endpoint, Object body) { 353 return sendBody(endpoint, ExchangePattern.InOut, body); 354 } 355 356 /** 357 * Send the body to an endpoint returning any result output body 358 * 359 * @param endpoint 360 * @param body = the payload 361 * @param header 362 * @param headerValue 363 * @return the result 364 */ 365 public Object requestBodyAndHeader(String endpoint, Object body, String header, Object headerValue) { 366 return sendBodyAndHeader(endpoint, ExchangePattern.InOut, body, header, headerValue); 367 } 368 369 // Methods using the default endpoint 370 // ----------------------------------------------------------------------- 371 372 /** 373 * Sends the body to the default endpoint and returns the result content 374 * 375 * @param body the body to send 376 * @return the returned message body 377 */ 378 public Object sendBody(Object body) { 379 return sendBody(getMandatoryDefaultEndpoint(), body); 380 } 381 382 /** 383 * Sends the exchange to the default endpoint 384 * 385 * @param exchange the exchange to send 386 */ 387 public E send(E exchange) { 388 return send(getMandatoryDefaultEndpoint(), exchange); 389 } 390 391 /** 392 * Sends an exchange to the default endpoint using a supplied 393 * 394 * @param processor the transformer used to populate the new exchange 395 * {@link Processor} to populate the exchange 396 */ 397 public E send(Processor processor) { 398 return send(getMandatoryDefaultEndpoint(), processor); 399 } 400 401 public Object sendBodyAndHeader(Object body, String header, Object headerValue) { 402 return sendBodyAndHeader(getMandatoryDefaultEndpoint(), body, header, headerValue); 403 } 404 405 public Object sendBodyAndHeaders(Object body, Map<String, Object> headers) { 406 return sendBodyAndHeaders(getMandatoryDefaultEndpoint(), body, headers); 407 } 408 409 // Properties 410 // ----------------------------------------------------------------------- 411 public Producer<E> getProducer(Endpoint<E> endpoint) { 412 return producerCache.getProducer(endpoint); 413 } 414 415 public CamelContext getContext() { 416 return context; 417 } 418 419 public Endpoint<E> getDefaultEndpoint() { 420 return defaultEndpoint; 421 } 422 423 public void setDefaultEndpoint(Endpoint<E> defaultEndpoint) { 424 this.defaultEndpoint = defaultEndpoint; 425 } 426 427 /** 428 * Sets the default endpoint to use if none is specified 429 */ 430 public void setDefaultEndpointUri(String endpointUri) { 431 setDefaultEndpoint(getContext().getEndpoint(endpointUri)); 432 } 433 434 public boolean isUseEndpointCache() { 435 return useEndpointCache; 436 } 437 438 public void setUseEndpointCache(boolean useEndpointCache) { 439 this.useEndpointCache = useEndpointCache; 440 } 441 442 // Implementation methods 443 // ----------------------------------------------------------------------- 444 445 protected Processor createBodyAndHeaderProcessor(final Object body, final String header, final Object headerValue) { 446 return new Processor() { 447 public void process(Exchange exchange) { 448 Message in = exchange.getIn(); 449 in.setHeader(header, headerValue); 450 in.setBody(body); 451 } 452 }; 453 } 454 455 protected Processor createSetBodyProcessor(final Object body) { 456 return new Processor() { 457 public void process(Exchange exchange) { 458 Message in = exchange.getIn(); 459 in.setBody(body); 460 } 461 }; 462 } 463 464 protected Endpoint resolveMandatoryEndpoint(String endpointUri) { 465 Endpoint endpoint = null; 466 467 if (isUseEndpointCache()) { 468 synchronized (endpointCache) { 469 endpoint = endpointCache.get(endpointUri); 470 if (endpoint == null) { 471 endpoint = context.getEndpoint(endpointUri); 472 if (endpoint != null) { 473 endpointCache.put(endpointUri, endpoint); 474 } 475 } 476 } 477 } else { 478 endpoint = context.getEndpoint(endpointUri); 479 } 480 if (endpoint == null) { 481 throw new NoSuchEndpointException(endpointUri); 482 } 483 return endpoint; 484 } 485 486 protected Endpoint<E> getMandatoryDefaultEndpoint() { 487 Endpoint<E> answer = getDefaultEndpoint(); 488 ObjectHelper.notNull(answer, "defaultEndpoint"); 489 return answer; 490 } 491 492 protected void doStart() throws Exception { 493 producerCache.start(); 494 } 495 496 protected void doStop() throws Exception { 497 producerCache.stop(); 498 } 499 500 protected Object extractResultBody(E result) { 501 Object answer = null; 502 if (result != null) { 503 Message out = result.getOut(false); 504 if (out != null) { 505 answer = out.getBody(); 506 } else { 507 answer = result.getIn().getBody(); 508 } 509 } 510 return answer; 511 } 512 }