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