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