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 */ 017package org.apache.camel.impl; 018 019import java.util.Map; 020import java.util.concurrent.Callable; 021import java.util.concurrent.ExecutorService; 022import java.util.concurrent.Future; 023import java.util.concurrent.TimeUnit; 024import java.util.concurrent.TimeoutException; 025 026import org.apache.camel.CamelContext; 027import org.apache.camel.CamelExecutionException; 028import org.apache.camel.Endpoint; 029import org.apache.camel.Exchange; 030import org.apache.camel.ExchangePattern; 031import org.apache.camel.Message; 032import org.apache.camel.NoSuchEndpointException; 033import org.apache.camel.Processor; 034import org.apache.camel.ProducerTemplate; 035import org.apache.camel.spi.Synchronization; 036import org.apache.camel.support.ServiceSupport; 037import org.apache.camel.util.CamelContextHelper; 038import org.apache.camel.util.ExchangeHelper; 039import org.apache.camel.util.ObjectHelper; 040import org.apache.camel.util.ServiceHelper; 041 042/** 043 * Template (named like Spring's TransactionTemplate & JmsTemplate 044 * et al) for working with Camel and sending {@link Message} instances in an 045 * {@link Exchange} to an {@link Endpoint}. 046 * 047 * @version 048 */ 049public class DefaultProducerTemplate extends ServiceSupport implements ProducerTemplate { 050 private final CamelContext camelContext; 051 private volatile ProducerCache producerCache; 052 private volatile ExecutorService executor; 053 private Endpoint defaultEndpoint; 054 private int maximumCacheSize; 055 private boolean eventNotifierEnabled = true; 056 057 public DefaultProducerTemplate(CamelContext camelContext) { 058 this.camelContext = camelContext; 059 } 060 061 public DefaultProducerTemplate(CamelContext camelContext, ExecutorService executor) { 062 this.camelContext = camelContext; 063 this.executor = executor; 064 } 065 066 public DefaultProducerTemplate(CamelContext camelContext, Endpoint defaultEndpoint) { 067 this(camelContext); 068 this.defaultEndpoint = defaultEndpoint; 069 } 070 071 public static DefaultProducerTemplate newInstance(CamelContext camelContext, String defaultEndpointUri) { 072 Endpoint endpoint = CamelContextHelper.getMandatoryEndpoint(camelContext, defaultEndpointUri); 073 return new DefaultProducerTemplate(camelContext, endpoint); 074 } 075 076 public int getMaximumCacheSize() { 077 return maximumCacheSize; 078 } 079 080 public void setMaximumCacheSize(int maximumCacheSize) { 081 this.maximumCacheSize = maximumCacheSize; 082 } 083 084 public int getCurrentCacheSize() { 085 if (producerCache == null) { 086 return 0; 087 } 088 return producerCache.size(); 089 } 090 091 public boolean isEventNotifierEnabled() { 092 return eventNotifierEnabled; 093 } 094 095 public void setEventNotifierEnabled(boolean eventNotifierEnabled) { 096 this.eventNotifierEnabled = eventNotifierEnabled; 097 // if we already created the cache then adjust its setting as well 098 if (producerCache != null) { 099 producerCache.setEventNotifierEnabled(eventNotifierEnabled); 100 } 101 } 102 103 public Exchange send(String endpointUri, Exchange exchange) { 104 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 105 return send(endpoint, exchange); 106 } 107 108 public Exchange send(String endpointUri, Processor processor) { 109 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 110 return send(endpoint, processor); 111 } 112 113 public Exchange send(String endpointUri, ExchangePattern pattern, Processor processor) { 114 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 115 return send(endpoint, pattern, processor); 116 } 117 118 public Exchange send(Endpoint endpoint, Exchange exchange) { 119 getProducerCache().send(endpoint, exchange); 120 return exchange; 121 } 122 123 public Exchange send(Endpoint endpoint, Processor processor) { 124 return getProducerCache().send(endpoint, processor); 125 } 126 127 public Exchange send(Endpoint endpoint, ExchangePattern pattern, Processor processor) { 128 return getProducerCache().send(endpoint, pattern, processor); 129 } 130 131 public Object sendBody(Endpoint endpoint, ExchangePattern pattern, Object body) { 132 Exchange result = send(endpoint, pattern, createSetBodyProcessor(body)); 133 return extractResultBody(result, pattern); 134 } 135 136 public void sendBody(Endpoint endpoint, Object body) throws CamelExecutionException { 137 Exchange result = send(endpoint, createSetBodyProcessor(body)); 138 // must invoke extract result body in case of exception to be rethrown 139 extractResultBody(result); 140 } 141 142 public void sendBody(String endpointUri, Object body) throws CamelExecutionException { 143 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 144 sendBody(endpoint, body); 145 } 146 147 public Object sendBody(String endpointUri, ExchangePattern pattern, Object body) throws CamelExecutionException { 148 Endpoint endpoint = resolveMandatoryEndpoint(endpointUri); 149 Object result = sendBody(endpoint, pattern, body); 150 if (pattern.isOutCapable()) { 151 return result; 152 } else { 153 // return null if not OUT capable 154 return null; 155 } 156 } 157 158 public void sendBodyAndHeader(String endpointUri, final Object body, final String header, final Object headerValue) throws CamelExecutionException { 159 sendBodyAndHeader(resolveMandatoryEndpoint(endpointUri), body, header, headerValue); 160 } 161 162 public void sendBodyAndHeader(Endpoint endpoint, final Object body, final String header, final Object headerValue) throws CamelExecutionException { 163 Exchange result = send(endpoint, createBodyAndHeaderProcessor(body, header, headerValue)); 164 // must invoke extract result body in case of exception to be rethrown 165 extractResultBody(result); 166 } 167 168 public Object sendBodyAndHeader(Endpoint endpoint, ExchangePattern pattern, final Object body, 169 final String header, final Object headerValue) throws CamelExecutionException { 170 Exchange exchange = send(endpoint, pattern, createBodyAndHeaderProcessor(body, header, headerValue)); 171 Object result = extractResultBody(exchange, pattern); 172 if (pattern.isOutCapable()) { 173 return result; 174 } else { 175 // return null if not OUT capable 176 return null; 177 } 178 } 179 180 public Object sendBodyAndHeader(String endpoint, ExchangePattern pattern, final Object body, 181 final String header, final Object headerValue) throws CamelExecutionException { 182 Exchange exchange = send(endpoint, pattern, createBodyAndHeaderProcessor(body, header, headerValue)); 183 Object result = extractResultBody(exchange, pattern); 184 if (pattern.isOutCapable()) { 185 return result; 186 } else { 187 // return null if not OUT capable 188 return null; 189 } 190 } 191 192 public void sendBodyAndProperty(String endpointUri, final Object body, 193 final String property, final Object propertyValue) throws CamelExecutionException { 194 sendBodyAndProperty(resolveMandatoryEndpoint(endpointUri), body, property, propertyValue); 195 } 196 197 public void sendBodyAndProperty(Endpoint endpoint, final Object body, 198 final String property, final Object propertyValue) throws CamelExecutionException { 199 Exchange result = send(endpoint, createBodyAndPropertyProcessor(body, property, propertyValue)); 200 // must invoke extract result body in case of exception to be rethrown 201 extractResultBody(result); 202 } 203 204 public Object sendBodyAndProperty(Endpoint endpoint, ExchangePattern pattern, final Object body, 205 final String property, final Object propertyValue) throws CamelExecutionException { 206 Exchange exchange = send(endpoint, pattern, createBodyAndPropertyProcessor(body, property, propertyValue)); 207 Object result = extractResultBody(exchange, pattern); 208 if (pattern.isOutCapable()) { 209 return result; 210 } else { 211 // return null if not OUT capable 212 return null; 213 } 214 } 215 216 public Object sendBodyAndProperty(String endpoint, ExchangePattern pattern, final Object body, 217 final String property, final Object propertyValue) throws CamelExecutionException { 218 Exchange exchange = send(endpoint, pattern, createBodyAndPropertyProcessor(body, property, propertyValue)); 219 Object result = extractResultBody(exchange, pattern); 220 if (pattern.isOutCapable()) { 221 return result; 222 } else { 223 // return null if not OUT capable 224 return null; 225 } 226 } 227 228 public void sendBodyAndHeaders(String endpointUri, final Object body, final Map<String, Object> headers) throws CamelExecutionException { 229 sendBodyAndHeaders(resolveMandatoryEndpoint(endpointUri), body, headers); 230 } 231 232 public void sendBodyAndHeaders(Endpoint endpoint, final Object body, final Map<String, Object> headers) throws CamelExecutionException { 233 Exchange result = send(endpoint, new Processor() { 234 public void process(Exchange exchange) { 235 Message in = exchange.getIn(); 236 if (headers != null) { 237 for (Map.Entry<String, Object> header : headers.entrySet()) { 238 in.setHeader(header.getKey(), header.getValue()); 239 } 240 } 241 in.setBody(body); 242 } 243 }); 244 // must invoke extract result body in case of exception to be rethrown 245 extractResultBody(result); 246 } 247 248 public Object sendBodyAndHeaders(String endpointUri, ExchangePattern pattern, Object body, Map<String, Object> headers) throws CamelExecutionException { 249 return sendBodyAndHeaders(resolveMandatoryEndpoint(endpointUri), pattern, body, headers); 250 } 251 252 public Object sendBodyAndHeaders(Endpoint endpoint, ExchangePattern pattern, final Object body, final Map<String, Object> headers) throws CamelExecutionException { 253 Exchange exchange = send(endpoint, pattern, new Processor() { 254 public void process(Exchange exchange) throws Exception { 255 Message in = exchange.getIn(); 256 if (headers != null) { 257 for (Map.Entry<String, Object> header : headers.entrySet()) { 258 in.setHeader(header.getKey(), header.getValue()); 259 } 260 } 261 in.setBody(body); 262 } 263 }); 264 Object result = extractResultBody(exchange, pattern); 265 if (pattern.isOutCapable()) { 266 return result; 267 } else { 268 // return null if not OUT capable 269 return null; 270 } 271 } 272 273 // Methods using an InOut ExchangePattern 274 // ----------------------------------------------------------------------- 275 276 public Exchange request(Endpoint endpoint, Processor processor) { 277 return send(endpoint, ExchangePattern.InOut, processor); 278 } 279 280 public Object requestBody(Object body) throws CamelExecutionException { 281 return sendBody(getMandatoryDefaultEndpoint(), ExchangePattern.InOut, body); 282 } 283 284 public Object requestBody(Endpoint endpoint, Object body) throws CamelExecutionException { 285 return sendBody(endpoint, ExchangePattern.InOut, body); 286 } 287 288 public Object requestBodyAndHeader(Object body, String header, Object headerValue) throws CamelExecutionException { 289 return sendBodyAndHeader(getMandatoryDefaultEndpoint(), ExchangePattern.InOut, body, header, headerValue); 290 } 291 292 public Object requestBodyAndHeader(Endpoint endpoint, Object body, String header, Object headerValue) throws CamelExecutionException { 293 return sendBodyAndHeader(endpoint, ExchangePattern.InOut, body, header, headerValue); 294 } 295 296 public Exchange request(String endpoint, Processor processor) throws CamelExecutionException { 297 return send(endpoint, ExchangePattern.InOut, processor); 298 } 299 300 public Object requestBody(String endpoint, Object body) throws CamelExecutionException { 301 return sendBody(endpoint, ExchangePattern.InOut, body); 302 } 303 304 public Object requestBodyAndHeader(String endpoint, Object body, String header, Object headerValue) throws CamelExecutionException { 305 return sendBodyAndHeader(endpoint, ExchangePattern.InOut, body, header, headerValue); 306 } 307 308 public Object requestBodyAndHeaders(String endpointUri, Object body, Map<String, Object> headers) { 309 return requestBodyAndHeaders(resolveMandatoryEndpoint(endpointUri), body, headers); 310 } 311 312 public Object requestBodyAndHeaders(Endpoint endpoint, final Object body, final Map<String, Object> headers) { 313 return sendBodyAndHeaders(endpoint, ExchangePattern.InOut, body, headers); 314 } 315 316 public Object requestBodyAndHeaders(final Object body, final Map<String, Object> headers) { 317 return sendBodyAndHeaders(getDefaultEndpoint(), ExchangePattern.InOut, body, headers); 318 } 319 320 public <T> T requestBody(Object body, Class<T> type) { 321 Object answer = requestBody(body); 322 return camelContext.getTypeConverter().convertTo(type, answer); 323 } 324 325 public <T> T requestBody(Endpoint endpoint, Object body, Class<T> type) { 326 Object answer = requestBody(endpoint, body); 327 return camelContext.getTypeConverter().convertTo(type, answer); 328 } 329 330 public <T> T requestBody(String endpointUri, Object body, Class<T> type) { 331 Object answer = requestBody(endpointUri, body); 332 return camelContext.getTypeConverter().convertTo(type, answer); 333 } 334 335 public <T> T requestBodyAndHeader(Endpoint endpoint, Object body, String header, Object headerValue, Class<T> type) { 336 Object answer = requestBodyAndHeader(endpoint, body, header, headerValue); 337 return camelContext.getTypeConverter().convertTo(type, answer); 338 } 339 340 public <T> T requestBodyAndHeader(String endpointUri, Object body, String header, Object headerValue, Class<T> type) { 341 Object answer = requestBodyAndHeader(endpointUri, body, header, headerValue); 342 return camelContext.getTypeConverter().convertTo(type, answer); 343 } 344 345 public <T> T requestBodyAndHeaders(String endpointUri, Object body, Map<String, Object> headers, Class<T> type) { 346 Object answer = requestBodyAndHeaders(endpointUri, body, headers); 347 return camelContext.getTypeConverter().convertTo(type, answer); 348 } 349 350 public <T> T requestBodyAndHeaders(Endpoint endpoint, Object body, Map<String, Object> headers, Class<T> type) { 351 Object answer = requestBodyAndHeaders(endpoint, body, headers); 352 return camelContext.getTypeConverter().convertTo(type, answer); 353 } 354 355 // Methods using the default endpoint 356 // ----------------------------------------------------------------------- 357 358 public void sendBody(Object body) { 359 sendBody(getMandatoryDefaultEndpoint(), body); 360 } 361 362 public Exchange send(Exchange exchange) { 363 return send(getMandatoryDefaultEndpoint(), exchange); 364 } 365 366 public Exchange send(Processor processor) { 367 return send(getMandatoryDefaultEndpoint(), processor); 368 } 369 370 public void sendBodyAndHeader(Object body, String header, Object headerValue) { 371 sendBodyAndHeader(getMandatoryDefaultEndpoint(), body, header, headerValue); 372 } 373 374 public void sendBodyAndProperty(Object body, String property, Object propertyValue) { 375 sendBodyAndProperty(getMandatoryDefaultEndpoint(), body, property, propertyValue); 376 } 377 378 public void sendBodyAndHeaders(Object body, Map<String, Object> headers) { 379 sendBodyAndHeaders(getMandatoryDefaultEndpoint(), body, headers); 380 } 381 382 // Properties 383 // ----------------------------------------------------------------------- 384 385 /** 386 * @deprecated use {@link #getCamelContext()} 387 */ 388 @Deprecated 389 public CamelContext getContext() { 390 return getCamelContext(); 391 } 392 393 public CamelContext getCamelContext() { 394 return camelContext; 395 } 396 397 public Endpoint getDefaultEndpoint() { 398 return defaultEndpoint; 399 } 400 401 public void setDefaultEndpoint(Endpoint defaultEndpoint) { 402 this.defaultEndpoint = defaultEndpoint; 403 } 404 405 /** 406 * Sets the default endpoint to use if none is specified 407 */ 408 public void setDefaultEndpointUri(String endpointUri) { 409 setDefaultEndpoint(getCamelContext().getEndpoint(endpointUri)); 410 } 411 412 /** 413 * @deprecated use {@link CamelContext#getEndpoint(String, Class)} 414 */ 415 @Deprecated 416 public <T extends Endpoint> T getResolvedEndpoint(String endpointUri, Class<T> expectedClass) { 417 return camelContext.getEndpoint(endpointUri, expectedClass); 418 } 419 420 // Implementation methods 421 // ----------------------------------------------------------------------- 422 423 protected Processor createBodyAndHeaderProcessor(final Object body, final String header, final Object headerValue) { 424 return new Processor() { 425 public void process(Exchange exchange) { 426 Message in = exchange.getIn(); 427 in.setHeader(header, headerValue); 428 in.setBody(body); 429 } 430 }; 431 } 432 433 protected Processor createBodyAndPropertyProcessor(final Object body, final String property, final Object propertyValue) { 434 return new Processor() { 435 public void process(Exchange exchange) { 436 exchange.setProperty(property, propertyValue); 437 Message in = exchange.getIn(); 438 in.setBody(body); 439 } 440 }; 441 } 442 443 protected Processor createSetBodyProcessor(final Object body) { 444 return new Processor() { 445 public void process(Exchange exchange) { 446 Message in = exchange.getIn(); 447 in.setBody(body); 448 } 449 }; 450 } 451 452 protected Endpoint resolveMandatoryEndpoint(String endpointUri) { 453 Endpoint endpoint = camelContext.getEndpoint(endpointUri); 454 if (endpoint == null) { 455 throw new NoSuchEndpointException(endpointUri); 456 } 457 return endpoint; 458 } 459 460 protected Endpoint getMandatoryDefaultEndpoint() { 461 Endpoint answer = getDefaultEndpoint(); 462 ObjectHelper.notNull(answer, "defaultEndpoint"); 463 return answer; 464 } 465 466 protected Object extractResultBody(Exchange result) { 467 return extractResultBody(result, null); 468 } 469 470 protected Object extractResultBody(Exchange result, ExchangePattern pattern) { 471 return ExchangeHelper.extractResultBody(result, pattern); 472 } 473 474 public void setExecutorService(ExecutorService executorService) { 475 this.executor = executorService; 476 } 477 478 public Future<Exchange> asyncSend(final String uri, final Exchange exchange) { 479 return asyncSend(resolveMandatoryEndpoint(uri), exchange); 480 } 481 482 public Future<Exchange> asyncSend(final String uri, final Processor processor) { 483 return asyncSend(resolveMandatoryEndpoint(uri), processor); 484 } 485 486 public Future<Object> asyncSendBody(final String uri, final Object body) { 487 return asyncSendBody(resolveMandatoryEndpoint(uri), body); 488 } 489 490 public Future<Object> asyncRequestBody(final String uri, final Object body) { 491 return asyncRequestBody(resolveMandatoryEndpoint(uri), body); 492 } 493 494 public <T> Future<T> asyncRequestBody(final String uri, final Object body, final Class<T> type) { 495 return asyncRequestBody(resolveMandatoryEndpoint(uri), body, type); 496 } 497 498 public Future<Object> asyncRequestBodyAndHeader(final String endpointUri, final Object body, final String header, final Object headerValue) { 499 return asyncRequestBodyAndHeader(resolveMandatoryEndpoint(endpointUri), body, header, headerValue); 500 } 501 502 public <T> Future<T> asyncRequestBodyAndHeader(final String endpointUri, final Object body, final String header, final Object headerValue, final Class<T> type) { 503 return asyncRequestBodyAndHeader(resolveMandatoryEndpoint(endpointUri), body, header, headerValue, type); 504 } 505 506 public Future<Object> asyncRequestBodyAndHeaders(final String endpointUri, final Object body, final Map<String, Object> headers) { 507 return asyncRequestBodyAndHeaders(resolveMandatoryEndpoint(endpointUri), body, headers); 508 } 509 510 public <T> Future<T> asyncRequestBodyAndHeaders(final String endpointUri, final Object body, final Map<String, Object> headers, final Class<T> type) { 511 return asyncRequestBodyAndHeaders(resolveMandatoryEndpoint(endpointUri), body, headers, type); 512 } 513 514 public <T> T extractFutureBody(Future<Object> future, Class<T> type) { 515 return ExchangeHelper.extractFutureBody(camelContext, future, type); 516 } 517 518 public <T> T extractFutureBody(Future<Object> future, long timeout, TimeUnit unit, Class<T> type) throws TimeoutException { 519 return ExchangeHelper.extractFutureBody(camelContext, future, timeout, unit, type); 520 } 521 522 public Future<Object> asyncCallbackSendBody(String uri, Object body, Synchronization onCompletion) { 523 return asyncCallbackSendBody(resolveMandatoryEndpoint(uri), body, onCompletion); 524 } 525 526 public Future<Object> asyncCallbackSendBody(Endpoint endpoint, Object body, Synchronization onCompletion) { 527 return asyncCallback(endpoint, ExchangePattern.InOnly, body, onCompletion); 528 } 529 530 public Future<Object> asyncCallbackRequestBody(String uri, Object body, Synchronization onCompletion) { 531 return asyncCallbackRequestBody(resolveMandatoryEndpoint(uri), body, onCompletion); 532 } 533 534 public Future<Object> asyncCallbackRequestBody(Endpoint endpoint, Object body, Synchronization onCompletion) { 535 return asyncCallback(endpoint, ExchangePattern.InOut, body, onCompletion); 536 } 537 538 public Future<Exchange> asyncCallback(String uri, Exchange exchange, Synchronization onCompletion) { 539 return asyncCallback(resolveMandatoryEndpoint(uri), exchange, onCompletion); 540 } 541 542 public Future<Exchange> asyncCallback(String uri, Processor processor, Synchronization onCompletion) { 543 return asyncCallback(resolveMandatoryEndpoint(uri), processor, onCompletion); 544 } 545 546 public Future<Object> asyncRequestBody(final Endpoint endpoint, final Object body) { 547 Callable<Object> task = new Callable<Object>() { 548 public Object call() throws Exception { 549 return requestBody(endpoint, body); 550 } 551 }; 552 return getExecutorService().submit(task); 553 } 554 555 public <T> Future<T> asyncRequestBody(final Endpoint endpoint, final Object body, final Class<T> type) { 556 Callable<T> task = new Callable<T>() { 557 public T call() throws Exception { 558 return requestBody(endpoint, body, type); 559 } 560 }; 561 return getExecutorService().submit(task); 562 } 563 564 public Future<Object> asyncRequestBodyAndHeader(final Endpoint endpoint, final Object body, final String header, 565 final Object headerValue) { 566 Callable<Object> task = new Callable<Object>() { 567 public Object call() throws Exception { 568 return requestBodyAndHeader(endpoint, body, header, headerValue); 569 } 570 }; 571 return getExecutorService().submit(task); 572 } 573 574 public <T> Future<T> asyncRequestBodyAndHeader(final Endpoint endpoint, final Object body, final String header, 575 final Object headerValue, final Class<T> type) { 576 Callable<T> task = new Callable<T>() { 577 public T call() throws Exception { 578 return requestBodyAndHeader(endpoint, body, header, headerValue, type); 579 } 580 }; 581 return getExecutorService().submit(task); 582 } 583 584 public Future<Object> asyncRequestBodyAndHeaders(final Endpoint endpoint, final Object body, 585 final Map<String, Object> headers) { 586 Callable<Object> task = new Callable<Object>() { 587 public Object call() throws Exception { 588 return requestBodyAndHeaders(endpoint, body, headers); 589 } 590 }; 591 return getExecutorService().submit(task); 592 } 593 594 public <T> Future<T> asyncRequestBodyAndHeaders(final Endpoint endpoint, final Object body, 595 final Map<String, Object> headers, final Class<T> type) { 596 Callable<T> task = new Callable<T>() { 597 public T call() throws Exception { 598 return requestBodyAndHeaders(endpoint, body, headers, type); 599 } 600 }; 601 return getExecutorService().submit(task); 602 } 603 604 public Future<Exchange> asyncSend(final Endpoint endpoint, final Exchange exchange) { 605 Callable<Exchange> task = new Callable<Exchange>() { 606 public Exchange call() throws Exception { 607 return send(endpoint, exchange); 608 } 609 }; 610 return getExecutorService().submit(task); 611 } 612 613 public Future<Exchange> asyncSend(final Endpoint endpoint, final Processor processor) { 614 Callable<Exchange> task = new Callable<Exchange>() { 615 public Exchange call() throws Exception { 616 return send(endpoint, processor); 617 } 618 }; 619 return getExecutorService().submit(task); 620 } 621 622 public Future<Object> asyncSendBody(final Endpoint endpoint, final Object body) { 623 Callable<Object> task = new Callable<Object>() { 624 public Object call() throws Exception { 625 sendBody(endpoint, body); 626 // its InOnly, so no body to return 627 return null; 628 } 629 }; 630 return getExecutorService().submit(task); 631 } 632 633 private Future<Object> asyncCallback(final Endpoint endpoint, final ExchangePattern pattern, final Object body, final Synchronization onCompletion) { 634 Callable<Object> task = new Callable<Object>() { 635 public Object call() throws Exception { 636 Exchange answer = send(endpoint, pattern, createSetBodyProcessor(body)); 637 638 // invoke callback before returning answer 639 // as it allows callback to be used without unit of work invoking it 640 // and thus it works directly from a producer template as well, as opposed 641 // to the unit of work that is injected in routes 642 if (answer.isFailed()) { 643 onCompletion.onFailure(answer); 644 } else { 645 onCompletion.onComplete(answer); 646 } 647 648 Object result = extractResultBody(answer, pattern); 649 if (pattern.isOutCapable()) { 650 return result; 651 } else { 652 // return null if not OUT capable 653 return null; 654 } 655 } 656 }; 657 return getExecutorService().submit(task); 658 } 659 660 public Future<Exchange> asyncCallback(final Endpoint endpoint, final Exchange exchange, final Synchronization onCompletion) { 661 Callable<Exchange> task = new Callable<Exchange>() { 662 public Exchange call() throws Exception { 663 // process the exchange, any exception occurring will be caught and set on the exchange 664 send(endpoint, exchange); 665 666 // invoke callback before returning answer 667 // as it allows callback to be used without unit of work invoking it 668 // and thus it works directly from a producer template as well, as opposed 669 // to the unit of work that is injected in routes 670 if (exchange.isFailed()) { 671 onCompletion.onFailure(exchange); 672 } else { 673 onCompletion.onComplete(exchange); 674 } 675 return exchange; 676 } 677 }; 678 return getExecutorService().submit(task); 679 } 680 681 public Future<Exchange> asyncCallback(final Endpoint endpoint, final Processor processor, final Synchronization onCompletion) { 682 Callable<Exchange> task = new Callable<Exchange>() { 683 public Exchange call() throws Exception { 684 // process the exchange, any exception occurring will be caught and set on the exchange 685 Exchange answer = send(endpoint, processor); 686 687 // invoke callback before returning answer 688 // as it allows callback to be used without unit of work invoking it 689 // and thus it works directly from a producer template as well, as opposed 690 // to the unit of work that is injected in routes 691 if (answer.isFailed()) { 692 onCompletion.onFailure(answer); 693 } else { 694 onCompletion.onComplete(answer); 695 } 696 return answer; 697 } 698 }; 699 return getExecutorService().submit(task); 700 } 701 702 private ProducerCache getProducerCache() { 703 if (!isStarted()) { 704 throw new IllegalStateException("ProducerTemplate has not been started"); 705 } 706 return producerCache; 707 } 708 709 private ExecutorService getExecutorService() { 710 if (!isStarted()) { 711 throw new IllegalStateException("ProducerTemplate has not been started"); 712 } 713 714 if (executor != null) { 715 return executor; 716 } 717 718 // create a default executor which must be synchronized 719 synchronized (this) { 720 if (executor != null) { 721 return executor; 722 } 723 executor = camelContext.getExecutorServiceManager().newDefaultThreadPool(this, "ProducerTemplate"); 724 } 725 726 ObjectHelper.notNull(executor, "ExecutorService"); 727 return executor; 728 } 729 730 protected void doStart() throws Exception { 731 if (producerCache == null) { 732 if (maximumCacheSize > 0) { 733 producerCache = new ProducerCache(this, camelContext, maximumCacheSize); 734 } else { 735 producerCache = new ProducerCache(this, camelContext); 736 } 737 producerCache.setEventNotifierEnabled(isEventNotifierEnabled()); 738 } 739 ServiceHelper.startService(producerCache); 740 } 741 742 protected void doStop() throws Exception { 743 ServiceHelper.stopService(producerCache); 744 producerCache = null; 745 746 if (executor != null) { 747 camelContext.getExecutorServiceManager().shutdownNow(executor); 748 executor = null; 749 } 750 } 751 752}