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.model; 018 019import java.util.ArrayList; 020import java.util.Arrays; 021import java.util.Collection; 022import java.util.Comparator; 023import java.util.HashMap; 024import java.util.Iterator; 025import java.util.LinkedList; 026import java.util.List; 027import java.util.Map; 028import java.util.concurrent.ExecutorService; 029import java.util.concurrent.TimeUnit; 030import java.util.concurrent.atomic.AtomicInteger; 031import java.util.function.Function; 032import java.util.function.Supplier; 033import javax.xml.bind.annotation.XmlAccessType; 034import javax.xml.bind.annotation.XmlAccessorType; 035import javax.xml.bind.annotation.XmlAnyAttribute; 036import javax.xml.bind.annotation.XmlAttribute; 037import javax.xml.bind.annotation.XmlTransient; 038import javax.xml.namespace.QName; 039 040import org.apache.camel.Channel; 041import org.apache.camel.Endpoint; 042import org.apache.camel.ErrorHandlerFactory; 043import org.apache.camel.Exchange; 044import org.apache.camel.ExchangePattern; 045import org.apache.camel.Expression; 046import org.apache.camel.LoggingLevel; 047import org.apache.camel.Predicate; 048import org.apache.camel.Processor; 049import org.apache.camel.Route; 050import org.apache.camel.builder.DataFormatClause; 051import org.apache.camel.builder.EnrichClause; 052import org.apache.camel.builder.ExpressionBuilder; 053import org.apache.camel.builder.ExpressionClause; 054import org.apache.camel.builder.ProcessClause; 055import org.apache.camel.builder.ProcessorBuilder; 056import org.apache.camel.model.cloud.ServiceCallDefinition; 057import org.apache.camel.model.language.ConstantExpression; 058import org.apache.camel.model.language.ExpressionDefinition; 059import org.apache.camel.model.language.LanguageExpression; 060import org.apache.camel.model.language.SimpleExpression; 061import org.apache.camel.model.rest.RestDefinition; 062import org.apache.camel.processor.InterceptEndpointProcessor; 063import org.apache.camel.processor.Pipeline; 064import org.apache.camel.processor.aggregate.AggregationStrategy; 065import org.apache.camel.processor.interceptor.DefaultChannel; 066import org.apache.camel.processor.interceptor.Delayer; 067import org.apache.camel.processor.interceptor.HandleFault; 068import org.apache.camel.processor.interceptor.StreamCaching; 069import org.apache.camel.processor.loadbalancer.LoadBalancer; 070import org.apache.camel.spi.AsEndpointUri; 071import org.apache.camel.spi.AsPredicate; 072import org.apache.camel.spi.DataFormat; 073import org.apache.camel.spi.IdAware; 074import org.apache.camel.spi.IdempotentRepository; 075import org.apache.camel.spi.InterceptStrategy; 076import org.apache.camel.spi.LifecycleStrategy; 077import org.apache.camel.spi.Policy; 078import org.apache.camel.spi.RouteContext; 079import org.apache.camel.support.ExpressionAdapter; 080import org.slf4j.Logger; 081import org.slf4j.LoggerFactory; 082 083/** 084 * Base class for processor types that most XML types extend. 085 * 086 * @version 087 */ 088@XmlAccessorType(XmlAccessType.FIELD) 089public abstract class ProcessorDefinition<Type extends ProcessorDefinition<Type>> extends OptionalIdentifiedDefinition<Type> implements Block, OtherAttributesAware { 090 @XmlTransient 091 private static final AtomicInteger COUNTER = new AtomicInteger(); 092 @XmlTransient 093 protected final Logger log = LoggerFactory.getLogger(getClass()); 094 @XmlAttribute 095 protected Boolean inheritErrorHandler; 096 @XmlTransient 097 private final LinkedList<Block> blocks = new LinkedList<Block>(); 098 @XmlTransient 099 private ProcessorDefinition<?> parent; 100 @XmlTransient 101 private final List<InterceptStrategy> interceptStrategies = new ArrayList<InterceptStrategy>(); 102 // use xs:any to support optional property placeholders 103 @XmlAnyAttribute 104 private Map<QName, Object> otherAttributes; 105 @XmlTransient 106 private final int index; 107 108 protected ProcessorDefinition() { 109 // every time we create a definition we should inc the COUNTER counter 110 index = COUNTER.getAndIncrement(); 111 } 112 113 /** 114 * Gets the unique index number for when this {@link ProcessorDefinition} was created by its constructor. 115 * <p/> 116 * This can be used to know the order in which the definition was created when assembled as a route. 117 * 118 * @return the index number 119 */ 120 public int getIndex() { 121 return index; 122 } 123 124 // else to use an optional attribute in JAXB2 125 public abstract List<ProcessorDefinition<?>> getOutputs(); 126 127 public abstract boolean isOutputSupported(); 128 129 /** 130 * Whether this definition can only be added as top-level directly on the route itself (such as onException,onCompletion,intercept, etc.) 131 * <p/> 132 * If trying to add a top-level only definition to a nested output would fail in the {@link #addOutput(ProcessorDefinition)} 133 * method. 134 */ 135 public boolean isTopLevelOnly() { 136 return false; 137 } 138 139 /** 140 * Whether this model is abstract or not. 141 * <p/> 142 * An abstract model is something that is used for configuring cross cutting concerns such as 143 * error handling, transaction policies, interceptors etc. 144 * <p/> 145 * Regular definitions is what is part of the route, such as ToDefinition, WireTapDefinition and the likes. 146 * <p/> 147 * Will by default return <tt>false</tt> to indicate regular definition, so all the abstract definitions 148 * must override this method and return <tt>true</tt> instead. 149 * <p/> 150 * This information is used in camel-spring to let Camel work a bit on the model provided by JAXB from the 151 * Spring XML file. This is needed to handle those cross cutting concerns properly. The Java DSL does not 152 * have this issue as it can work this out directly using the fluent builder methods. 153 * 154 * @return <tt>true</tt> for abstract, otherwise <tt>false</tt> for regular. 155 */ 156 public boolean isAbstract() { 157 return false; 158 } 159 160 /** 161 * Whether this definition is wrapping the entire output. 162 * <p/> 163 * When a definition is wrapping the entire output, the check to ensure 164 * that a route definition is empty should be done on the wrapped output. 165 * 166 * @return <tt>true</tt> when wrapping the entire output. 167 */ 168 public boolean isWrappingEntireOutput() { 169 return false; 170 } 171 172 /** 173 * Override this in definition class and implement logic to create the processor 174 * based on the definition model. 175 */ 176 public Processor createProcessor(RouteContext routeContext) throws Exception { 177 throw new UnsupportedOperationException("Not implemented yet for class: " + getClass().getName()); 178 } 179 180 /** 181 * Prefer to use {#link #createChildProcessor}. 182 */ 183 public Processor createOutputsProcessor(RouteContext routeContext) throws Exception { 184 Collection<ProcessorDefinition<?>> outputs = getOutputs(); 185 return createOutputsProcessor(routeContext, outputs); 186 } 187 188 /** 189 * Creates the child processor (outputs) from the current definition 190 * 191 * @param routeContext the route context 192 * @param mandatory whether or not children is mandatory (ie the definition should have outputs) 193 * @return the created children, or <tt>null</tt> if definition had no output 194 * @throws Exception is thrown if error creating the child or if it was mandatory and there was no output defined on definition 195 */ 196 public Processor createChildProcessor(RouteContext routeContext, boolean mandatory) throws Exception { 197 Processor children = null; 198 // at first use custom factory 199 if (routeContext.getCamelContext().getProcessorFactory() != null) { 200 children = routeContext.getCamelContext().getProcessorFactory().createChildProcessor(routeContext, this, mandatory); 201 } 202 // fallback to default implementation if factory did not create the child 203 if (children == null) { 204 children = createOutputsProcessor(routeContext); 205 } 206 207 if (children == null && mandatory) { 208 throw new IllegalArgumentException("Definition has no children on " + this); 209 } 210 return children; 211 } 212 213 @Override 214 public void addOutput(ProcessorDefinition<?> output) { 215 if (!blocks.isEmpty()) { 216 // let the Block deal with the output 217 Block block = blocks.getLast(); 218 block.addOutput(output); 219 return; 220 } 221 222 // validate that top-level is only added on the route (eg top level) 223 boolean parentIsRoute = RouteDefinition.class.isAssignableFrom(this.getClass()); 224 if (output.isTopLevelOnly() && !parentIsRoute) { 225 throw new IllegalArgumentException("The output must be added as top-level on the route. Try moving " + output + " to the top of route."); 226 } 227 228 output.setParent(this); 229 configureChild(output); 230 getOutputs().add(output); 231 } 232 233 public void clearOutput() { 234 getOutputs().clear(); 235 blocks.clear(); 236 } 237 238 public void addRoutes(RouteContext routeContext, Collection<Route> routes) throws Exception { 239 Processor processor = makeProcessor(routeContext); 240 if (processor == null) { 241 // no processor to add 242 return; 243 } 244 245 if (!routeContext.isRouteAdded()) { 246 boolean endpointInterceptor = false; 247 248 // are we routing to an endpoint interceptor, if so we should not add it as an event driven 249 // processor as we use the producer to trigger the interceptor 250 if (processor instanceof Channel) { 251 Channel channel = (Channel) processor; 252 Processor next = channel.getNextProcessor(); 253 if (next instanceof InterceptEndpointProcessor) { 254 endpointInterceptor = true; 255 } 256 } 257 258 // only add regular processors as event driven 259 if (endpointInterceptor) { 260 log.debug("Endpoint interceptor should not be added as an event driven consumer route: {}", processor); 261 } else { 262 log.trace("Adding event driven processor: {}", processor); 263 routeContext.addEventDrivenProcessor(processor); 264 } 265 266 } 267 } 268 269 /** 270 * Wraps the child processor in whatever necessary interceptors and error handlers 271 */ 272 public Processor wrapProcessor(RouteContext routeContext, Processor processor) throws Exception { 273 // dont double wrap 274 if (processor instanceof Channel) { 275 return processor; 276 } 277 return wrapChannel(routeContext, processor, null); 278 } 279 280 protected Processor wrapChannel(RouteContext routeContext, Processor processor, ProcessorDefinition<?> child) throws Exception { 281 return wrapChannel(routeContext, processor, child, isInheritErrorHandler()); 282 } 283 284 protected Processor wrapChannel(RouteContext routeContext, Processor processor, ProcessorDefinition<?> child, Boolean inheritErrorHandler) throws Exception { 285 // put a channel in between this and each output to control the route flow logic 286 ModelChannel channel = createChannel(routeContext); 287 channel.setNextProcessor(processor); 288 289 // add interceptor strategies to the channel must be in this order: camel context, route context, local 290 addInterceptStrategies(routeContext, channel, routeContext.getCamelContext().getInterceptStrategies()); 291 addInterceptStrategies(routeContext, channel, routeContext.getInterceptStrategies()); 292 addInterceptStrategies(routeContext, channel, this.getInterceptStrategies()); 293 294 // must do this ugly cast to avoid compiler error on AIX/HP-UX 295 ProcessorDefinition<?> defn = (ProcessorDefinition<?>) this; 296 297 // set the child before init the channel 298 channel.setChildDefinition(child); 299 channel.initChannel(defn, routeContext); 300 301 // set the error handler, must be done after init as we can set the error handler as first in the chain 302 if (defn instanceof TryDefinition || defn instanceof CatchDefinition || defn instanceof FinallyDefinition) { 303 // do not use error handler for try .. catch .. finally blocks as it will handle errors itself 304 log.trace("{} is part of doTry .. doCatch .. doFinally so no error handler is applied", defn); 305 } else if (ProcessorDefinitionHelper.isParentOfType(TryDefinition.class, defn, true) 306 || ProcessorDefinitionHelper.isParentOfType(CatchDefinition.class, defn, true) 307 || ProcessorDefinitionHelper.isParentOfType(FinallyDefinition.class, defn, true)) { 308 // do not use error handler for try .. catch .. finally blocks as it will handle errors itself 309 // by checking that any of our parent(s) is not a try .. catch or finally type 310 log.trace("{} is part of doTry .. doCatch .. doFinally so no error handler is applied", defn); 311 } else if (defn instanceof OnExceptionDefinition || ProcessorDefinitionHelper.isParentOfType(OnExceptionDefinition.class, defn, true)) { 312 log.trace("{} is part of OnException so no error handler is applied", defn); 313 // do not use error handler for onExceptions blocks as it will handle errors itself 314 } else if (defn instanceof HystrixDefinition || ProcessorDefinitionHelper.isParentOfType(HystrixDefinition.class, defn, true)) { 315 log.trace("{} is part of HystrixCircuitBreaker so no error handler is applied", defn); 316 // do not use error handler for hystrixCircuitBreaker blocks as it will handle errors itself 317 } else if (defn instanceof MulticastDefinition) { 318 // do not use error handler for multicast as it offers fine grained error handlers for its outputs 319 // however if share unit of work is enabled, we need to wrap an error handler on the multicast parent 320 MulticastDefinition def = (MulticastDefinition) defn; 321 boolean isShareUnitOfWork = def.getShareUnitOfWork() != null && def.getShareUnitOfWork(); 322 if (isShareUnitOfWork && child == null) { 323 // only wrap the parent (not the children of the multicast) 324 wrapChannelInErrorHandler(channel, routeContext, inheritErrorHandler); 325 } else { 326 log.trace("{} is part of multicast which have special error handling so no error handler is applied", defn); 327 } 328 } else { 329 // use error handler by default or if configured to do so 330 wrapChannelInErrorHandler(channel, routeContext, inheritErrorHandler); 331 } 332 333 // do post init at the end 334 channel.postInitChannel(defn, routeContext); 335 log.trace("{} wrapped in Channel: {}", defn, channel); 336 337 return channel; 338 } 339 340 /** 341 * Wraps the given channel in error handler (if error handler is inherited) 342 * 343 * @param channel the channel 344 * @param routeContext the route context 345 * @param inheritErrorHandler whether to inherit error handler 346 * @throws Exception can be thrown if failed to create error handler builder 347 */ 348 private void wrapChannelInErrorHandler(Channel channel, RouteContext routeContext, Boolean inheritErrorHandler) throws Exception { 349 if (inheritErrorHandler == null || inheritErrorHandler) { 350 log.trace("{} is configured to inheritErrorHandler", this); 351 Processor output = channel.getOutput(); 352 Processor errorHandler = wrapInErrorHandler(routeContext, output); 353 // set error handler on channel 354 channel.setErrorHandler(errorHandler); 355 } else { 356 log.debug("{} is configured to not inheritErrorHandler.", this); 357 } 358 } 359 360 /** 361 * Wraps the given output in an error handler 362 * 363 * @param routeContext the route context 364 * @param output the output 365 * @return the output wrapped with the error handler 366 * @throws Exception can be thrown if failed to create error handler builder 367 */ 368 protected Processor wrapInErrorHandler(RouteContext routeContext, Processor output) throws Exception { 369 ErrorHandlerFactory builder = routeContext.getRoute().getErrorHandlerBuilder(); 370 // create error handler 371 Processor errorHandler = builder.createErrorHandler(routeContext, output); 372 373 // invoke lifecycles so we can manage this error handler builder 374 for (LifecycleStrategy strategy : routeContext.getCamelContext().getLifecycleStrategies()) { 375 strategy.onErrorHandlerAdd(routeContext, errorHandler, builder); 376 } 377 378 return errorHandler; 379 } 380 381 /** 382 * Adds the given list of interceptors to the channel. 383 * 384 * @param routeContext the route context 385 * @param channel the channel to add strategies 386 * @param strategies list of strategies to add. 387 */ 388 protected void addInterceptStrategies(RouteContext routeContext, Channel channel, List<InterceptStrategy> strategies) { 389 for (InterceptStrategy strategy : strategies) { 390 if (!routeContext.isStreamCaching() && strategy instanceof StreamCaching) { 391 // stream cache is disabled so we should not add it 392 continue; 393 } 394 if (!routeContext.isHandleFault() && strategy instanceof HandleFault) { 395 // handle fault is disabled so we should not add it 396 continue; 397 } 398 if (strategy instanceof Delayer) { 399 if (routeContext.getDelayer() == null || routeContext.getDelayer() <= 0) { 400 // delayer is disabled so we should not add it 401 continue; 402 } else { 403 // replace existing delayer as delayer have individual configuration 404 Iterator<InterceptStrategy> it = channel.getInterceptStrategies().iterator(); 405 while (it.hasNext()) { 406 InterceptStrategy existing = it.next(); 407 if (existing instanceof Delayer) { 408 it.remove(); 409 } 410 } 411 // add the new correct delayer 412 channel.addInterceptStrategy(strategy); 413 continue; 414 } 415 } 416 417 // add strategy 418 channel.addInterceptStrategy(strategy); 419 } 420 } 421 422 /** 423 * Creates a new instance of some kind of composite processor which defaults 424 * to using a {@link Pipeline} but derived classes could change the behaviour 425 */ 426 protected Processor createCompositeProcessor(RouteContext routeContext, List<Processor> list) throws Exception { 427 return Pipeline.newInstance(routeContext.getCamelContext(), list); 428 } 429 430 /** 431 * Creates a new instance of the {@link Channel}. 432 */ 433 protected ModelChannel createChannel(RouteContext routeContext) throws Exception { 434 return new DefaultChannel(); 435 } 436 437 protected Processor createOutputsProcessor(RouteContext routeContext, Collection<ProcessorDefinition<?>> outputs) throws Exception { 438 // We will save list of actions to restore the outputs back to the original state. 439 Runnable propertyPlaceholdersChangeReverter = ProcessorDefinitionHelper.createPropertyPlaceholdersChangeReverter(); 440 try { 441 return createOutputsProcessorImpl(routeContext, outputs); 442 } finally { 443 propertyPlaceholdersChangeReverter.run(); 444 } 445 } 446 447 protected Processor createOutputsProcessorImpl(RouteContext routeContext, Collection<ProcessorDefinition<?>> outputs) throws Exception { 448 List<Processor> list = new ArrayList<Processor>(); 449 for (ProcessorDefinition<?> output : outputs) { 450 451 // allow any custom logic before we create the processor 452 output.preCreateProcessor(); 453 454 // resolve properties before we create the processor 455 ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), output); 456 457 // resolve constant fields (eg Exchange.FILE_NAME) 458 ProcessorDefinitionHelper.resolveKnownConstantFields(output); 459 460 // also resolve properties and constant fields on embedded expressions 461 ProcessorDefinition<?> me = (ProcessorDefinition<?>) output; 462 if (me instanceof ExpressionNode) { 463 ExpressionNode exp = (ExpressionNode) me; 464 ExpressionDefinition expressionDefinition = exp.getExpression(); 465 if (expressionDefinition != null) { 466 // resolve properties before we create the processor 467 ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), expressionDefinition); 468 469 // resolve constant fields (eg Exchange.FILE_NAME) 470 ProcessorDefinitionHelper.resolveKnownConstantFields(expressionDefinition); 471 } 472 } 473 474 Processor processor = createProcessor(routeContext, output); 475 476 // inject id 477 if (processor instanceof IdAware) { 478 String id = output.idOrCreate(routeContext.getCamelContext().getNodeIdFactory()); 479 ((IdAware) processor).setId(id); 480 } 481 482 if (output instanceof Channel && processor == null) { 483 continue; 484 } 485 486 Processor channel = wrapChannel(routeContext, processor, output); 487 list.add(channel); 488 } 489 490 // if more than one output wrap than in a composite processor else just keep it as is 491 Processor processor = null; 492 if (!list.isEmpty()) { 493 if (list.size() == 1) { 494 processor = list.get(0); 495 } else { 496 processor = createCompositeProcessor(routeContext, list); 497 } 498 } 499 500 return processor; 501 } 502 503 protected Processor createProcessor(RouteContext routeContext, ProcessorDefinition<?> output) throws Exception { 504 Processor processor = null; 505 // at first use custom factory 506 if (routeContext.getCamelContext().getProcessorFactory() != null) { 507 processor = routeContext.getCamelContext().getProcessorFactory().createProcessor(routeContext, output); 508 } 509 // fallback to default implementation if factory did not create the processor 510 if (processor == null) { 511 processor = output.createProcessor(routeContext); 512 } 513 return processor; 514 } 515 516 /** 517 * Creates the processor and wraps it in any necessary interceptors and error handlers 518 */ 519 protected Processor makeProcessor(RouteContext routeContext) throws Exception { 520 // We will save list of actions to restore the definition back to the original state. 521 Runnable propertyPlaceholdersChangeReverter = ProcessorDefinitionHelper.createPropertyPlaceholdersChangeReverter(); 522 try { 523 return makeProcessorImpl(routeContext); 524 } finally { 525 // Lets restore 526 propertyPlaceholdersChangeReverter.run(); 527 } 528 } 529 530 private Processor makeProcessorImpl(RouteContext routeContext) throws Exception { 531 Processor processor = null; 532 533 // allow any custom logic before we create the processor 534 preCreateProcessor(); 535 536 // resolve properties before we create the processor 537 ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), this); 538 539 // resolve constant fields (eg Exchange.FILE_NAME) 540 ProcessorDefinitionHelper.resolveKnownConstantFields(this); 541 542 // also resolve properties and constant fields on embedded expressions 543 ProcessorDefinition<?> me = (ProcessorDefinition<?>) this; 544 if (me instanceof ExpressionNode) { 545 ExpressionNode exp = (ExpressionNode) me; 546 ExpressionDefinition expressionDefinition = exp.getExpression(); 547 if (expressionDefinition != null) { 548 // resolve properties before we create the processor 549 ProcessorDefinitionHelper.resolvePropertyPlaceholders(routeContext.getCamelContext(), expressionDefinition); 550 551 // resolve constant fields (eg Exchange.FILE_NAME) 552 ProcessorDefinitionHelper.resolveKnownConstantFields(expressionDefinition); 553 } 554 } 555 556 // at first use custom factory 557 if (routeContext.getCamelContext().getProcessorFactory() != null) { 558 processor = routeContext.getCamelContext().getProcessorFactory().createProcessor(routeContext, this); 559 } 560 // fallback to default implementation if factory did not create the processor 561 if (processor == null) { 562 processor = createProcessor(routeContext); 563 } 564 565 // inject id 566 if (processor instanceof IdAware) { 567 String id = this.idOrCreate(routeContext.getCamelContext().getNodeIdFactory()); 568 ((IdAware) processor).setId(id); 569 } 570 571 if (processor == null) { 572 // no processor to make 573 return null; 574 } 575 return wrapProcessor(routeContext, processor); 576 } 577 578 /** 579 * Strategy to execute any custom logic before the {@link Processor} is created. 580 */ 581 protected void preCreateProcessor() { 582 // noop 583 } 584 585 /** 586 * Strategy for children to do any custom configuration 587 * 588 * @param output the child to be added as output to this 589 */ 590 public void configureChild(ProcessorDefinition<?> output) { 591 // noop 592 } 593 594 // Fluent API 595 // ------------------------------------------------------------------------- 596 597 /** 598 * Adds a placeholder for the given option 599 * <p/> 600 * Requires using the {@link org.apache.camel.component.properties.PropertiesComponent} 601 * 602 * @param option the name of the option 603 * @param key the placeholder key 604 * @return the builder 605 */ 606 public Type placeholder(String option, String key) { 607 QName name = new QName(Constants.PLACEHOLDER_QNAME, option); 608 return attribute(name, key); 609 } 610 611 /** 612 * Adds an optional attribute 613 * 614 * @param name the name of the attribute 615 * @param value the value 616 * @return the builder 617 */ 618 @SuppressWarnings("unchecked") 619 public Type attribute(QName name, Object value) { 620 if (otherAttributes == null) { 621 otherAttributes = new HashMap<QName, Object>(); 622 } 623 otherAttributes.put(name, value); 624 return (Type) this; 625 } 626 627 /** 628 * Sends the exchange to the given endpoint 629 * 630 * @param uri the endpoint to send to 631 * @return the builder 632 */ 633 @SuppressWarnings("unchecked") 634 public Type to(@AsEndpointUri String uri) { 635 addOutput(new ToDefinition(uri)); 636 return (Type) this; 637 } 638 639 /** 640 * Sends the exchange to the given dynamic endpoint 641 * 642 * @param uri the dynamic endpoint to send to (resolved using simple language by default) 643 * @return the builder 644 */ 645 @SuppressWarnings("unchecked") 646 public Type toD(@AsEndpointUri String uri) { 647 ToDynamicDefinition answer = new ToDynamicDefinition(); 648 answer.setUri(uri); 649 addOutput(answer); 650 return (Type) this; 651 } 652 653 /** 654 * Sends the exchange to the given dynamic endpoint 655 * 656 * @param uri the dynamic endpoint to send to (resolved using simple language by default) 657 * @param cacheSize sets the maximum size used by the {@link org.apache.camel.impl.ConsumerCache} which is used to cache and reuse producers. 658 * 659 * @return the builder 660 */ 661 @SuppressWarnings("unchecked") 662 public Type toD(@AsEndpointUri String uri, int cacheSize) { 663 ToDynamicDefinition answer = new ToDynamicDefinition(); 664 answer.setUri(uri); 665 answer.setCacheSize(cacheSize); 666 addOutput(answer); 667 return (Type) this; 668 } 669 670 /** 671 * Sends the exchange to the given dynamic endpoint 672 * 673 * @param uri the dynamic endpoint to send to (resolved using simple language by default) 674 * @param ignoreInvalidEndpoint ignore the invalidate endpoint exception when try to create a producer with that endpoint 675 * @return the builder 676 */ 677 @SuppressWarnings("unchecked") 678 public Type toD(@AsEndpointUri String uri, boolean ignoreInvalidEndpoint) { 679 ToDynamicDefinition answer = new ToDynamicDefinition(); 680 answer.setUri(uri); 681 answer.setIgnoreInvalidEndpoint(ignoreInvalidEndpoint); 682 addOutput(answer); 683 return (Type) this; 684 } 685 686 /** 687 * Sends the exchange to the given endpoint 688 * 689 * @param uri the String formatted endpoint uri to send to 690 * @param args arguments for the string formatting of the uri 691 * @return the builder 692 */ 693 @SuppressWarnings("unchecked") 694 public Type toF(@AsEndpointUri String uri, Object... args) { 695 addOutput(new ToDefinition(String.format(uri, args))); 696 return (Type) this; 697 } 698 699 /** 700 * Calls the service 701 * 702 * @return the builder 703 */ 704 public ServiceCallDefinition serviceCall() { 705 ServiceCallDefinition answer = new ServiceCallDefinition(); 706 addOutput(answer); 707 return answer; 708 } 709 710 /** 711 * Calls the service 712 * 713 * @param name the service name 714 * @return the builder 715 */ 716 @SuppressWarnings("unchecked") 717 public Type serviceCall(String name) { 718 ServiceCallDefinition answer = new ServiceCallDefinition(); 719 answer.setName(name); 720 addOutput(answer); 721 return (Type) this; 722 } 723 724 /** 725 * Calls the service 726 * 727 * @param name the service name 728 * @param uri the endpoint uri to use for calling the service 729 * @return the builder 730 */ 731 @SuppressWarnings("unchecked") 732 public Type serviceCall(String name, @AsEndpointUri String uri) { 733 ServiceCallDefinition answer = new ServiceCallDefinition(); 734 answer.setName(name); 735 answer.setUri(uri); 736 addOutput(answer); 737 return (Type) this; 738 } 739 740 /** 741 * Sends the exchange to the given endpoint 742 * 743 * @param endpoint the endpoint to send to 744 * @return the builder 745 */ 746 @SuppressWarnings("unchecked") 747 public Type to(Endpoint endpoint) { 748 addOutput(new ToDefinition(endpoint)); 749 return (Type) this; 750 } 751 752 /** 753 * Sends the exchange with certain exchange pattern to the given endpoint 754 * <p/> 755 * Notice the existing MEP is preserved 756 * 757 * @param pattern the pattern to use for the message exchange 758 * @param uri the endpoint to send to 759 * @return the builder 760 */ 761 @SuppressWarnings("unchecked") 762 public Type to(ExchangePattern pattern, @AsEndpointUri String uri) { 763 addOutput(new ToDefinition(uri, pattern)); 764 return (Type) this; 765 } 766 767 /** 768 * Sends the exchange with certain exchange pattern to the given endpoint 769 * <p/> 770 * Notice the existing MEP is preserved 771 * 772 * @param pattern the pattern to use for the message exchange 773 * @param endpoint the endpoint to send to 774 * @return the builder 775 */ 776 @SuppressWarnings("unchecked") 777 public Type to(ExchangePattern pattern, Endpoint endpoint) { 778 addOutput(new ToDefinition(endpoint, pattern)); 779 return (Type) this; 780 } 781 782 /** 783 * Sends the exchange to a list of endpoints 784 * 785 * @param uris list of endpoints to send to 786 * @return the builder 787 */ 788 @SuppressWarnings("unchecked") 789 public Type to(@AsEndpointUri String... uris) { 790 for (String uri : uris) { 791 addOutput(new ToDefinition(uri)); 792 } 793 return (Type) this; 794 } 795 796 /** 797 * Sends the exchange to a list of endpoints 798 * 799 * @param endpoints list of endpoints to send to 800 * @return the builder 801 */ 802 @SuppressWarnings("unchecked") 803 public Type to(Endpoint... endpoints) { 804 for (Endpoint endpoint : endpoints) { 805 addOutput(new ToDefinition(endpoint)); 806 } 807 return (Type) this; 808 } 809 810 /** 811 * Sends the exchange to a list of endpoints 812 * 813 * @param endpoints list of endpoints to send to 814 * @return the builder 815 */ 816 @SuppressWarnings("unchecked") 817 public Type to(Iterable<Endpoint> endpoints) { 818 for (Endpoint endpoint : endpoints) { 819 addOutput(new ToDefinition(endpoint)); 820 } 821 return (Type) this; 822 } 823 824 /** 825 * Sends the exchange to a list of endpoints 826 * <p/> 827 * Notice the existing MEP is preserved 828 * 829 * @param pattern the pattern to use for the message exchanges 830 * @param uris list of endpoints to send to 831 * @return the builder 832 */ 833 @SuppressWarnings("unchecked") 834 public Type to(ExchangePattern pattern, @AsEndpointUri String... uris) { 835 for (String uri : uris) { 836 addOutput(new ToDefinition(uri, pattern)); 837 } 838 return (Type) this; 839 } 840 841 /** 842 * Sends the exchange to a list of endpoints 843 * <p/> 844 * Notice the existing MEP is preserved 845 * 846 * @param pattern the pattern to use for the message exchanges 847 * @param endpoints list of endpoints to send to 848 * @return the builder 849 */ 850 @SuppressWarnings("unchecked") 851 public Type to(ExchangePattern pattern, Endpoint... endpoints) { 852 for (Endpoint endpoint : endpoints) { 853 addOutput(new ToDefinition(endpoint, pattern)); 854 } 855 return (Type) this; 856 } 857 858 /** 859 * Sends the exchange to a list of endpoints 860 * 861 * @param pattern the pattern to use for the message exchanges 862 * @param endpoints list of endpoints to send to 863 * @return the builder 864 */ 865 @SuppressWarnings("unchecked") 866 public Type to(ExchangePattern pattern, Iterable<Endpoint> endpoints) { 867 for (Endpoint endpoint : endpoints) { 868 addOutput(new ToDefinition(endpoint, pattern)); 869 } 870 return (Type) this; 871 } 872 873 /** 874 * <a href="http://camel.apache.org/exchange-pattern.html">ExchangePattern:</a> 875 * set the {@link ExchangePattern} into the {@link Exchange}. 876 * <p/> 877 * The pattern set on the {@link Exchange} will be changed from this point going foward. 878 * 879 * @param exchangePattern instance of {@link ExchangePattern} 880 * @return the builder 881 */ 882 @SuppressWarnings("unchecked") 883 public Type setExchangePattern(ExchangePattern exchangePattern) { 884 addOutput(new SetExchangePatternDefinition(exchangePattern)); 885 return (Type) this; 886 } 887 888 /** 889 * <a href="http://camel.apache.org/exchange-pattern.html">ExchangePattern:</a> 890 * set the exchange's ExchangePattern {@link ExchangePattern} to be InOnly 891 * <p/> 892 * The pattern set on the {@link Exchange} will be changed from this point going foward. 893 * 894 * @return the builder 895 * @deprecated use {@link #setExchangePattern(org.apache.camel.ExchangePattern)} instead 896 */ 897 @Deprecated 898 public Type inOnly() { 899 return setExchangePattern(ExchangePattern.InOnly); 900 } 901 902 /** 903 * Sends the message to the given endpoint using an 904 * <a href="http://camel.apache.org/event-message.html">Event Message</a> or 905 * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a> 906 * <p/> 907 * Notice the existing MEP is restored after the message has been sent to the given endpoint. 908 * 909 * @param uri The endpoint uri which is used for sending the exchange 910 * @return the builder 911 */ 912 public Type inOnly(@AsEndpointUri String uri) { 913 return to(ExchangePattern.InOnly, uri); 914 } 915 916 /** 917 * Sends the message to the given endpoint using an 918 * <a href="http://camel.apache.org/event-message.html">Event Message</a> or 919 * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a> 920 * <p/> 921 * Notice the existing MEP is restored after the message has been sent to the given endpoint. 922 * 923 * @param endpoint The endpoint which is used for sending the exchange 924 * @return the builder 925 */ 926 public Type inOnly(Endpoint endpoint) { 927 return to(ExchangePattern.InOnly, endpoint); 928 } 929 930 /** 931 * Sends the message to the given endpoints using an 932 * <a href="http://camel.apache.org/event-message.html">Event Message</a> or 933 * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a> 934 * <p/> 935 * Notice the existing MEP is restored after the message has been sent to the given endpoint. 936 * 937 * @param uris list of endpoints to send to 938 * @return the builder 939 */ 940 public Type inOnly(@AsEndpointUri String... uris) { 941 return to(ExchangePattern.InOnly, uris); 942 } 943 944 /** 945 * Sends the message to the given endpoints using an 946 * <a href="http://camel.apache.org/event-message.html">Event Message</a> or 947 * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a> 948 * <p/> 949 * Notice the existing MEP is restored after the message has been sent to the given endpoint. 950 * 951 * @param endpoints list of endpoints to send to 952 * @return the builder 953 */ 954 public Type inOnly(@AsEndpointUri Endpoint... endpoints) { 955 return to(ExchangePattern.InOnly, endpoints); 956 } 957 958 /** 959 * Sends the message to the given endpoints using an 960 * <a href="http://camel.apache.org/event-message.html">Event Message</a> or 961 * <a href="http://camel.apache.org/exchange-pattern.html">InOnly exchange pattern</a> 962 * <p/> 963 * Notice the existing MEP is restored after the message has been sent to the given endpoint. 964 * 965 * @param endpoints list of endpoints to send to 966 * @return the builder 967 */ 968 public Type inOnly(Iterable<Endpoint> endpoints) { 969 return to(ExchangePattern.InOnly, endpoints); 970 } 971 972 /** 973 * <a href="http://camel.apache.org/exchange-pattern.html">ExchangePattern:</a> 974 * set the exchange's ExchangePattern {@link ExchangePattern} to be InOut 975 * 976 * @return the builder 977 * @deprecated use {@link #setExchangePattern(org.apache.camel.ExchangePattern)} instead 978 */ 979 @Deprecated 980 public Type inOut() { 981 return setExchangePattern(ExchangePattern.InOut); 982 } 983 984 /** 985 * Sends the message to the given endpoint using an 986 * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or 987 * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a> 988 * <p/> 989 * Notice the existing MEP is restored after the message has been sent to the given endpoint. 990 * 991 * @param uri The endpoint uri which is used for sending the exchange 992 * @return the builder 993 */ 994 public Type inOut(@AsEndpointUri String uri) { 995 return to(ExchangePattern.InOut, uri); 996 } 997 998 /** 999 * Sends the message to the given endpoint using an 1000 * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or 1001 * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a> 1002 * <p/> 1003 * Notice the existing MEP is restored after the message has been sent to the given endpoint. 1004 * 1005 * @param endpoint The endpoint which is used for sending the exchange 1006 * @return the builder 1007 */ 1008 public Type inOut(Endpoint endpoint) { 1009 return to(ExchangePattern.InOut, endpoint); 1010 } 1011 1012 /** 1013 * Sends the message to the given endpoints using an 1014 * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or 1015 * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a> 1016 * <p/> 1017 * Notice the existing MEP is restored after the message has been sent to the given endpoint. 1018 * 1019 * @param uris list of endpoints to send to 1020 * @return the builder 1021 */ 1022 public Type inOut(@AsEndpointUri String... uris) { 1023 return to(ExchangePattern.InOut, uris); 1024 } 1025 1026 /** 1027 * Sends the message to the given endpoints using an 1028 * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or 1029 * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a> 1030 * <p/> 1031 * Notice the existing MEP is restored after the message has been sent to the given endpoint. 1032 * 1033 * @param endpoints list of endpoints to send to 1034 * @return the builder 1035 */ 1036 public Type inOut(Endpoint... endpoints) { 1037 return to(ExchangePattern.InOut, endpoints); 1038 } 1039 1040 /** 1041 * Sends the message to the given endpoints using an 1042 * <a href="http://camel.apache.org/request-reply.html">Request Reply</a> or 1043 * <a href="http://camel.apache.org/exchange-pattern.html">InOut exchange pattern</a> 1044 * <p/> 1045 * Notice the existing MEP is restored after the message has been sent to the given endpoint. 1046 * 1047 * @param endpoints list of endpoints to send to 1048 * @return the builder 1049 */ 1050 public Type inOut(Iterable<Endpoint> endpoints) { 1051 return to(ExchangePattern.InOut, endpoints); 1052 } 1053 1054 /** 1055 * Sets the id of this node. 1056 * <p/> 1057 * <b>Important:</b> If you want to set the id of the route, 1058 * then you <b>must</b> use {@link #routeId(String)} instead. 1059 * 1060 * @param id the id 1061 * @return the builder 1062 */ 1063 @SuppressWarnings("unchecked") 1064 public Type id(String id) { 1065 if (isOutputSupported() && getOutputs().isEmpty()) { 1066 // set id on this 1067 setId(id); 1068 } else { 1069 1070 // set it on last output as this is what the user means to do 1071 // for Block(s) with non empty getOutputs() the id probably refers 1072 // to the last definition in the current Block 1073 List<ProcessorDefinition<?>> outputs = getOutputs(); 1074 if (!blocks.isEmpty()) { 1075 if (blocks.getLast() instanceof ProcessorDefinition) { 1076 ProcessorDefinition<?> block = (ProcessorDefinition<?>)blocks.getLast(); 1077 if (!block.getOutputs().isEmpty()) { 1078 outputs = block.getOutputs(); 1079 } 1080 } 1081 } 1082 if (!getOutputs().isEmpty()) { 1083 outputs.get(outputs.size() - 1).setId(id); 1084 } else { 1085 // the output could be empty 1086 setId(id); 1087 } 1088 } 1089 1090 return (Type) this; 1091 } 1092 1093 /** 1094 * Set the route id for this route. 1095 * <p/> 1096 * <b>Important: </b> Each route in the same {@link org.apache.camel.CamelContext} must have an <b>unique</b> route id. 1097 * If you use the API from {@link org.apache.camel.CamelContext} or {@link ModelCamelContext} to add routes, then any 1098 * new routes which has a route id that matches an old route, then the old route is replaced by the new route. 1099 * 1100 * @param id the route id, should be unique 1101 * @return the builder 1102 */ 1103 @SuppressWarnings("unchecked") 1104 public Type routeId(String id) { 1105 ProcessorDefinition<?> def = this; 1106 1107 RouteDefinition route = ProcessorDefinitionHelper.getRoute(def); 1108 if (route != null) { 1109 route.setId(id); 1110 } 1111 1112 return (Type) this; 1113 } 1114 1115 /** 1116 * Set the route description for this route 1117 * 1118 * @param description the route description 1119 * @return the builder 1120 */ 1121 @SuppressWarnings("unchecked") 1122 public Type routeDescription(String description) { 1123 ProcessorDefinition<?> def = this; 1124 1125 RouteDefinition route = ProcessorDefinitionHelper.getRoute(def); 1126 if (route != null) { 1127 DescriptionDefinition desc = new DescriptionDefinition(); 1128 desc.setText(description); 1129 route.setDescription(desc); 1130 } 1131 1132 return (Type) this; 1133 } 1134 1135 /** 1136 * <a href="http://camel.apache.org/multicast.html">Multicast EIP:</a> 1137 * Multicasts messages to all its child outputs; so that each processor and 1138 * destination gets a copy of the original message to avoid the processors 1139 * interfering with each other. 1140 * 1141 * @return the builder 1142 */ 1143 public MulticastDefinition multicast() { 1144 MulticastDefinition answer = new MulticastDefinition(); 1145 addOutput(answer); 1146 return answer; 1147 } 1148 1149 /** 1150 * <a href="http://camel.apache.org/multicast.html">Multicast EIP:</a> 1151 * Multicasts messages to all its child outputs; so that each processor and 1152 * destination gets a copy of the original message to avoid the processors 1153 * interfering with each other. 1154 * 1155 * @param aggregationStrategy the strategy used to aggregate responses for 1156 * every part 1157 * @param parallelProcessing if is <tt>true</tt> camel will fork thread to call the endpoint producer 1158 * @return the builder 1159 */ 1160 public MulticastDefinition multicast(AggregationStrategy aggregationStrategy, boolean parallelProcessing) { 1161 MulticastDefinition answer = new MulticastDefinition(); 1162 addOutput(answer); 1163 answer.setAggregationStrategy(aggregationStrategy); 1164 answer.setParallelProcessing(parallelProcessing); 1165 return answer; 1166 } 1167 1168 /** 1169 * <a href="http://camel.apache.org/multicast.html">Multicast EIP:</a> 1170 * Multicasts messages to all its child outputs; so that each processor and 1171 * destination gets a copy of the original message to avoid the processors 1172 * interfering with each other. 1173 * 1174 * @param aggregationStrategy the strategy used to aggregate responses for every part 1175 * @return the builder 1176 */ 1177 public MulticastDefinition multicast(AggregationStrategy aggregationStrategy) { 1178 MulticastDefinition answer = new MulticastDefinition(); 1179 addOutput(answer); 1180 answer.setAggregationStrategy(aggregationStrategy); 1181 return answer; 1182 } 1183 1184 /** 1185 * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a> 1186 * Creates a {@link Pipeline} so that the message 1187 * will get processed by each endpoint in turn and for request/response the 1188 * output of one endpoint will be the input of the next endpoint 1189 * 1190 * @return the builder 1191 */ 1192 public PipelineDefinition pipeline() { 1193 PipelineDefinition answer = new PipelineDefinition(); 1194 addOutput(answer); 1195 return answer; 1196 } 1197 1198 /** 1199 * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a> 1200 * Creates a {@link Pipeline} of the list of endpoints so that the message 1201 * will get processed by each endpoint in turn and for request/response the 1202 * output of one endpoint will be the input of the next endpoint 1203 * 1204 * @param uris list of endpoints 1205 * @return the builder 1206 */ 1207 public Type pipeline(@AsEndpointUri String... uris) { 1208 PipelineDefinition answer = new PipelineDefinition(); 1209 addOutput(answer); 1210 answer.to(uris); 1211 return (Type) this; 1212 } 1213 1214 /** 1215 * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a> 1216 * Creates a {@link Pipeline} of the list of endpoints so that the message 1217 * will get processed by each endpoint in turn and for request/response the 1218 * output of one endpoint will be the input of the next endpoint 1219 * 1220 * @param endpoints list of endpoints 1221 * @return the builder 1222 */ 1223 public Type pipeline(Endpoint... endpoints) { 1224 PipelineDefinition answer = new PipelineDefinition(); 1225 addOutput(answer); 1226 answer.to(endpoints); 1227 return (Type) this; 1228 } 1229 1230 /** 1231 * <a href="http://camel.apache.org/pipes-nd-filters.html">Pipes and Filters EIP:</a> 1232 * Creates a {@link Pipeline} of the list of endpoints so that the message 1233 * will get processed by each endpoint in turn and for request/response the 1234 * output of one endpoint will be the input of the next endpoint 1235 * 1236 * @param endpoints list of endpoints 1237 * @return the builder 1238 */ 1239 public Type pipeline(Collection<Endpoint> endpoints) { 1240 PipelineDefinition answer = new PipelineDefinition(); 1241 addOutput(answer); 1242 answer.to(endpoints); 1243 return (Type) this; 1244 } 1245 1246 /** 1247 * Continues processing the {@link org.apache.camel.Exchange} using asynchronous routing engine. 1248 * 1249 * @return the builder 1250 */ 1251 public ThreadsDefinition threads() { 1252 ThreadsDefinition answer = new ThreadsDefinition(); 1253 addOutput(answer); 1254 return answer; 1255 } 1256 1257 /** 1258 * Continues processing the {@link org.apache.camel.Exchange} using asynchronous routing engine. 1259 * 1260 * @param poolSize the core pool size 1261 * @return the builder 1262 */ 1263 public ThreadsDefinition threads(int poolSize) { 1264 ThreadsDefinition answer = new ThreadsDefinition(); 1265 answer.setPoolSize(poolSize); 1266 addOutput(answer); 1267 return answer; 1268 } 1269 1270 /** 1271 * Continues processing the {@link org.apache.camel.Exchange} using asynchronous routing engine. 1272 * 1273 * @param poolSize the core pool size 1274 * @param maxPoolSize the maximum pool size 1275 * @return the builder 1276 */ 1277 public ThreadsDefinition threads(int poolSize, int maxPoolSize) { 1278 ThreadsDefinition answer = new ThreadsDefinition(); 1279 answer.setPoolSize(poolSize); 1280 answer.setMaxPoolSize(maxPoolSize); 1281 addOutput(answer); 1282 return answer; 1283 } 1284 1285 /** 1286 * Continues processing the {@link org.apache.camel.Exchange} using asynchronous routing engine. 1287 * 1288 * @param poolSize the core pool size 1289 * @param maxPoolSize the maximum pool size 1290 * @param threadName the thread pool name 1291 * @return the builder 1292 */ 1293 public ThreadsDefinition threads(int poolSize, int maxPoolSize, String threadName) { 1294 ThreadsDefinition answer = new ThreadsDefinition(); 1295 answer.setPoolSize(poolSize); 1296 answer.setMaxPoolSize(maxPoolSize); 1297 answer.setThreadName(threadName); 1298 addOutput(answer); 1299 return answer; 1300 } 1301 1302 /** 1303 * Wraps the sub route using AOP allowing you to do before and after work (AOP around). 1304 * 1305 * @return the builder 1306 * @deprecated to be removed in the near future. Instead you can use interceptors or processors to do AOP with Camel. 1307 */ 1308 @Deprecated 1309 public AOPDefinition aop() { 1310 AOPDefinition answer = new AOPDefinition(); 1311 addOutput(answer); 1312 return answer; 1313 } 1314 1315 /** 1316 * Ends the current block 1317 * 1318 * @return the builder 1319 */ 1320 public ProcessorDefinition<?> end() { 1321 // must do this ugly cast to avoid compiler error on AIX/HP-UX 1322 ProcessorDefinition<?> defn = (ProcessorDefinition<?>) this; 1323 1324 // when using choice .. when .. otherwise - doTry .. doCatch .. doFinally we should always 1325 // end the choice/try definition to avoid having to use 2 x end() in the route 1326 // this is counter intuitive for end users 1327 // TODO (camel-3.0): this should be done inside of TryDefinition or even better 1328 // in Block(s) in general, but the api needs to be revisited for that. 1329 if (defn instanceof TryDefinition || defn instanceof ChoiceDefinition) { 1330 popBlock(); 1331 } 1332 1333 if (blocks.isEmpty()) { 1334 if (parent == null) { 1335 return this.endParent(); 1336 } 1337 return parent.endParent(); 1338 } 1339 popBlock(); 1340 return this.endParent(); 1341 } 1342 1343 /** 1344 * Strategy to allow {@link ProcessorDefinition}s to have special logic when using end() in the DSL 1345 * to return back to the intended parent. 1346 * <p/> 1347 * For example a content based router we return back to the {@link ChoiceDefinition} when we end() 1348 * from a {@link WhenDefinition}. 1349 * 1350 * @return the end 1351 */ 1352 public ProcessorDefinition<?> endParent() { 1353 return this; 1354 } 1355 1356 /** 1357 * Ends the current block and returns back to the {@link ChoiceDefinition choice()} DSL. 1358 * <p/> 1359 * <b>Important:</b> If you want to end the entire choice block, then use {@link #end()} instead. 1360 * The purpose of {@link #endChoice()} is to return <i>control</i> back to the {@link ChoiceDefinition choice()} DSL, 1361 * so you can add subsequent <tt>when</tt> and <tt>otherwise</tt> to the choice. There can be situations where 1362 * you would need to use {@link #endChoice()} often when you add additional EIPs inside the <tt>when</tt>'s, and 1363 * the DSL <t>looses</t> scope when using a regular {@link #end()}, and you would need to use this {@link #endChoice()} 1364 * to return back the scope to the {@link ChoiceDefinition choice()} DSL. 1365 * <p/> 1366 * For more details and examples see also this FAQ: 1367 * <a href="http://camel.apache.org/why-can-i-not-use-when-or-otherwise-in-a-java-camel-route.html">Why can I not use when or otherwise in a Java Camel route </a>. 1368 * 1369 * @return the choice builder 1370 */ 1371 public ChoiceDefinition endChoice() { 1372 // are we nested choice? 1373 ProcessorDefinition<?> def = this; 1374 if (def.getParent() instanceof WhenDefinition) { 1375 return (ChoiceDefinition) def.getParent().getParent(); 1376 } 1377 1378 // are we already a choice? 1379 if (def instanceof ChoiceDefinition) { 1380 return (ChoiceDefinition) def; 1381 } 1382 1383 // okay end this and get back to the choice 1384 def = end(); 1385 if (def instanceof WhenDefinition) { 1386 return (ChoiceDefinition) def.getParent(); 1387 } else if (def instanceof OtherwiseDefinition) { 1388 return (ChoiceDefinition) def.getParent(); 1389 } else { 1390 return (ChoiceDefinition) def; 1391 } 1392 } 1393 1394 /** 1395 * Ends the current block and returns back to the {@link org.apache.camel.model.rest.RestDefinition rest()} DSL. 1396 * 1397 * @return the builder 1398 */ 1399 public RestDefinition endRest() { 1400 ProcessorDefinition<?> def = this; 1401 1402 RouteDefinition route = ProcessorDefinitionHelper.getRoute(def); 1403 if (route != null) { 1404 return route.getRestDefinition(); 1405 } 1406 1407 throw new IllegalArgumentException("Cannot find RouteDefinition to allow endRest"); 1408 } 1409 1410 /** 1411 * Ends the current block and returns back to the {@link TryDefinition doTry()} DSL. 1412 * 1413 * @return the builder 1414 */ 1415 public TryDefinition endDoTry() { 1416 ProcessorDefinition<?> def = this; 1417 1418 // are we already a try? 1419 if (def instanceof TryDefinition) { 1420 return (TryDefinition) def; 1421 } 1422 1423 // okay end this and get back to the try 1424 def = end(); 1425 return (TryDefinition) def; 1426 } 1427 1428 /** 1429 * Ends the current block and returns back to the {@link HystrixDefinition hystrix()} DSL. 1430 * 1431 * @return the builder 1432 */ 1433 public HystrixDefinition endHystrix() { 1434 ProcessorDefinition<?> def = this; 1435 1436 // are we already a try? 1437 if (def instanceof HystrixDefinition) { 1438 return (HystrixDefinition) def; 1439 } 1440 1441 // okay end this and get back to the try 1442 def = end(); 1443 return (HystrixDefinition) def; 1444 } 1445 1446 /** 1447 * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a> 1448 * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer} using a fluent builder. 1449 */ 1450 public ExpressionClause<IdempotentConsumerDefinition> idempotentConsumer() { 1451 IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition(); 1452 addOutput(answer); 1453 1454 return ExpressionClause.createAndSetExpression(answer); 1455 } 1456 1457 /** 1458 * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a> 1459 * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer} 1460 * to avoid duplicate messages 1461 * 1462 * @param messageIdExpression expression to test of duplicate messages 1463 * @return the builder 1464 */ 1465 public IdempotentConsumerDefinition idempotentConsumer(Expression messageIdExpression) { 1466 IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition(); 1467 answer.setExpression(ExpressionNodeHelper.toExpressionDefinition(messageIdExpression)); 1468 addOutput(answer); 1469 return answer; 1470 } 1471 1472 /** 1473 * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a> 1474 * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer} 1475 * to avoid duplicate messages 1476 * 1477 * @param messageIdExpression expression to test of duplicate messages 1478 * @param idempotentRepository the repository to use for duplicate check 1479 * @return the builder 1480 */ 1481 public IdempotentConsumerDefinition idempotentConsumer(Expression messageIdExpression, IdempotentRepository<?> idempotentRepository) { 1482 IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition(messageIdExpression, idempotentRepository); 1483 addOutput(answer); 1484 return answer; 1485 } 1486 1487 /** 1488 * <a href="http://camel.apache.org/idempotent-consumer.html">Idempotent consumer EIP:</a> 1489 * Creates an {@link org.apache.camel.processor.idempotent.IdempotentConsumer IdempotentConsumer} 1490 * to avoid duplicate messages 1491 * 1492 * @param idempotentRepository the repository to use for duplicate check 1493 * @return the builder used to create the expression 1494 * @deprecated will be removed in Camel 3.0. Instead use any of the other methods 1495 */ 1496 @Deprecated 1497 public ExpressionClause<IdempotentConsumerDefinition> idempotentConsumer(IdempotentRepository<?> idempotentRepository) { 1498 IdempotentConsumerDefinition answer = new IdempotentConsumerDefinition(); 1499 answer.setMessageIdRepository(idempotentRepository); 1500 addOutput(answer); 1501 return ExpressionClause.createAndSetExpression(answer); 1502 } 1503 1504 /** 1505 * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a> 1506 * Creates a predicate expression which only if it is <tt>true</tt> then the 1507 * exchange is forwarded to the destination 1508 * 1509 * @return the clause used to create the filter expression 1510 */ 1511 @AsPredicate 1512 public ExpressionClause<? extends FilterDefinition> filter() { 1513 FilterDefinition filter = new FilterDefinition(); 1514 addOutput(filter); 1515 return ExpressionClause.createAndSetExpression(filter); 1516 } 1517 1518 /** 1519 * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a> 1520 * Creates a predicate which is applied and only if it is <tt>true</tt> then the 1521 * exchange is forwarded to the destination 1522 * 1523 * @param predicate predicate to use 1524 * @return the builder 1525 */ 1526 public FilterDefinition filter(@AsPredicate Predicate predicate) { 1527 FilterDefinition filter = new FilterDefinition(predicate); 1528 addOutput(filter); 1529 return filter; 1530 } 1531 1532 /** 1533 * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a> 1534 * Creates a predicate expression which only if it is <tt>true</tt> then the 1535 * exchange is forwarded to the destination 1536 * 1537 * @param expression the predicate expression to use 1538 * @return the builder 1539 */ 1540 public FilterDefinition filter(@AsPredicate ExpressionDefinition expression) { 1541 FilterDefinition filter = new FilterDefinition(expression); 1542 addOutput(filter); 1543 return filter; 1544 } 1545 1546 /** 1547 * <a href="http://camel.apache.org/message-filter.html">Message Filter EIP:</a> 1548 * Creates a predicate language expression which only if it is <tt>true</tt> then the 1549 * exchange is forwarded to the destination 1550 * 1551 * @param language language for expression 1552 * @param expression the expression 1553 * @return the builder 1554 */ 1555 public FilterDefinition filter(String language, @AsPredicate String expression) { 1556 return filter(new LanguageExpression(language, expression)); 1557 } 1558 1559 /** 1560 * Creates a validation expression which only if it is <tt>true</tt> then the 1561 * exchange is forwarded to the destination. 1562 * Otherwise a {@link org.apache.camel.processor.validation.PredicateValidationException} is thrown. 1563 * 1564 * @param expression the expression 1565 * @return the builder 1566 */ 1567 public ValidateDefinition validate(@AsPredicate Expression expression) { 1568 ValidateDefinition answer = new ValidateDefinition(expression); 1569 addOutput(answer); 1570 return answer; 1571 } 1572 1573 /** 1574 * Creates a validation expression which only if it is <tt>true</tt> then the 1575 * exchange is forwarded to the destination. 1576 * Otherwise a {@link org.apache.camel.processor.validation.PredicateValidationException} is thrown. 1577 * 1578 * @param predicate the predicate 1579 * @return the builder 1580 */ 1581 public ValidateDefinition validate(@AsPredicate Predicate predicate) { 1582 ValidateDefinition answer = new ValidateDefinition(predicate); 1583 addOutput(answer); 1584 return answer; 1585 } 1586 1587 /** 1588 * Creates a validation expression which only if it is <tt>true</tt> then the 1589 * exchange is forwarded to the destination. 1590 * Otherwise a {@link org.apache.camel.processor.validation.PredicateValidationException} is thrown. 1591 * 1592 * @return the builder 1593 */ 1594 @AsPredicate 1595 public ExpressionClause<ValidateDefinition> validate() { 1596 ValidateDefinition answer = new ValidateDefinition(); 1597 addOutput(answer); 1598 return ExpressionClause.createAndSetExpression(answer); 1599 } 1600 1601 /** 1602 * Creates a Hystrix Circuit Breaker EIP. 1603 * <p/> 1604 * This requires having camel-hystrix on the classpath. 1605 * 1606 * @return the builder 1607 */ 1608 public HystrixDefinition hystrix() { 1609 HystrixDefinition answer = new HystrixDefinition(); 1610 addOutput(answer); 1611 return answer; 1612 } 1613 1614 /** 1615 * <a href="http://camel.apache.org/load-balancer.html">Load Balancer EIP:</a> 1616 * Creates a loadbalance 1617 * 1618 * @return the builder 1619 */ 1620 public LoadBalanceDefinition loadBalance() { 1621 LoadBalanceDefinition answer = new LoadBalanceDefinition(); 1622 addOutput(answer); 1623 return answer; 1624 } 1625 1626 /** 1627 * <a href="http://camel.apache.org/load-balancer.html">Load Balancer EIP:</a> 1628 * Creates a loadbalance 1629 * 1630 * @param loadBalancer a custom load balancer to use 1631 * @return the builder 1632 */ 1633 public LoadBalanceDefinition loadBalance(LoadBalancer loadBalancer) { 1634 LoadBalanceDefinition answer = new LoadBalanceDefinition(); 1635 addOutput(answer); 1636 return answer.loadBalance(loadBalancer); 1637 } 1638 1639 /** 1640 * Creates a log message to be logged at INFO level. 1641 * 1642 * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax) 1643 * @return the builder 1644 */ 1645 @SuppressWarnings("unchecked") 1646 public Type log(String message) { 1647 LogDefinition answer = new LogDefinition(message); 1648 addOutput(answer); 1649 return (Type) this; 1650 } 1651 1652 /** 1653 * Creates a log message to be logged at the given level. 1654 * 1655 * @param loggingLevel the logging level to use 1656 * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax) 1657 * @return the builder 1658 */ 1659 @SuppressWarnings("unchecked") 1660 public Type log(LoggingLevel loggingLevel, String message) { 1661 LogDefinition answer = new LogDefinition(message); 1662 answer.setLoggingLevel(loggingLevel); 1663 addOutput(answer); 1664 return (Type) this; 1665 } 1666 1667 /** 1668 * Creates a log message to be logged at the given level and name. 1669 * 1670 * @param loggingLevel the logging level to use 1671 * @param logName the log name to use 1672 * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax) 1673 * @return the builder 1674 */ 1675 @SuppressWarnings("unchecked") 1676 public Type log(LoggingLevel loggingLevel, String logName, String message) { 1677 LogDefinition answer = new LogDefinition(message); 1678 answer.setLoggingLevel(loggingLevel); 1679 answer.setLogName(logName); 1680 addOutput(answer); 1681 return (Type) this; 1682 } 1683 1684 /** 1685 * Creates a log message to be logged at the given level using provided logger. 1686 * 1687 * @param loggingLevel the logging level to use 1688 * @param logger the logger to use 1689 * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax) 1690 * @return the builder 1691 */ 1692 @SuppressWarnings("unchecked") 1693 public Type log(LoggingLevel loggingLevel, Logger logger, String message) { 1694 LogDefinition answer = new LogDefinition(message); 1695 answer.setLoggingLevel(loggingLevel); 1696 answer.setLogger(logger); 1697 addOutput(answer); 1698 return (Type) this; 1699 } 1700 1701 /** 1702 * Creates a log message to be logged at the given level and name. 1703 * 1704 * 1705 * @param loggingLevel the logging level to use 1706 * @param logName the log name to use 1707 * @param marker log marker name 1708 * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax) 1709 * @return the builder 1710 */ 1711 @SuppressWarnings("unchecked") 1712 public Type log(LoggingLevel loggingLevel, String logName, String marker, String message) { 1713 LogDefinition answer = new LogDefinition(message); 1714 answer.setLoggingLevel(loggingLevel); 1715 answer.setLogName(logName); 1716 answer.setMarker(marker); 1717 addOutput(answer); 1718 return (Type) this; 1719 } 1720 1721 /** 1722 * Creates a log message to be logged at the given level using provided logger. 1723 * 1724 * 1725 * @param loggingLevel the logging level to use 1726 * @param logger the logger to use 1727 * @param marker log marker name 1728 * @param message the log message, (you can use {@link org.apache.camel.language.simple.SimpleLanguage} syntax) 1729 * @return the builder 1730 */ 1731 @SuppressWarnings("unchecked") 1732 public Type log(LoggingLevel loggingLevel, Logger logger, String marker, String message) { 1733 LogDefinition answer = new LogDefinition(message); 1734 answer.setLoggingLevel(loggingLevel); 1735 answer.setLogger(logger); 1736 answer.setMarker(marker); 1737 addOutput(answer); 1738 return (Type) this; 1739 } 1740 1741 /** 1742 * <a href="http://camel.apache.org/content-based-router.html">Content Based Router EIP:</a> 1743 * Creates a choice of one or more predicates with an otherwise clause 1744 * 1745 * @return the builder for a choice expression 1746 */ 1747 public ChoiceDefinition choice() { 1748 ChoiceDefinition answer = new ChoiceDefinition(); 1749 addOutput(answer); 1750 return answer; 1751 } 1752 1753 /** 1754 * Creates a try/catch block 1755 * 1756 * @return the builder for a tryBlock expression 1757 */ 1758 public TryDefinition doTry() { 1759 TryDefinition answer = new TryDefinition(); 1760 addOutput(answer); 1761 return answer; 1762 } 1763 1764 /** 1765 * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a> 1766 * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients. 1767 * <p/> 1768 * Will use comma as default delimiter. 1769 * 1770 * @param recipients expression to decide the destinations 1771 * @return the builder 1772 */ 1773 public RecipientListDefinition<Type> recipientList(@AsEndpointUri Expression recipients) { 1774 RecipientListDefinition<Type> answer = new RecipientListDefinition<Type>(recipients); 1775 addOutput(answer); 1776 return answer; 1777 } 1778 1779 /** 1780 * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a> 1781 * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients 1782 * 1783 * @param recipients expression to decide the destinations 1784 * @param delimiter a custom delimiter to use 1785 * @return the builder 1786 */ 1787 public RecipientListDefinition<Type> recipientList(@AsEndpointUri Expression recipients, String delimiter) { 1788 RecipientListDefinition<Type> answer = new RecipientListDefinition<Type>(recipients); 1789 answer.setDelimiter(delimiter); 1790 addOutput(answer); 1791 return answer; 1792 } 1793 1794 /** 1795 * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a> 1796 * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients 1797 * 1798 * @param delimiter a custom delimiter to use 1799 * @return the builder 1800 */ 1801 @AsEndpointUri 1802 public ExpressionClause<RecipientListDefinition<Type>> recipientList(String delimiter) { 1803 RecipientListDefinition<Type> answer = new RecipientListDefinition<Type>(); 1804 answer.setDelimiter(delimiter); 1805 addOutput(answer); 1806 return ExpressionClause.createAndSetExpression(answer); 1807 } 1808 1809 /** 1810 * <a href="http://camel.apache.org/recipient-list.html">Recipient List EIP:</a> 1811 * Creates a dynamic recipient list allowing you to route messages to a number of dynamically specified recipients 1812 * 1813 * @return the expression clause to configure the expression to decide the destinations 1814 */ 1815 @AsEndpointUri 1816 public ExpressionClause<RecipientListDefinition<Type>> recipientList() { 1817 RecipientListDefinition<Type> answer = new RecipientListDefinition<Type>(); 1818 addOutput(answer); 1819 return ExpressionClause.createAndSetExpression(answer); 1820 } 1821 1822 /** 1823 * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a> 1824 * Creates a routing slip allowing you to route a message consecutively through a series of processing 1825 * steps where the sequence of steps is not known at design time and can vary for each message. 1826 * <p/> 1827 * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing. 1828 * 1829 * @param header is the header that the {@link org.apache.camel.processor.RoutingSlip RoutingSlip} 1830 * class will look in for the list of URIs to route the message to. 1831 * @param uriDelimiter is the delimiter that will be used to split up 1832 * the list of URIs in the routing slip. 1833 * @return the builder 1834 * @deprecated prefer to use {@link #routingSlip(org.apache.camel.Expression, String)} instead 1835 */ 1836 @Deprecated 1837 public Type routingSlip(String header, String uriDelimiter) { 1838 RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(header, uriDelimiter); 1839 addOutput(answer); 1840 return (Type) this; 1841 } 1842 1843 /** 1844 * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a> 1845 * Creates a routing slip allowing you to route a message consecutively through a series of processing 1846 * steps where the sequence of steps is not known at design time and can vary for each message. 1847 * <p/> 1848 * The list of URIs will be split based on the default delimiter {@link RoutingSlipDefinition#DEFAULT_DELIMITER} 1849 * <p/> 1850 * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing. 1851 * 1852 * @param header is the header that the {@link org.apache.camel.processor.RoutingSlip RoutingSlip} 1853 * class will look in for the list of URIs to route the message to. 1854 * @return the builder 1855 * @deprecated prefer to use {@link #routingSlip(org.apache.camel.Expression)} instead 1856 */ 1857 @Deprecated 1858 public Type routingSlip(String header) { 1859 RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(header); 1860 addOutput(answer); 1861 return (Type) this; 1862 } 1863 1864 /** 1865 * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a> 1866 * Creates a routing slip allowing you to route a message consecutively through a series of processing 1867 * steps where the sequence of steps is not known at design time and can vary for each message. 1868 * <p/> 1869 * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing. 1870 * 1871 * @param header is the header that the {@link org.apache.camel.processor.RoutingSlip RoutingSlip} 1872 * class will look in for the list of URIs to route the message to. 1873 * @param uriDelimiter is the delimiter that will be used to split up 1874 * the list of URIs in the routing slip. 1875 * @param ignoreInvalidEndpoints if this parameter is true, routingSlip will ignore the endpoints which 1876 * cannot be resolved or a producer cannot be created or started 1877 * @return the builder 1878 * @deprecated prefer to use {@link #routingSlip()} instead 1879 */ 1880 @Deprecated 1881 public Type routingSlip(String header, String uriDelimiter, boolean ignoreInvalidEndpoints) { 1882 RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(header, uriDelimiter); 1883 answer.setIgnoreInvalidEndpoints(ignoreInvalidEndpoints); 1884 addOutput(answer); 1885 return (Type) this; 1886 } 1887 1888 /** 1889 * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a> 1890 * Creates a routing slip allowing you to route a message consecutively through a series of processing 1891 * steps where the sequence of steps is not known at design time and can vary for each message. 1892 * <p/> 1893 * The list of URIs will be split based on the default delimiter {@link RoutingSlipDefinition#DEFAULT_DELIMITER} 1894 * <p/> 1895 * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing. 1896 * 1897 * @param header is the header that the {@link org.apache.camel.processor.RoutingSlip RoutingSlip} 1898 * class will look in for the list of URIs to route the message to. 1899 * @param ignoreInvalidEndpoints if this parameter is true, routingSlip will ignore the endpoints which 1900 * cannot be resolved or a producer cannot be created or started 1901 * @return the builder 1902 * @deprecated prefer to use {@link #routingSlip()} instead 1903 */ 1904 @Deprecated 1905 public Type routingSlip(String header, boolean ignoreInvalidEndpoints) { 1906 RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(header); 1907 answer.setIgnoreInvalidEndpoints(ignoreInvalidEndpoints); 1908 addOutput(answer); 1909 return (Type) this; 1910 } 1911 1912 /** 1913 * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a> 1914 * Creates a routing slip allowing you to route a message consecutively through a series of processing 1915 * steps where the sequence of steps is not known at design time and can vary for each message. 1916 * <p/> 1917 * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing. 1918 * 1919 * @param expression to decide the destinations 1920 * @param uriDelimiter is the delimiter that will be used to split up 1921 * the list of URIs in the routing slip. 1922 * @return the builder 1923 */ 1924 public RoutingSlipDefinition<Type> routingSlip(@AsEndpointUri Expression expression, String uriDelimiter) { 1925 RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(expression, uriDelimiter); 1926 addOutput(answer); 1927 return answer; 1928 } 1929 1930 /** 1931 * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a> 1932 * Creates a routing slip allowing you to route a message consecutively through a series of processing 1933 * steps where the sequence of steps is not known at design time and can vary for each message. 1934 * <p/> 1935 * The list of URIs will be split based on the default delimiter {@link RoutingSlipDefinition#DEFAULT_DELIMITER} 1936 * <p/> 1937 * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing. 1938 * 1939 * @param expression to decide the destinations 1940 * @return the builder 1941 */ 1942 public RoutingSlipDefinition<Type> routingSlip(@AsEndpointUri Expression expression) { 1943 RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(expression); 1944 addOutput(answer); 1945 return answer; 1946 } 1947 1948 /** 1949 * <a href="http://camel.apache.org/routing-slip.html">Routing Slip EIP:</a> 1950 * Creates a routing slip allowing you to route a message consecutively through a series of processing 1951 * steps where the sequence of steps is not known at design time and can vary for each message. 1952 * <p/> 1953 * The list of URIs will be split based on the default delimiter {@link RoutingSlipDefinition#DEFAULT_DELIMITER} 1954 * <p/> 1955 * The route slip will be evaluated <i>once</i>, use {@link #dynamicRouter()} if you need even more dynamic routing. 1956 * 1957 * @return the expression clause to configure the expression to decide the destinations 1958 */ 1959 public ExpressionClause<RoutingSlipDefinition<Type>> routingSlip() { 1960 RoutingSlipDefinition<Type> answer = new RoutingSlipDefinition<Type>(); 1961 addOutput(answer); 1962 return ExpressionClause.createAndSetExpression(answer); 1963 } 1964 1965 /** 1966 * <a href="http://camel.apache.org/dynamic-router.html">Dynamic Router EIP:</a> 1967 * Creates a dynamic router allowing you to route a message consecutively through a series of processing 1968 * steps where the sequence of steps is not known at design time and can vary for each message. 1969 * <p/> 1970 * <br/><b>Important:</b> The expression will be invoked repeatedly until it returns <tt>null</tt>, so be sure it does that, 1971 * otherwise it will be invoked endlessly. 1972 * 1973 * @param expression to decide the destinations, which will be invoked repeatedly 1974 * until it evaluates <tt>null</tt> to indicate no more destinations. 1975 * @return the builder 1976 */ 1977 public DynamicRouterDefinition<Type> dynamicRouter(@AsEndpointUri Expression expression) { 1978 DynamicRouterDefinition<Type> answer = new DynamicRouterDefinition<Type>(expression); 1979 addOutput(answer); 1980 return answer; 1981 } 1982 1983 /** 1984 * <a href="http://camel.apache.org/dynamic-router.html">Dynamic Router EIP:</a> 1985 * Creates a dynamic router allowing you to route a message consecutively through a series of processing 1986 * steps where the sequence of steps is not known at design time and can vary for each message. 1987 * <p/> 1988 * <br/><b>Important:</b> The expression will be invoked repeatedly until it returns <tt>null</tt>, so be sure it does that, 1989 * otherwise it will be invoked endlessly. 1990 * 1991 * @return the expression clause to configure the expression to decide the destinations, 1992 * which will be invoked repeatedly until it evaluates <tt>null</tt> to indicate no more destinations. 1993 */ 1994 @AsEndpointUri 1995 public ExpressionClause<DynamicRouterDefinition<Type>> dynamicRouter() { 1996 DynamicRouterDefinition<Type> answer = new DynamicRouterDefinition<Type>(); 1997 addOutput(answer); 1998 return ExpressionClause.createAndSetExpression(answer); 1999 } 2000 2001 /** 2002 * <a href="http://camel.apache.org/sampling.html">Sampling Throttler</a> 2003 * Creates a sampling throttler allowing you to extract a sample of 2004 * exchanges from the traffic on a route. It is configured with a sampling 2005 * period, during which only a single exchange is allowed to pass through. 2006 * All other exchanges will be stopped. 2007 * <p/> 2008 * Default period is one second. 2009 * 2010 * @return the builder 2011 */ 2012 public SamplingDefinition sample() { 2013 return sample(1, TimeUnit.SECONDS); 2014 } 2015 2016 /** 2017 * <a href="http://camel.apache.org/sampling.html">Sampling Throttler</a> 2018 * Creates a sampling throttler allowing you to extract a sample of exchanges 2019 * from the traffic through a route. It is configured with a sampling period 2020 * during which only a single exchange is allowed to pass through. 2021 * All other exchanges will be stopped. 2022 * 2023 * @param samplePeriod this is the sample interval, only one exchange is 2024 * allowed through in this interval 2025 * @param unit this is the units for the samplePeriod e.g. Seconds 2026 * @return the builder 2027 */ 2028 public SamplingDefinition sample(long samplePeriod, TimeUnit unit) { 2029 SamplingDefinition answer = new SamplingDefinition(samplePeriod, unit); 2030 addOutput(answer); 2031 return answer; 2032 } 2033 2034 /** 2035 * <a href="http://camel.apache.org/sampling.html">Sampling Throttler</a> 2036 * Creates a sampling throttler allowing you to extract a sample of exchanges 2037 * from the traffic through a route. It is configured with a sampling message frequency 2038 * during which only a single exchange is allowed to pass through. 2039 * All other exchanges will be stopped. 2040 * 2041 * @param messageFrequency this is the sample message frequency, only one exchange is 2042 * allowed through for this many messages received 2043 * @return the builder 2044 */ 2045 public SamplingDefinition sample(long messageFrequency) { 2046 SamplingDefinition answer = new SamplingDefinition(messageFrequency); 2047 addOutput(answer); 2048 return answer; 2049 } 2050 2051 /** 2052 * <a href="http://camel.apache.org/splitter.html">Splitter EIP:</a> 2053 * Creates a splitter allowing you split a message into a number of pieces and process them individually. 2054 * <p> 2055 * This splitter responds with the original input message. You can use a custom {@link AggregationStrategy} to 2056 * control what to respond from the splitter. 2057 * 2058 * @return the expression clause builder for the expression on which to split 2059 */ 2060 public ExpressionClause<SplitDefinition> split() { 2061 SplitDefinition answer = new SplitDefinition(); 2062 addOutput(answer); 2063 return ExpressionClause.createAndSetExpression(answer); 2064 } 2065 2066 /** 2067 * <a href="http://camel.apache.org/splitter.html">Splitter EIP:</a> 2068 * Creates a splitter allowing you split a message into a number of pieces and process them individually. 2069 * <p> 2070 * This splitter responds with the original input message. You can use a custom {@link AggregationStrategy} to 2071 * control what to respond from the splitter. 2072 * 2073 * @param expression the expression on which to split the message 2074 * @return the builder 2075 */ 2076 public SplitDefinition split(Expression expression) { 2077 SplitDefinition answer = new SplitDefinition(expression); 2078 addOutput(answer); 2079 return answer; 2080 } 2081 2082 /** 2083 * <a href="http://camel.apache.org/splitter.html">Splitter EIP:</a> 2084 * Creates a splitter allowing you split a message into a number of pieces and process them individually. 2085 * <p> 2086 * The splitter responds with the answer produced by the given {@link AggregationStrategy}. 2087 * 2088 * @param expression the expression on which to split 2089 * @param aggregationStrategy the strategy used to aggregate responses for every part 2090 * @return the builder 2091 */ 2092 public SplitDefinition split(Expression expression, AggregationStrategy aggregationStrategy) { 2093 SplitDefinition answer = new SplitDefinition(expression); 2094 addOutput(answer); 2095 answer.setAggregationStrategy(aggregationStrategy); 2096 return answer; 2097 } 2098 2099 /** 2100 * <a href="http://camel.apache.org/resequencer.html">Resequencer EIP:</a> 2101 * Creates a resequencer allowing you to reorganize messages based on some comparator. 2102 * 2103 * @return the expression clause for the expressions on which to compare messages in order 2104 */ 2105 public ExpressionClause<ResequenceDefinition> resequence() { 2106 ResequenceDefinition answer = new ResequenceDefinition(); 2107 ExpressionClause<ResequenceDefinition> clause = new ExpressionClause<ResequenceDefinition>(answer); 2108 answer.setExpression(clause); 2109 addOutput(answer); 2110 return clause; 2111 } 2112 2113 /** 2114 * <a href="http://camel.apache.org/resequencer.html">Resequencer EIP:</a> 2115 * Creates a resequencer allowing you to reorganize messages based on some comparator. 2116 * 2117 * @param expression the expression on which to compare messages in order 2118 * @return the builder 2119 */ 2120 public ResequenceDefinition resequence(Expression expression) { 2121 ResequenceDefinition answer = new ResequenceDefinition(expression); 2122 addOutput(answer); 2123 return answer; 2124 } 2125 2126 /** 2127 * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a> 2128 * Creates an aggregator allowing you to combine a number of messages together into a single message. 2129 * 2130 * @return the expression clause to be used as builder to configure the correlation expression 2131 */ 2132 public ExpressionClause<AggregateDefinition> aggregate() { 2133 AggregateDefinition answer = new AggregateDefinition(); 2134 ExpressionClause<AggregateDefinition> clause = new ExpressionClause<AggregateDefinition>(answer); 2135 answer.setExpression(clause); 2136 addOutput(answer); 2137 return clause; 2138 } 2139 2140 /** 2141 * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a> 2142 * Creates an aggregator allowing you to combine a number of messages together into a single message. 2143 * 2144 * @param aggregationStrategy the strategy used for the aggregation 2145 * @return the expression clause to be used as builder to configure the correlation expression 2146 */ 2147 public ExpressionClause<AggregateDefinition> aggregate(AggregationStrategy aggregationStrategy) { 2148 AggregateDefinition answer = new AggregateDefinition(); 2149 ExpressionClause<AggregateDefinition> clause = new ExpressionClause<>(answer); 2150 answer.setExpression(clause); 2151 answer.setAggregationStrategy(aggregationStrategy); 2152 addOutput(answer); 2153 return clause; 2154 } 2155 2156 /** 2157 * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a> 2158 * Creates an aggregator allowing you to combine a number of messages together into a single message. 2159 * 2160 * @param correlationExpression the expression used to calculate the 2161 * correlation key. For a JMS message this could be the 2162 * expression <code>header("JMSDestination")</code> or 2163 * <code>header("JMSCorrelationID")</code> 2164 * @return the builder 2165 */ 2166 public AggregateDefinition aggregate(Expression correlationExpression) { 2167 AggregateDefinition answer = new AggregateDefinition(correlationExpression); 2168 addOutput(answer); 2169 return answer; 2170 } 2171 2172 /** 2173 * <a href="http://camel.apache.org/aggregator.html">Aggregator EIP:</a> 2174 * Creates an aggregator allowing you to combine a number of messages together into a single message. 2175 * 2176 * @param correlationExpression the expression used to calculate the 2177 * correlation key. For a JMS message this could be the 2178 * expression <code>header("JMSDestination")</code> or 2179 * <code>header("JMSCorrelationID")</code> 2180 * @param aggregationStrategy the strategy used for the aggregation 2181 * @return the builder 2182 */ 2183 public AggregateDefinition aggregate(Expression correlationExpression, AggregationStrategy aggregationStrategy) { 2184 AggregateDefinition answer = new AggregateDefinition(correlationExpression, aggregationStrategy); 2185 addOutput(answer); 2186 return answer; 2187 } 2188 2189 /** 2190 * <a href="http://camel.apache.org/delayer.html">Delayer EIP:</a> 2191 * Creates a delayer allowing you to delay the delivery of messages to some destination. 2192 * 2193 * @param delay an expression to calculate the delay time in millis 2194 * @return the builder 2195 */ 2196 public DelayDefinition delay(Expression delay) { 2197 DelayDefinition answer = new DelayDefinition(delay); 2198 addOutput(answer); 2199 return answer; 2200 } 2201 2202 /** 2203 * <a href="http://camel.apache.org/delayer.html">Delayer EIP:</a> 2204 * Creates a delayer allowing you to delay the delivery of messages to some destination. 2205 * 2206 * @return the expression clause to create the expression 2207 */ 2208 public ExpressionClause<DelayDefinition> delay() { 2209 DelayDefinition answer = new DelayDefinition(); 2210 addOutput(answer); 2211 return ExpressionClause.createAndSetExpression(answer); 2212 } 2213 2214 /** 2215 * <a href="http://camel.apache.org/delayer.html">Delayer EIP:</a> 2216 * Creates a delayer allowing you to delay the delivery of messages to some destination. 2217 * 2218 * @param delay the delay in millis 2219 * @return the builder 2220 */ 2221 public DelayDefinition delay(long delay) { 2222 return delay(ExpressionBuilder.constantExpression(delay)); 2223 } 2224 2225 /** 2226 * <a href="http://camel.apache.org/throttler.html">Throttler EIP:</a> 2227 * Creates a throttler using a fluent builder. 2228 * 2229 * @return the builder 2230 */ 2231 public ExpressionClause<ThrottleDefinition> throttle() { 2232 ThrottleDefinition answer = new ThrottleDefinition(); 2233 addOutput(answer); 2234 2235 return ExpressionClause.createAndSetExpression(answer); 2236 } 2237 2238 /** 2239 * <a href="http://camel.apache.org/throttler.html">Throttler EIP:</a> 2240 * Creates a throttler allowing you to ensure that a specific endpoint does not get overloaded, 2241 * or that we don't exceed an agreed SLA with some external service. 2242 * <p/> 2243 * Will default use a time period of 1 second, so setting the maximumRequestCount to eg 10 2244 * will default ensure at most 10 messages per second. 2245 * 2246 * @param maximumRequestCount the maximum messages 2247 * @return the builder 2248 */ 2249 public ThrottleDefinition throttle(long maximumRequestCount) { 2250 return throttle(ExpressionBuilder.constantExpression(maximumRequestCount)); 2251 } 2252 2253 /** 2254 * <a href="http://camel.apache.org/throttler.html">Throttler EIP:</a> 2255 * Creates a throttler allowing you to ensure that a specific endpoint does not get overloaded, 2256 * or that we don't exceed an agreed SLA with some external service. 2257 * <p/> 2258 * Will default use a time period of 1 second, so setting the maximumRequestCount to eg 10 2259 * will default ensure at most 10 messages per second. 2260 * 2261 * @param maximumRequestCount an expression to calculate the maximum request count 2262 * @return the builder 2263 */ 2264 public ThrottleDefinition throttle(Expression maximumRequestCount) { 2265 ThrottleDefinition answer = new ThrottleDefinition(maximumRequestCount); 2266 addOutput(answer); 2267 return answer; 2268 } 2269 2270 /** 2271 * <a href="http://camel.apache.org/loop.html">Loop EIP:</a> 2272 * Creates a loop allowing to process the a message a number of times and possibly process them 2273 * in a different way. Useful mostly for testing. 2274 * 2275 * @return the clause used to create the loop expression 2276 */ 2277 public ExpressionClause<LoopDefinition> loop() { 2278 LoopDefinition loop = new LoopDefinition(); 2279 addOutput(loop); 2280 return ExpressionClause.createAndSetExpression(loop); 2281 } 2282 2283 /** 2284 * <a href="http://camel.apache.org/loop.html">Loop EIP:</a> 2285 * Creates a loop allowing to process the a message a number of times and possibly process them 2286 * in a different way. 2287 * 2288 * @param expression the loop expression 2289 * @return the builder 2290 */ 2291 public LoopDefinition loop(Expression expression) { 2292 LoopDefinition loop = new LoopDefinition(expression); 2293 addOutput(loop); 2294 return loop; 2295 } 2296 2297 /** 2298 * <a href="http://camel.apache.org/loop.html">Loop EIP:</a> 2299 * Creates a while loop allowing to process the a message while the predicate matches 2300 * and possibly process them in a different way. 2301 * 2302 * @param predicate the while loop predicate 2303 * @return the builder 2304 */ 2305 public LoopDefinition loopDoWhile(@AsPredicate Predicate predicate) { 2306 LoopDefinition loop = new LoopDefinition(predicate); 2307 addOutput(loop); 2308 return loop; 2309 } 2310 2311 /** 2312 * <a href="http://camel.apache.org/loop.html">Loop EIP:</a> 2313 * Creates a loop allowing to process the a message a number of times and possibly process them 2314 * in a different way using a fluent builder. 2315 * 2316 * @return the builder 2317 */ 2318 public ExpressionClause<LoopDefinition> loopDoWhile() { 2319 LoopDefinition loop = new LoopDefinition(); 2320 loop.setDoWhile(true); 2321 2322 addOutput(loop); 2323 2324 return ExpressionClause.createAndSetExpression(loop); 2325 } 2326 2327 /** 2328 * <a href="http://camel.apache.org/loop.html">Loop EIP:</a> 2329 * Creates a loop allowing to process the a message a number of times and possibly process them 2330 * in a different way. 2331 * 2332 * @param count the number of times 2333 * @return the builder 2334 */ 2335 public LoopDefinition loop(int count) { 2336 LoopDefinition loop = new LoopDefinition(new ConstantExpression(Integer.toString(count))); 2337 addOutput(loop); 2338 return loop; 2339 } 2340 2341 /** 2342 * Sets the exception on the {@link org.apache.camel.Exchange} 2343 * 2344 * @param exception the exception to throw 2345 * @return the builder 2346 */ 2347 public Type throwException(Exception exception) { 2348 ThrowExceptionDefinition answer = new ThrowExceptionDefinition(); 2349 answer.setException(exception); 2350 addOutput(answer); 2351 return (Type) this; 2352 } 2353 2354 /** 2355 * Sets the exception on the {@link org.apache.camel.Exchange} 2356 * 2357 * @param type the exception class to use 2358 * @param message the given message as caused message (supports simple language) 2359 * @return the builder 2360 */ 2361 public Type throwException(Class<? extends Exception> type, String message) { 2362 ThrowExceptionDefinition answer = new ThrowExceptionDefinition(); 2363 answer.setExceptionClass(type); 2364 answer.setMessage(message); 2365 addOutput(answer); 2366 return (Type) this; 2367 } 2368 2369 /** 2370 * Marks the exchange for rollback only. 2371 * <p/> 2372 * Does <b>not</b> set any exception as opposed to {@link #rollback()} methods. 2373 * 2374 * @return the builder 2375 * @see #rollback() 2376 * @see #rollback(String) 2377 * @see #markRollbackOnlyLast() 2378 */ 2379 public Type markRollbackOnly() { 2380 RollbackDefinition answer = new RollbackDefinition(); 2381 answer.setMarkRollbackOnly(true); 2382 addOutput(answer); 2383 return (Type) this; 2384 } 2385 2386 /** 2387 * Marks the exchange for rollback only, but only for the last (current) transaction. 2388 * <p/> 2389 * A last rollback is used when you have nested transactions and only want the last local transaction to rollback, 2390 * where as the outer transaction can still be completed 2391 * <p/> 2392 * Does <b>not</b> set any exception as opposed to {@link #rollback()} methods. 2393 * 2394 * @return the builder 2395 * @see #rollback() 2396 * @see #rollback(String) 2397 * @see #markRollbackOnly() 2398 */ 2399 public Type markRollbackOnlyLast() { 2400 RollbackDefinition answer = new RollbackDefinition(); 2401 answer.setMarkRollbackOnlyLast(true); 2402 addOutput(answer); 2403 return (Type) this; 2404 } 2405 2406 /** 2407 * Marks the exchange for rollback only and sets an exception with a default message. 2408 * <p/> 2409 * This is done by setting a {@link org.apache.camel.RollbackExchangeException} on the Exchange 2410 * and mark it for rollback. 2411 * 2412 * @return the builder 2413 * @see #markRollbackOnly() 2414 */ 2415 public Type rollback() { 2416 return rollback(null); 2417 } 2418 2419 /** 2420 * Marks the exchange for rollback and sets an exception with the provided message. 2421 * <p/> 2422 * This is done by setting a {@link org.apache.camel.RollbackExchangeException} on the Exchange 2423 * and mark it for rollback. 2424 * 2425 * @param message an optional message used for logging purpose why the rollback was triggered 2426 * @return the builder 2427 * @see #markRollbackOnly() 2428 */ 2429 public Type rollback(String message) { 2430 RollbackDefinition answer = new RollbackDefinition(message); 2431 addOutput(answer); 2432 return (Type) this; 2433 } 2434 2435 /** 2436 * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a> 2437 * Sends messages to all its child outputs; so that each processor and 2438 * destination gets a copy of the original message to avoid the processors 2439 * interfering with each other using {@link ExchangePattern#InOnly}. 2440 * 2441 * @param endpoint the endpoint to wiretap to 2442 * @return the builder 2443 */ 2444 public WireTapDefinition<Type> wireTap(Endpoint endpoint) { 2445 WireTapDefinition answer = new WireTapDefinition(); 2446 answer.setUri(endpoint.getEndpointUri()); 2447 addOutput(answer); 2448 return answer; 2449 } 2450 2451 /** 2452 * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a> 2453 * Sends messages to all its child outputs; so that each processor and 2454 * destination gets a copy of the original message to avoid the processors 2455 * interfering with each other using {@link ExchangePattern#InOnly}. 2456 * 2457 * @param uri the dynamic endpoint to wiretap to (resolved using simple language by default) 2458 * @return the builder 2459 */ 2460 public WireTapDefinition<Type> wireTap(@AsEndpointUri String uri) { 2461 WireTapDefinition answer = new WireTapDefinition(); 2462 answer.setUri(uri); 2463 addOutput(answer); 2464 return answer; 2465 } 2466 2467 /** 2468 * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a> 2469 * Sends messages to all its child outputs; so that each processor and 2470 * destination gets a copy of the original message to avoid the processors 2471 * interfering with each other using {@link ExchangePattern#InOnly}. 2472 * 2473 * @param uri the dynamic endpoint to wiretap to (resolved using simple language by default) 2474 * @param executorService a custom {@link ExecutorService} to use as thread pool 2475 * for sending tapped exchanges 2476 * @return the builder 2477 * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0 2478 */ 2479 @Deprecated 2480 public WireTapDefinition<Type> wireTap(@AsEndpointUri String uri, ExecutorService executorService) { 2481 WireTapDefinition answer = new WireTapDefinition(); 2482 answer.setUri(uri); 2483 answer.setExecutorService(executorService); 2484 addOutput(answer); 2485 return answer; 2486 } 2487 2488 /** 2489 * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a> 2490 * Sends messages to all its child outputs; so that each processor and 2491 * destination gets a copy of the original message to avoid the processors 2492 * interfering with each other using {@link ExchangePattern#InOnly}. 2493 * 2494 * @param uri the dynamic endpoint to wiretap to (resolved using simple language by default) 2495 * @param executorServiceRef reference to lookup a custom {@link ExecutorService} 2496 * to use as thread pool for sending tapped exchanges 2497 * @return the builder 2498 * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0 2499 */ 2500 @Deprecated 2501 public WireTapDefinition<Type> wireTap(@AsEndpointUri String uri, String executorServiceRef) { 2502 WireTapDefinition answer = new WireTapDefinition(); 2503 answer.setUri(uri); 2504 answer.setExecutorServiceRef(executorServiceRef); 2505 addOutput(answer); 2506 return answer; 2507 } 2508 2509 /** 2510 * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a> 2511 * Sends a new {@link org.apache.camel.Exchange} to the destination 2512 * using {@link ExchangePattern#InOnly}. 2513 * <p/> 2514 * Will use a copy of the original Exchange which is passed in as argument 2515 * to the given expression 2516 * 2517 * @param uri the dynamic endpoint to wiretap to (resolved using simple language by default) 2518 * @param body expression that creates the body to send 2519 * @return the builder 2520 * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0 2521 */ 2522 @Deprecated 2523 public WireTapDefinition<Type> wireTap(@AsEndpointUri String uri, Expression body) { 2524 return wireTap(uri, true, body); 2525 } 2526 2527 /** 2528 * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a> 2529 * Sends a new {@link org.apache.camel.Exchange} to the destination 2530 * using {@link ExchangePattern#InOnly}. 2531 * 2532 * @param uri the dynamic endpoint to wiretap to (resolved using simple language by default) 2533 * @param copy whether or not use a copy of the original exchange or a new empty exchange 2534 * @return the builder 2535 * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0 2536 */ 2537 @Deprecated 2538 public WireTapDefinition<Type> wireTap(@AsEndpointUri String uri, boolean copy) { 2539 WireTapDefinition answer = new WireTapDefinition(); 2540 answer.setUri(uri); 2541 answer.setCopy(copy); 2542 addOutput(answer); 2543 return answer; 2544 } 2545 2546 /** 2547 * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a> 2548 * Sends a new {@link org.apache.camel.Exchange} to the destination 2549 * using {@link ExchangePattern#InOnly}. 2550 * 2551 * @param uri the dynamic endpoint to wiretap to (resolved using simple language by default) 2552 * @param copy whether or not use a copy of the original exchange or a new empty exchange 2553 * @param body expression that creates the body to send 2554 * @return the builder 2555 * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0 2556 */ 2557 @Deprecated 2558 public WireTapDefinition<Type> wireTap(@AsEndpointUri String uri, boolean copy, Expression body) { 2559 WireTapDefinition answer = new WireTapDefinition(); 2560 answer.setUri(uri); 2561 answer.setCopy(copy); 2562 answer.setNewExchangeExpression(new ExpressionSubElementDefinition(body)); 2563 addOutput(answer); 2564 return answer; 2565 } 2566 2567 /** 2568 * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a> 2569 * Sends a new {@link org.apache.camel.Exchange} to the destination 2570 * using {@link ExchangePattern#InOnly}. 2571 * <p/> 2572 * Will use a copy of the original Exchange which is passed in as argument 2573 * to the given processor 2574 * 2575 * @param uri the dynamic endpoint to wiretap to (resolved using simple language by default) 2576 * @param processor processor preparing the new exchange to send 2577 * @return the builder 2578 * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0 2579 */ 2580 @Deprecated 2581 public WireTapDefinition<Type> wireTap(@AsEndpointUri String uri, Processor processor) { 2582 return wireTap(uri, true, processor); 2583 } 2584 2585 /** 2586 * <a href="http://camel.apache.org/wiretap.html">WireTap EIP:</a> 2587 * Sends a new {@link org.apache.camel.Exchange} to the destination 2588 * using {@link ExchangePattern#InOnly}. 2589 * 2590 * @param uri the dynamic endpoint to wiretap to (resolved using simple language by default) 2591 * @param copy whether or not use a copy of the original exchange or a new empty exchange 2592 * @param processor processor preparing the new exchange to send 2593 * @return the builder 2594 * @deprecated use the fluent builder from {@link WireTapDefinition}, will be removed in Camel 3.0 2595 */ 2596 @Deprecated 2597 public WireTapDefinition<Type> wireTap(@AsEndpointUri String uri, boolean copy, Processor processor) { 2598 WireTapDefinition answer = new WireTapDefinition(); 2599 answer.setUri(uri); 2600 answer.setCopy(copy); 2601 answer.setNewExchangeProcessor(processor); 2602 addOutput(answer); 2603 return answer; 2604 } 2605 2606 /** 2607 * Pushes the given block on the stack as current block 2608 * 2609 * @param block the block 2610 */ 2611 void pushBlock(Block block) { 2612 blocks.add(block); 2613 } 2614 2615 /** 2616 * Pops the block off the stack as current block 2617 * 2618 * @return the block 2619 */ 2620 Block popBlock() { 2621 return blocks.isEmpty() ? null : blocks.removeLast(); 2622 } 2623 2624 @SuppressWarnings("unchecked") 2625 public Type startupOrder(int startupOrder) { 2626 ProcessorDefinition<?> def = this; 2627 2628 RouteDefinition route = ProcessorDefinitionHelper.getRoute(def); 2629 if (route != null) { 2630 route.startupOrder(startupOrder); 2631 } 2632 2633 return (Type) this; 2634 } 2635 2636 /** 2637 * Stops continue routing the current {@link org.apache.camel.Exchange} and marks it as completed. 2638 * 2639 * @return the builder 2640 */ 2641 @SuppressWarnings("unchecked") 2642 public Type stop() { 2643 StopDefinition stop = new StopDefinition(); 2644 addOutput(stop); 2645 return (Type) this; 2646 } 2647 2648 /** 2649 * <a href="http://camel.apache.org/exception-clause.html">Exception clause</a> 2650 * for catching certain exceptions and handling them. 2651 * 2652 * @param exceptionType the exception to catch 2653 * @return the exception builder to configure 2654 */ 2655 public OnExceptionDefinition onException(Class<? extends Throwable> exceptionType) { 2656 OnExceptionDefinition answer = new OnExceptionDefinition(exceptionType); 2657 answer.setRouteScoped(true); 2658 addOutput(answer); 2659 return answer; 2660 } 2661 2662 /** 2663 * <a href="http://camel.apache.org/exception-clause.html">Exception clause</a> 2664 * for catching certain exceptions and handling them. 2665 * 2666 * @param exceptions list of exceptions to catch 2667 * @return the exception builder to configure 2668 */ 2669 public OnExceptionDefinition onException(Class<? extends Throwable>... exceptions) { 2670 OnExceptionDefinition answer = new OnExceptionDefinition(Arrays.asList(exceptions)); 2671 answer.setRouteScoped(true); 2672 addOutput(answer); 2673 return answer; 2674 } 2675 2676 /** 2677 * Apply a {@link Policy}. 2678 * <p/> 2679 * Policy can be used for transactional policies. 2680 * 2681 * @param policy the policy to apply 2682 * @return the policy builder to configure 2683 */ 2684 public PolicyDefinition policy(Policy policy) { 2685 PolicyDefinition answer = new PolicyDefinition(policy); 2686 addOutput(answer); 2687 return answer; 2688 } 2689 2690 /** 2691 * Apply a {@link Policy}. 2692 * <p/> 2693 * Policy can be used for transactional policies. 2694 * 2695 * @param ref reference to lookup a policy in the registry 2696 * @return the policy builder to configure 2697 */ 2698 public PolicyDefinition policy(String ref) { 2699 PolicyDefinition answer = new PolicyDefinition(); 2700 answer.setRef(ref); 2701 addOutput(answer); 2702 return answer; 2703 } 2704 2705 /** 2706 * Marks this route as transacted and uses the default transacted policy found in the registry. 2707 * 2708 * @return the policy builder to configure 2709 */ 2710 public TransactedDefinition transacted() { 2711 TransactedDefinition answer = new TransactedDefinition(); 2712 addOutput(answer); 2713 return answer; 2714 } 2715 2716 /** 2717 * Marks this route as transacted. 2718 * 2719 * @param ref reference to lookup a transacted policy in the registry 2720 * @return the policy builder to configure 2721 */ 2722 public TransactedDefinition transacted(String ref) { 2723 TransactedDefinition answer = new TransactedDefinition(); 2724 answer.setRef(ref); 2725 addOutput(answer); 2726 return answer; 2727 } 2728 2729 /** 2730 * Marks this route as participating to a saga. 2731 * 2732 * @return the saga definition 2733 */ 2734 public SagaDefinition saga() { 2735 SagaDefinition answer = new SagaDefinition(); 2736 addOutput(answer); 2737 return answer; 2738 } 2739 2740 // Transformers 2741 // ------------------------------------------------------------------------- 2742 2743 /** 2744 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2745 * Adds the custom processor to this destination which could be a final 2746 * destination, or could be a transformation in a pipeline 2747 * 2748 * @param processor the custom {@link Processor} 2749 * @return the builder 2750 */ 2751 @SuppressWarnings("unchecked") 2752 public Type process(Processor processor) { 2753 ProcessDefinition answer = new ProcessDefinition(processor); 2754 addOutput(answer); 2755 return (Type) this; 2756 } 2757 2758 /** 2759 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2760 * Adds the custom processor reference to this destination which could be a final 2761 * destination, or could be a transformation in a pipeline 2762 * 2763 * @param ref reference to a {@link Processor} to lookup in the registry 2764 * @return the builder 2765 */ 2766 @SuppressWarnings("unchecked") 2767 public Type process(String ref) { 2768 ProcessDefinition answer = new ProcessDefinition(); 2769 answer.setRef(ref); 2770 addOutput(answer); 2771 return (Type) this; 2772 } 2773 2774 /** 2775 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2776 * Adds the custom processor reference to this destination which could be a final 2777 * destination, or could be a transformation in a pipeline 2778 * 2779 * @param ref reference to a {@link Processor} to lookup in the registry 2780 * @return the builder 2781 * @deprecated use {@link #process(String)} 2782 */ 2783 @SuppressWarnings("unchecked") 2784 @Deprecated 2785 public Type processRef(String ref) { 2786 ProcessDefinition answer = new ProcessDefinition(); 2787 answer.setRef(ref); 2788 addOutput(answer); 2789 return (Type) this; 2790 } 2791 2792 /** 2793 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2794 * Adds the custom processor using a fluent builder to this destination which could be a final 2795 * destination, or could be a transformation in a pipeline 2796 * 2797 * @return the builder 2798 */ 2799 public ProcessClause<ProcessorDefinition<Type>> process() { 2800 ProcessClause<ProcessorDefinition<Type>> clause = new ProcessClause<>(this); 2801 ProcessDefinition answer = new ProcessDefinition(clause); 2802 2803 addOutput(answer); 2804 return clause; 2805 } 2806 2807 /** 2808 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2809 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 2810 * 2811 * @param bean the bean to invoke, or a reference to a bean if the type is a String 2812 * @return the builder 2813 */ 2814 @SuppressWarnings("unchecked") 2815 public Type bean(Object bean) { 2816 BeanDefinition answer = new BeanDefinition(); 2817 if (bean instanceof String) { 2818 answer.setRef((String) bean); 2819 } else { 2820 answer.setBean(bean); 2821 } 2822 addOutput(answer); 2823 return (Type) this; 2824 } 2825 2826 /** 2827 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2828 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 2829 * 2830 * @param bean the bean to invoke, or a reference to a bean if the type is a String 2831 * @param method the method name to invoke on the bean (can be used to avoid ambiguity) 2832 * @return the builder 2833 */ 2834 @SuppressWarnings("unchecked") 2835 public Type bean(Object bean, String method) { 2836 BeanDefinition answer = new BeanDefinition(); 2837 if (bean instanceof String) { 2838 answer.setRef((String) bean); 2839 } else { 2840 answer.setBean(bean); 2841 } 2842 answer.setMethod(method); 2843 addOutput(answer); 2844 return (Type) this; 2845 } 2846 2847 /** 2848 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2849 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 2850 * 2851 * @param bean the bean to invoke, or a reference to a bean if the type is a String 2852 * @param cache if enabled, Camel will cache the result of the first Registry look-up. 2853 * Cache can be enabled if the bean in the Registry is defined as a singleton scope. 2854 * the multi parameter 2855 * @return the builder 2856 */ 2857 @SuppressWarnings("unchecked") 2858 public Type bean(Object bean, boolean cache) { 2859 BeanDefinition answer = new BeanDefinition(); 2860 if (bean instanceof String) { 2861 answer.setRef((String) bean); 2862 } else { 2863 answer.setBean(bean); 2864 } 2865 answer.setCache(cache); 2866 addOutput(answer); 2867 return (Type) this; 2868 } 2869 2870 /** 2871 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2872 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 2873 * 2874 * @param bean the bean to invoke, or a reference to a bean if the type is a String 2875 * @param method the method name to invoke on the bean (can be used to avoid ambiguity) 2876 * @param cache if enabled, Camel will cache the result of the first Registry look-up. 2877 * Cache can be enabled if the bean in the Registry is defined as a singleton scope. 2878 * the multi parameter 2879 * @return the builder 2880 */ 2881 @SuppressWarnings("unchecked") 2882 public Type bean(Object bean, String method, boolean cache) { 2883 BeanDefinition answer = new BeanDefinition(); 2884 if (bean instanceof String) { 2885 answer.setRef((String) bean); 2886 } else { 2887 answer.setBean(bean); 2888 } 2889 answer.setMethod(method); 2890 answer.setCache(cache); 2891 addOutput(answer); 2892 return (Type) this; 2893 } 2894 2895 /** 2896 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2897 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 2898 * 2899 * @param beanType the bean class, Camel will instantiate an object at runtime 2900 * @return the builder 2901 */ 2902 @SuppressWarnings("unchecked") 2903 public Type bean(Class<?> beanType) { 2904 BeanDefinition answer = new BeanDefinition(); 2905 answer.setBeanType(beanType); 2906 addOutput(answer); 2907 return (Type) this; 2908 } 2909 2910 /** 2911 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2912 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 2913 * 2914 * @param beanType the bean class, Camel will instantiate an object at runtime 2915 * @param method the method name to invoke on the bean (can be used to avoid ambiguity) 2916 * @return the builder 2917 */ 2918 @SuppressWarnings("unchecked") 2919 public Type bean(Class<?> beanType, String method) { 2920 BeanDefinition answer = new BeanDefinition(); 2921 answer.setBeanType(beanType); 2922 answer.setMethod(method); 2923 addOutput(answer); 2924 return (Type) this; 2925 } 2926 2927 /** 2928 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2929 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 2930 * 2931 * @param beanType the bean class, Camel will instantiate an object at runtime 2932 * @param method the method name to invoke on the bean (can be used to avoid ambiguity) 2933 * @param multiParameterArray if it is true, camel will treat the message body as an object array which holds 2934 * the multi parameter 2935 * @return the builder 2936 * @deprecated the option multiParameterArray is deprecated 2937 */ 2938 @SuppressWarnings("unchecked") 2939 @Deprecated 2940 public Type bean(Class<?> beanType, String method, boolean multiParameterArray) { 2941 BeanDefinition answer = new BeanDefinition(); 2942 answer.setBeanType(beanType); 2943 answer.setMethod(method); 2944 answer.setMultiParameterArray(multiParameterArray); 2945 addOutput(answer); 2946 return (Type) this; 2947 } 2948 2949 /** 2950 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2951 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 2952 * 2953 * @param beanType the bean class, Camel will instantiate an object at runtime 2954 * @param method the method name to invoke on the bean (can be used to avoid ambiguity) 2955 * @param multiParameterArray if it is true, camel will treat the message body as an object array which holds 2956 * the multi parameter 2957 * @param cache if enabled, Camel will cache the result of the first Registry look-up. 2958 * Cache can be enabled if the bean in the Registry is defined as a singleton scope. 2959 * @return the builder 2960 * @deprecated the option multiParameterArray is deprecated 2961 */ 2962 @SuppressWarnings("unchecked") 2963 @Deprecated 2964 public Type bean(Class<?> beanType, String method, boolean multiParameterArray, boolean cache) { 2965 BeanDefinition answer = new BeanDefinition(); 2966 answer.setBeanType(beanType); 2967 answer.setMethod(method); 2968 answer.setMultiParameterArray(multiParameterArray); 2969 answer.setCache(cache); 2970 addOutput(answer); 2971 return (Type) this; 2972 } 2973 2974 /** 2975 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2976 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 2977 * 2978 * @param ref reference to a bean to lookup in the registry 2979 * @return the builder 2980 * @deprecated use {@link #bean(Object)} 2981 */ 2982 @SuppressWarnings("unchecked") 2983 @Deprecated 2984 public Type beanRef(String ref) { 2985 BeanDefinition answer = new BeanDefinition(ref); 2986 addOutput(answer); 2987 return (Type) this; 2988 } 2989 2990 /** 2991 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 2992 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 2993 * 2994 * @param ref reference to a bean to lookup in the registry 2995 * @param method the method name to invoke on the bean (can be used to avoid ambiguity) 2996 * @return the builder 2997 * @deprecated use {@link #bean(Object, String)} 2998 */ 2999 @SuppressWarnings("unchecked") 3000 @Deprecated 3001 public Type beanRef(String ref, String method) { 3002 BeanDefinition answer = new BeanDefinition(ref, method); 3003 addOutput(answer); 3004 return (Type) this; 3005 } 3006 3007 /** 3008 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 3009 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 3010 * 3011 * @param ref reference to a bean to lookup in the registry 3012 * @param cache if enabled, Camel will cache the result of the first Registry look-up. 3013 * Cache can be enabled if the bean in the Registry is defined as a singleton scope. 3014 * @return the builder 3015 * @deprecated use {@link #bean(Object, String, boolean)} 3016 */ 3017 @SuppressWarnings("unchecked") 3018 @Deprecated 3019 public Type beanRef(String ref, boolean cache) { 3020 BeanDefinition answer = new BeanDefinition(ref); 3021 answer.setCache(cache); 3022 addOutput(answer); 3023 return (Type) this; 3024 } 3025 3026 /** 3027 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 3028 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 3029 * 3030 * @param ref reference to a bean to lookup in the registry 3031 * @param method the method name to invoke on the bean (can be used to avoid ambiguity) 3032 * @param cache if enabled, Camel will cache the result of the first Registry look-up. 3033 * Cache can be enabled if the bean in the Registry is defined as a singleton scope. 3034 * @return the builder 3035 * @deprecated use {@link #bean(Object, String, boolean)} 3036 */ 3037 @SuppressWarnings("unchecked") 3038 @Deprecated 3039 public Type beanRef(String ref, String method, boolean cache) { 3040 BeanDefinition answer = new BeanDefinition(ref, method); 3041 answer.setCache(cache); 3042 addOutput(answer); 3043 return (Type) this; 3044 } 3045 3046 /** 3047 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 3048 * Adds a bean which is invoked which could be a final destination, or could be a transformation in a pipeline 3049 * 3050 * @param ref reference to a bean to lookup in the registry 3051 * @param method the method name to invoke on the bean (can be used to avoid ambiguity) 3052 * @param cache if enabled, Camel will cache the result of the first Registry look-up. 3053 * Cache can be enabled if the bean in the Registry is defined as a singleton scope. 3054 * @param multiParameterArray if it is true, camel will treat the message body as an object array which holds 3055 * the multi parameter 3056 * @return the builder 3057 * @deprecated the option multiParameterArray is deprecated 3058 */ 3059 @SuppressWarnings("unchecked") 3060 @Deprecated 3061 public Type beanRef(String ref, String method, boolean cache, boolean multiParameterArray) { 3062 BeanDefinition answer = new BeanDefinition(ref, method); 3063 answer.setCache(cache); 3064 answer.setMultiParameterArray(multiParameterArray); 3065 addOutput(answer); 3066 return (Type) this; 3067 } 3068 3069 /** 3070 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 3071 * Adds a processor which sets the body on the IN message 3072 * 3073 * @return a expression builder clause to set the body 3074 */ 3075 public ExpressionClause<ProcessorDefinition<Type>> setBody() { 3076 ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this); 3077 SetBodyDefinition answer = new SetBodyDefinition(clause); 3078 addOutput(answer); 3079 return clause; 3080 } 3081 3082 /** 3083 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 3084 * Adds a processor which sets the body on the IN message 3085 * 3086 * @param expression the expression used to set the body 3087 * @return the builder 3088 */ 3089 @SuppressWarnings("unchecked") 3090 public Type setBody(Expression expression) { 3091 SetBodyDefinition answer = new SetBodyDefinition(expression); 3092 addOutput(answer); 3093 return (Type) this; 3094 } 3095 3096 /** 3097 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 3098 * Adds a processor which sets the body on the IN message 3099 * 3100 * @param supplier the supplier that provides a value to the IN message body 3101 * @return the builder 3102 */ 3103 public <Result> Type setBody(Supplier<Result> supplier) { 3104 SetBodyDefinition answer = new SetBodyDefinition(new ExpressionAdapter() { 3105 @Override 3106 public Result evaluate(Exchange exchange) { 3107 return supplier.get(); 3108 } 3109 }); 3110 addOutput(answer); 3111 return (Type) this; 3112 } 3113 3114 /** 3115 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 3116 * Adds a processor which sets the body on the IN message 3117 * 3118 * @param function the function that provides a value to the IN message body 3119 * @return the builder 3120 */ 3121 public <Result> Type setBody(Function<Exchange, Result> function) { 3122 SetBodyDefinition answer = new SetBodyDefinition(new ExpressionAdapter() { 3123 @Override 3124 public Result evaluate(Exchange exchange) { 3125 return function.apply(exchange); 3126 } 3127 }); 3128 addOutput(answer); 3129 return (Type) this; 3130 } 3131 3132 /** 3133 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 3134 * Adds a processor which sets the body on the OUT message 3135 * 3136 * @param expression the expression used to set the body 3137 * @return the builder 3138 */ 3139 @SuppressWarnings("unchecked") 3140 public Type transform(Expression expression) { 3141 TransformDefinition answer = new TransformDefinition(expression); 3142 addOutput(answer); 3143 return (Type) this; 3144 } 3145 3146 /** 3147 * <a href="http://camel.apache.org/message-translator.html">Message Translator EIP:</a> 3148 * Adds a processor which sets the body on the OUT message 3149 * 3150 * @return a expression builder clause to set the body 3151 */ 3152 public ExpressionClause<ProcessorDefinition<Type>> transform() { 3153 ExpressionClause<ProcessorDefinition<Type>> clause = 3154 new ExpressionClause<ProcessorDefinition<Type>>((ProcessorDefinition<Type>) this); 3155 TransformDefinition answer = new TransformDefinition(clause); 3156 addOutput(answer); 3157 return clause; 3158 } 3159 3160 /** 3161 * Executes a script (do not change the message body). 3162 * 3163 * @param expression the expression used as the script. 3164 * @return the builder 3165 */ 3166 @SuppressWarnings("unchecked") 3167 public Type script(Expression expression) { 3168 ScriptDefinition answer = new ScriptDefinition(expression); 3169 addOutput(answer); 3170 return (Type) this; 3171 } 3172 3173 /** 3174 * Executes a script (do not change the message body). 3175 * 3176 * @return a expression builder clause to use as script. 3177 */ 3178 public ExpressionClause<ProcessorDefinition<Type>> script() { 3179 ExpressionClause<ProcessorDefinition<Type>> clause = 3180 new ExpressionClause<ProcessorDefinition<Type>>((ProcessorDefinition<Type>) this); 3181 ScriptDefinition answer = new ScriptDefinition(clause); 3182 addOutput(answer); 3183 return clause; 3184 } 3185 3186 /** 3187 * Adds a processor which sets the body on the FAULT message 3188 * 3189 * @param expression the expression used to set the body 3190 * @return the builder 3191 */ 3192 public Type setFaultBody(Expression expression) { 3193 return process(ProcessorBuilder.setFaultBody(expression)); 3194 } 3195 3196 /** 3197 * Adds a processor which sets the header on the IN message 3198 * 3199 * @param name the header name 3200 * @return a expression builder clause to set the header 3201 */ 3202 public ExpressionClause<ProcessorDefinition<Type>> setHeader(String name) { 3203 ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this); 3204 SetHeaderDefinition answer = new SetHeaderDefinition(name, clause); 3205 addOutput(answer); 3206 return clause; 3207 } 3208 3209 /** 3210 * Adds a processor which sets the header on the IN message 3211 * 3212 * @param name the header name 3213 * @param expression the expression used to set the header 3214 * @return the builder 3215 */ 3216 @SuppressWarnings("unchecked") 3217 public Type setHeader(String name, Expression expression) { 3218 SetHeaderDefinition answer = new SetHeaderDefinition(name, expression); 3219 addOutput(answer); 3220 return (Type) this; 3221 } 3222 3223 /** 3224 * Adds a processor which sets the header on the IN message 3225 * 3226 * @param name the header name 3227 * @param supplier the supplier used to set the header 3228 * @return the builder 3229 */ 3230 @SuppressWarnings("unchecked") 3231 public Type setHeader(String name, final Supplier<Object> supplier) { 3232 SetHeaderDefinition answer = new SetHeaderDefinition(name, new ExpressionAdapter() { 3233 @Override 3234 public Object evaluate(Exchange exchange) { 3235 return supplier.get(); 3236 } 3237 }); 3238 3239 addOutput(answer); 3240 return (Type) this; 3241 } 3242 3243 /** 3244 * Adds a processor which sets the header on the OUT message 3245 * 3246 * @param name the header name 3247 * @return a expression builder clause to set the header 3248 * @deprecated use {@link #setHeader(String)} 3249 */ 3250 @Deprecated 3251 public ExpressionClause<ProcessorDefinition<Type>> setOutHeader(String name) { 3252 ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this); 3253 SetOutHeaderDefinition answer = new SetOutHeaderDefinition(name, clause); 3254 addOutput(answer); 3255 return clause; 3256 } 3257 3258 /** 3259 * Adds a processor which sets the header on the OUT message 3260 * 3261 * @param name the header name 3262 * @param expression the expression used to set the header 3263 * @return the builder 3264 * @deprecated use {@link #setHeader(String, org.apache.camel.Expression)} 3265 */ 3266 @SuppressWarnings("unchecked") 3267 @Deprecated 3268 public Type setOutHeader(String name, Expression expression) { 3269 SetOutHeaderDefinition answer = new SetOutHeaderDefinition(name, expression); 3270 addOutput(answer); 3271 return (Type) this; 3272 } 3273 3274 /** 3275 * Adds a processor which sets the header on the FAULT message 3276 * 3277 * @param name the header name 3278 * @param expression the expression used to set the header 3279 * @return the builder 3280 * @deprecated use {@link #setHeader(String, org.apache.camel.Expression)} 3281 */ 3282 @Deprecated 3283 public Type setFaultHeader(String name, Expression expression) { 3284 return process(ProcessorBuilder.setFaultHeader(name, expression)); 3285 } 3286 3287 /** 3288 * Adds a processor which sets the exchange property 3289 * 3290 * @param name the property name 3291 * @param expression the expression used to set the property 3292 * @return the builder 3293 */ 3294 @SuppressWarnings("unchecked") 3295 public Type setProperty(String name, Expression expression) { 3296 SetPropertyDefinition answer = new SetPropertyDefinition(name, expression); 3297 addOutput(answer); 3298 return (Type) this; 3299 } 3300 3301 /** 3302 * Adds a processor which sets the exchange property 3303 * 3304 * @param name the property name 3305 * @return a expression builder clause to set the property 3306 */ 3307 public ExpressionClause<ProcessorDefinition<Type>> setProperty(String name) { 3308 ExpressionClause<ProcessorDefinition<Type>> clause = new ExpressionClause<ProcessorDefinition<Type>>(this); 3309 SetPropertyDefinition answer = new SetPropertyDefinition(name, clause); 3310 addOutput(answer); 3311 return clause; 3312 } 3313 3314 /** 3315 * Adds a processor which removes the header on the IN message 3316 * 3317 * @param name the header name 3318 * @return the builder 3319 */ 3320 @SuppressWarnings("unchecked") 3321 public Type removeHeader(String name) { 3322 RemoveHeaderDefinition answer = new RemoveHeaderDefinition(name); 3323 addOutput(answer); 3324 return (Type) this; 3325 } 3326 3327 /** 3328 * Adds a processor which removes the headers on the IN message 3329 * 3330 * @param pattern a pattern to match header names to be removed 3331 * @return the builder 3332 */ 3333 @SuppressWarnings("unchecked") 3334 public Type removeHeaders(String pattern) { 3335 RemoveHeadersDefinition answer = new RemoveHeadersDefinition(pattern); 3336 addOutput(answer); 3337 return (Type) this; 3338 } 3339 3340 /** 3341 * Adds a processor which removes the headers on the IN message 3342 * 3343 * @param pattern a pattern to match header names to be removed 3344 * @param excludePatterns one or more pattern of header names that should be excluded (= preserved) 3345 * @return the builder 3346 */ 3347 @SuppressWarnings("unchecked") 3348 public Type removeHeaders(String pattern, String... excludePatterns) { 3349 RemoveHeadersDefinition answer = new RemoveHeadersDefinition(pattern, excludePatterns); 3350 addOutput(answer); 3351 return (Type) this; 3352 } 3353 3354 /** 3355 * Adds a processor which removes the header on the FAULT message 3356 * 3357 * @param name the header name 3358 * @return the builder 3359 * @deprecated will be removed in the near future. Instead use {@link #removeHeader(String)} 3360 */ 3361 @Deprecated 3362 public Type removeFaultHeader(String name) { 3363 return process(ProcessorBuilder.removeFaultHeader(name)); 3364 } 3365 3366 /** 3367 * Adds a processor which removes the exchange property 3368 * 3369 * @param name the property name 3370 * @return the builder 3371 */ 3372 @SuppressWarnings("unchecked") 3373 public Type removeProperty(String name) { 3374 RemovePropertyDefinition answer = new RemovePropertyDefinition(name); 3375 addOutput(answer); 3376 return (Type) this; 3377 } 3378 3379 /** 3380 * Adds a processor which removes the properties in the exchange 3381 * 3382 * @param pattern a pattern to match properties names to be removed 3383 * @return the builder 3384 */ 3385 @SuppressWarnings("unchecked") 3386 public Type removeProperties(String pattern) { 3387 RemovePropertiesDefinition answer = new RemovePropertiesDefinition(pattern); 3388 addOutput(answer); 3389 return (Type) this; 3390 } 3391 3392 /** 3393 * Adds a processor which removes the properties in the exchange 3394 * 3395 * @param pattern a pattern to match properties names to be removed 3396 * @param excludePatterns one or more pattern of properties names that should be excluded (= preserved) 3397 * @return the builder 3398 */ 3399 @SuppressWarnings("unchecked") 3400 public Type removeProperties(String pattern, String... excludePatterns) { 3401 RemovePropertiesDefinition answer = new RemovePropertiesDefinition(pattern, excludePatterns); 3402 addOutput(answer); 3403 return (Type) this; 3404 } 3405 3406 /** 3407 * Converts the IN message body to the specified type 3408 * 3409 * @param type the type to convert to 3410 * @return the builder 3411 */ 3412 @SuppressWarnings("unchecked") 3413 public Type convertBodyTo(Class<?> type) { 3414 addOutput(new ConvertBodyDefinition(type)); 3415 return (Type) this; 3416 } 3417 3418 /** 3419 * Converts the IN message body to the specified type 3420 * 3421 * @param type the type to convert to 3422 * @param charset the charset to use by type converters (not all converters support specifc charset) 3423 * @return the builder 3424 */ 3425 @SuppressWarnings("unchecked") 3426 public Type convertBodyTo(Class<?> type, String charset) { 3427 addOutput(new ConvertBodyDefinition(type, charset)); 3428 return (Type) this; 3429 } 3430 3431 /** 3432 * Sorts the expression using a default sorting based on toString representation. 3433 * 3434 * @param expression the expression, must be convertable to {@link List} 3435 * @return the builder 3436 */ 3437 public Type sort(Expression expression) { 3438 return sort(expression, null); 3439 } 3440 3441 /** 3442 * Sorts the expression using the given comparator 3443 * 3444 * @param expression the expression, must be convertable to {@link List} 3445 * @param comparator the comparator to use for sorting 3446 * @return the builder 3447 */ 3448 @SuppressWarnings("unchecked") 3449 public <T> Type sort(Expression expression, Comparator<T> comparator) { 3450 addOutput(new SortDefinition<T>(expression, comparator)); 3451 return (Type) this; 3452 } 3453 3454 /** 3455 * Sorts the expression 3456 * 3457 * @return the builder 3458 */ 3459 public <T> ExpressionClause<SortDefinition<T>> sort() { 3460 SortDefinition<T> answer = new SortDefinition<T>(); 3461 addOutput(answer); 3462 return ExpressionClause.createAndSetExpression(answer); 3463 } 3464 3465 /** 3466 * The <a href="http://camel.apache.org/claim-check.html">Claim Check EIP</a> 3467 * allows you to replace message content with a claim check (a unique key), 3468 * which can be used to retrieve the message content at a later time. 3469 */ 3470 public ClaimCheckDefinition claimCheck() { 3471 ClaimCheckDefinition answer = new ClaimCheckDefinition(); 3472 addOutput(answer); 3473 return answer; 3474 } 3475 3476 /** 3477 * The <a href="http://camel.apache.org/claim-check.html">Claim Check EIP</a> 3478 * allows you to replace message content with a claim check (a unique key), 3479 * which can be used to retrieve the message content at a later time. 3480 * 3481 * @param operation the claim check operation to use. 3482 */ 3483 public Type claimCheck(ClaimCheckOperation operation) { 3484 ClaimCheckDefinition answer = new ClaimCheckDefinition(); 3485 answer.setOperation(operation); 3486 addOutput(answer); 3487 return (Type) this; 3488 } 3489 3490 /** 3491 * The <a href="http://camel.apache.org/claim-check.html">Claim Check EIP</a> 3492 * allows you to replace message content with a claim check (a unique key), 3493 * which can be used to retrieve the message content at a later time. 3494 * 3495 * @param operation the claim check operation to use. 3496 * @param key the unique key to use for the get and set operations, can be <tt>null</tt> for push/pop operations 3497 */ 3498 public Type claimCheck(ClaimCheckOperation operation, String key) { 3499 return claimCheck(operation, key, null); 3500 } 3501 3502 /** 3503 * The <a href="http://camel.apache.org/claim-check.html">Claim Check EIP</a> 3504 * allows you to replace message content with a claim check (a unique key), 3505 * which can be used to retrieve the message content at a later time. 3506 * 3507 * @param operation the claim check operation to use. 3508 * @param key the unique key to use for the get and set operations, can be <tt>null</tt> for push/pop operations 3509 * @param filter describes what data to include/exclude when merging data back when using get or pop operations. 3510 */ 3511 public Type claimCheck(ClaimCheckOperation operation, String key, String filter) { 3512 ClaimCheckDefinition answer = new ClaimCheckDefinition(); 3513 answer.setOperation(operation); 3514 answer.setKey(key); 3515 answer.setFilter(filter); 3516 addOutput(answer); 3517 return (Type) this; 3518 } 3519 3520 /** 3521 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3522 * enriches an exchange with additional data obtained from a <code>resourceUri</code>. 3523 * <p/> 3524 * The difference between this and {@link #pollEnrich(String)} is that this uses a producer 3525 * to obatin the additional data, where as pollEnrich uses a polling consumer. 3526 * 3527 * @param resourceUri URI of resource endpoint for obtaining additional data. 3528 * @return the builder 3529 * @see org.apache.camel.processor.Enricher 3530 */ 3531 public Type enrich(@AsEndpointUri String resourceUri) { 3532 return enrich(resourceUri, null); 3533 } 3534 3535 /** 3536 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3537 * enriches an exchange with additional data obtained from a <code>resourceUri</code>. 3538 * 3539 * @param resourceUri URI of resource endpoint for obtaining additional data. 3540 * @param aggregationStrategy aggregation strategy to aggregate input data and additional data. 3541 * @return the builder 3542 * @see org.apache.camel.processor.Enricher 3543 */ 3544 public Type enrich(@AsEndpointUri String resourceUri, AggregationStrategy aggregationStrategy) { 3545 return enrich(resourceUri, aggregationStrategy, false); 3546 } 3547 3548 /** 3549 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3550 * enriches an exchange with additional data obtained from a <code>resourceUri</code> and 3551 * with an aggregation strategy created using a fluent builder. 3552 * 3553 * <blockquote><pre>{@code 3554 * fom("direct:start") 3555 * .enrichWith("direct:resource") 3556 * .body(String.class, (o, n) -> n + o); 3557 * }</pre></blockquote> 3558 * 3559 * @param resourceUri URI of resource endpoint for obtaining additional data. 3560 * @return the builder 3561 * @see org.apache.camel.processor.Enricher 3562 */ 3563 public EnrichClause<ProcessorDefinition<Type>> enrichWith(@AsEndpointUri String resourceUri) { 3564 EnrichClause<ProcessorDefinition<Type>> clause = new EnrichClause<>(this); 3565 enrich(resourceUri, clause); 3566 return clause; 3567 } 3568 3569 /** 3570 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3571 * enriches an exchange with additional data obtained from a <code>resourceUri</code> and 3572 * with an aggregation strategy created using a fluent builder. 3573 */ 3574 public EnrichClause<ProcessorDefinition<Type>> enrichWith(@AsEndpointUri String resourceUri, boolean aggregateOnException) { 3575 EnrichClause<ProcessorDefinition<Type>> clause = new EnrichClause<>(this); 3576 enrich(resourceUri, clause, aggregateOnException, false); 3577 return clause; 3578 } 3579 3580 /** 3581 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3582 * enriches an exchange with additional data obtained from a <code>resourceUri</code> and 3583 * with an aggregation strategy created using a fluent builder. 3584 */ 3585 public EnrichClause<ProcessorDefinition<Type>> enrichWith(@AsEndpointUri String resourceUri, boolean aggregateOnException, boolean shareUnitOfWork) { 3586 EnrichClause<ProcessorDefinition<Type>> clause = new EnrichClause<>(this); 3587 enrich(resourceUri, clause, aggregateOnException, shareUnitOfWork); 3588 return clause; 3589 } 3590 3591 /** 3592 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3593 * enriches an exchange with additional data obtained from a <code>resourceUri</code>. 3594 * 3595 * @param resourceUri URI of resource endpoint for obtaining additional data. 3596 * @param aggregationStrategy aggregation strategy to aggregate input data and additional data. 3597 * @param aggregateOnException whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if 3598 * an exception was thrown. 3599 * @return the builder 3600 * @see org.apache.camel.processor.Enricher 3601 */ 3602 public Type enrich(@AsEndpointUri String resourceUri, AggregationStrategy aggregationStrategy, boolean aggregateOnException) { 3603 return enrich(resourceUri, aggregationStrategy, aggregateOnException, false); 3604 } 3605 3606 /** 3607 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3608 * enriches an exchange with additional data obtained from a <code>resourceUri</code>. 3609 * 3610 * @param resourceUri URI of resource endpoint for obtaining additional data. 3611 * @param aggregationStrategy aggregation strategy to aggregate input data and additional data. 3612 * @param aggregateOnException whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if 3613 * an exception was thrown. 3614 * @param shareUnitOfWork whether to share unit of work 3615 * @return the builder 3616 * @see org.apache.camel.processor.Enricher 3617 */ 3618 @SuppressWarnings("unchecked") 3619 public Type enrich(@AsEndpointUri String resourceUri, AggregationStrategy aggregationStrategy, boolean aggregateOnException, boolean shareUnitOfWork) { 3620 EnrichDefinition answer = new EnrichDefinition(); 3621 answer.setExpression(new ConstantExpression(resourceUri)); 3622 answer.setAggregationStrategy(aggregationStrategy); 3623 answer.setAggregateOnException(aggregateOnException); 3624 answer.setShareUnitOfWork(shareUnitOfWork); 3625 addOutput(answer); 3626 return (Type) this; 3627 } 3628 3629 /** 3630 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3631 * enriches an exchange with additional data obtained from a <code>resourceUri</code>. 3632 * <p/> 3633 * The difference between this and {@link #pollEnrich(String)} is that this uses a producer 3634 * to obtain the additional data, where as pollEnrich uses a polling consumer. 3635 * 3636 * @param resourceRef Reference of resource endpoint for obtaining additional data. 3637 * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data. 3638 * @return the builder 3639 * @see org.apache.camel.processor.Enricher 3640 * @deprecated use enrich with a <tt>ref:id</tt> as the resourceUri parameter. 3641 */ 3642 @Deprecated 3643 public Type enrichRef(String resourceRef, String aggregationStrategyRef) { 3644 return enrichRef(resourceRef, aggregationStrategyRef, false); 3645 } 3646 3647 /** 3648 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3649 * enriches an exchange with additional data obtained from a <code>resourceUri</code>. 3650 * <p/> 3651 * The difference between this and {@link #pollEnrich(String)} is that this uses a producer 3652 * to obtain the additional data, where as pollEnrich uses a polling consumer. 3653 * 3654 * @param resourceRef Reference of resource endpoint for obtaining additional data. 3655 * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data. 3656 * @param aggregateOnException whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if 3657 * an exception was thrown. 3658 * @return the builder 3659 * @see org.apache.camel.processor.Enricher 3660 * @deprecated use enrich with a <tt>ref:id</tt> as the resourceUri parameter. 3661 */ 3662 @Deprecated 3663 public Type enrichRef(String resourceRef, String aggregationStrategyRef, boolean aggregateOnException) { 3664 return enrichRef(resourceRef, aggregationStrategyRef, false, false); 3665 } 3666 3667 /** 3668 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3669 * enriches an exchange with additional data obtained from a <code>resourceUri</code>. 3670 * <p/> 3671 * The difference between this and {@link #pollEnrich(String)} is that this uses a producer 3672 * to obtain the additional data, where as pollEnrich uses a polling consumer. 3673 * 3674 * @param resourceRef Reference of resource endpoint for obtaining additional data. 3675 * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data. 3676 * @param aggregateOnException whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if 3677 * an exception was thrown. 3678 * @param shareUnitOfWork whether to share unit of work 3679 * @return the builder 3680 * @see org.apache.camel.processor.Enricher 3681 * @deprecated use enrich with a <tt>ref:id</tt> as the resourceUri parameter. 3682 */ 3683 @Deprecated 3684 @SuppressWarnings("unchecked") 3685 public Type enrichRef(String resourceRef, String aggregationStrategyRef, boolean aggregateOnException, boolean shareUnitOfWork) { 3686 EnrichDefinition answer = new EnrichDefinition(); 3687 answer.setExpression(new SimpleExpression("ref:" + resourceRef)); 3688 answer.setAggregationStrategyRef(aggregationStrategyRef); 3689 answer.setAggregateOnException(aggregateOnException); 3690 answer.setShareUnitOfWork(shareUnitOfWork); 3691 addOutput(answer); 3692 return (Type) this; 3693 } 3694 3695 /** 3696 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3697 * enriches an exchange with additional data obtained from a <code>resourceUri</code>. 3698 * <p/> 3699 * The difference between this and {@link #pollEnrich(String)} is that this uses a producer 3700 * to obtain the additional data, where as pollEnrich uses a polling consumer. 3701 * 3702 * @return a expression builder clause to set the expression to use for computing the endpoint to use 3703 * @see org.apache.camel.processor.PollEnricher 3704 */ 3705 @AsEndpointUri 3706 public ExpressionClause<EnrichDefinition> enrich() { 3707 EnrichDefinition answer = new EnrichDefinition(); 3708 addOutput(answer); 3709 return ExpressionClause.createAndSetExpression(answer); 3710 } 3711 3712 /** 3713 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3714 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3715 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3716 * <p/> 3717 * The difference between this and {@link #enrich(String)} is that this uses a consumer 3718 * to obtain the additional data, where as enrich uses a producer. 3719 * <p/> 3720 * This method will <tt>block</tt> until data is available, use the method with timeout if you do not 3721 * want to risk waiting a long time before data is available from the resourceUri. 3722 * 3723 * @param resourceUri URI of resource endpoint for obtaining additional data. 3724 * @return the builder 3725 * @see org.apache.camel.processor.PollEnricher 3726 */ 3727 public Type pollEnrich(@AsEndpointUri String resourceUri) { 3728 return pollEnrich(resourceUri, null); 3729 } 3730 3731 /** 3732 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3733 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3734 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3735 * <p/> 3736 * The difference between this and {@link #enrich(String)} is that this uses a consumer 3737 * to obtain the additional data, where as enrich uses a producer. 3738 * <p/> 3739 * This method will <b>block</b> until data is available, use the method with timeout if you do not 3740 * want to risk waiting a long time before data is available from the resourceUri. 3741 * 3742 * @param resourceUri URI of resource endpoint for obtaining additional data. 3743 * @param aggregationStrategy aggregation strategy to aggregate input data and additional data. 3744 * @return the builder 3745 * @see org.apache.camel.processor.PollEnricher 3746 */ 3747 public Type pollEnrich(@AsEndpointUri String resourceUri, AggregationStrategy aggregationStrategy) { 3748 return pollEnrich(resourceUri, -1, aggregationStrategy); 3749 } 3750 3751 /** 3752 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3753 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3754 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3755 * <p/> 3756 * The difference between this and {@link #enrich(String)} is that this uses a consumer 3757 * to obtain the additional data, where as enrich uses a producer. 3758 * <p/> 3759 * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}. 3760 * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt> 3761 * otherwise we use <tt>receive(timeout)</tt>. 3762 * 3763 * @param resourceUri URI of resource endpoint for obtaining additional data. 3764 * @param timeout timeout in millis to wait at most for data to be available. 3765 * @param aggregationStrategy aggregation strategy to aggregate input data and additional data. 3766 * @return the builder 3767 * @see org.apache.camel.processor.PollEnricher 3768 */ 3769 public Type pollEnrich(@AsEndpointUri String resourceUri, long timeout, AggregationStrategy aggregationStrategy) { 3770 return pollEnrich(resourceUri, timeout, aggregationStrategy, false); 3771 } 3772 3773 /** 3774 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3775 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3776 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3777 * <p/> 3778 * The difference between this and {@link #enrich(String)} is that this uses a consumer 3779 * to obtain the additional data, where as enrich uses a producer. 3780 * <p/> 3781 * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}. 3782 * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt> 3783 * otherwise we use <tt>receive(timeout)</tt>. 3784 * 3785 * @param resourceUri URI of resource endpoint for obtaining additional data. 3786 * @param timeout timeout in millis to wait at most for data to be available. 3787 * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data. 3788 * @return the builder 3789 * @see org.apache.camel.processor.PollEnricher 3790 */ 3791 public Type pollEnrich(@AsEndpointUri String resourceUri, long timeout, String aggregationStrategyRef) { 3792 return pollEnrich(resourceUri, timeout, aggregationStrategyRef, false); 3793 } 3794 3795 /** 3796 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3797 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3798 * and with an aggregation strategy created using a fluent builder using 3799 * a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3800 */ 3801 public EnrichClause<ProcessorDefinition<Type>> pollEnrichWith(@AsEndpointUri String resourceUri) { 3802 EnrichClause<ProcessorDefinition<Type>> clause = new EnrichClause<>(this); 3803 pollEnrich(resourceUri, -1, clause, false); 3804 return clause; 3805 } 3806 3807 /** 3808 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3809 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3810 * and with an aggregation strategy created using a fluent builder using 3811 * a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3812 */ 3813 public EnrichClause<ProcessorDefinition<Type>> pollEnrichWith(@AsEndpointUri String resourceUri, long timeout) { 3814 EnrichClause<ProcessorDefinition<Type>> clause = new EnrichClause<>(this); 3815 pollEnrich(resourceUri, timeout, clause, false); 3816 return clause; 3817 } 3818 3819 /** 3820 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3821 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3822 * and with an aggregation strategy created using a fluent builder using 3823 * a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3824 */ 3825 public EnrichClause<ProcessorDefinition<Type>> pollEnrichWith(@AsEndpointUri String resourceUri, long timeout, boolean aggregateOnException) { 3826 EnrichClause<ProcessorDefinition<Type>> clause = new EnrichClause<>(this); 3827 pollEnrich(resourceUri, timeout, clause, aggregateOnException); 3828 return clause; 3829 } 3830 3831 /** 3832 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3833 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3834 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3835 * <p/> 3836 * The difference between this and {@link #enrich(String)} is that this uses a consumer 3837 * to obtain the additional data, where as enrich uses a producer. 3838 * <p/> 3839 * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}. 3840 * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt> 3841 * otherwise we use <tt>receive(timeout)</tt>. 3842 * 3843 * @param resourceUri URI of resource endpoint for obtaining additional data. 3844 * @param timeout timeout in millis to wait at most for data to be available. 3845 * @param aggregationStrategy aggregation strategy to aggregate input data and additional data. 3846 * @param aggregateOnException whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if 3847 * an exception was thrown. 3848 * @return the builder 3849 * @see org.apache.camel.processor.PollEnricher 3850 */ 3851 @SuppressWarnings("unchecked") 3852 public Type pollEnrich(@AsEndpointUri String resourceUri, long timeout, AggregationStrategy aggregationStrategy, boolean aggregateOnException) { 3853 PollEnrichDefinition pollEnrich = new PollEnrichDefinition(); 3854 pollEnrich.setExpression(new ConstantExpression(resourceUri)); 3855 pollEnrich.setTimeout(timeout); 3856 pollEnrich.setAggregationStrategy(aggregationStrategy); 3857 pollEnrich.setAggregateOnException(aggregateOnException); 3858 addOutput(pollEnrich); 3859 return (Type) this; 3860 } 3861 3862 /** 3863 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3864 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3865 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3866 * <p/> 3867 * The difference between this and {@link #enrich(String)} is that this uses a consumer 3868 * to obtain the additional data, where as enrich uses a producer. 3869 * <p/> 3870 * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}. 3871 * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt> 3872 * otherwise we use <tt>receive(timeout)</tt>. 3873 * 3874 * @param resourceUri URI of resource endpoint for obtaining additional data. 3875 * @param timeout timeout in millis to wait at most for data to be available. 3876 * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data. 3877 * @param aggregateOnException whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if 3878 * an exception was thrown. 3879 * @return the builder 3880 * @see org.apache.camel.processor.PollEnricher 3881 */ 3882 @SuppressWarnings("unchecked") 3883 public Type pollEnrich(@AsEndpointUri String resourceUri, long timeout, String aggregationStrategyRef, boolean aggregateOnException) { 3884 PollEnrichDefinition pollEnrich = new PollEnrichDefinition(); 3885 pollEnrich.setExpression(new ConstantExpression(resourceUri)); 3886 pollEnrich.setTimeout(timeout); 3887 pollEnrich.setAggregationStrategyRef(aggregationStrategyRef); 3888 pollEnrich.setAggregateOnException(aggregateOnException); 3889 addOutput(pollEnrich); 3890 return (Type) this; 3891 } 3892 3893 /** 3894 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3895 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3896 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3897 * <p/> 3898 * The difference between this and {@link #enrich(String)} is that this uses a consumer 3899 * to obtain the additional data, where as enrich uses a producer. 3900 * <p/> 3901 * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}. 3902 * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt> 3903 * otherwise we use <tt>receive(timeout)</tt>. 3904 * 3905 * @param resourceUri URI of resource endpoint for obtaining additional data. 3906 * @param timeout timeout in millis to wait at most for data to be available. 3907 * @return the builder 3908 * @see org.apache.camel.processor.PollEnricher 3909 */ 3910 public Type pollEnrich(@AsEndpointUri String resourceUri, long timeout) { 3911 return pollEnrich(resourceUri, timeout, (String) null); 3912 } 3913 3914 /** 3915 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3916 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3917 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3918 * <p/> 3919 * The difference between this and {@link #enrich(String)} is that this uses a consumer 3920 * to obtain the additional data, where as enrich uses a producer. 3921 * <p/> 3922 * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}. 3923 * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt> 3924 * otherwise we use <tt>receive(timeout)</tt>. 3925 * 3926 * @param resourceRef Reference of resource endpoint for obtaining additional data. 3927 * @param timeout timeout in millis to wait at most for data to be available. 3928 * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data. 3929 * @return the builder 3930 * @see org.apache.camel.processor.PollEnricher 3931 * @deprecated use pollEnrich with a <tt>ref:id</tt> as the resourceUri parameter. 3932 */ 3933 @Deprecated 3934 @SuppressWarnings("unchecked") 3935 public Type pollEnrichRef(String resourceRef, long timeout, String aggregationStrategyRef) { 3936 PollEnrichDefinition pollEnrich = new PollEnrichDefinition(); 3937 pollEnrich.setExpression(new SimpleExpression("ref:" + resourceRef)); 3938 pollEnrich.setTimeout(timeout); 3939 pollEnrich.setAggregationStrategyRef(aggregationStrategyRef); 3940 addOutput(pollEnrich); 3941 return (Type) this; 3942 } 3943 3944 /** 3945 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3946 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3947 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3948 * <p/> 3949 * The difference between this and {@link #enrich(String)} is that this uses a consumer 3950 * to obtain the additional data, where as enrich uses a producer. 3951 * <p/> 3952 * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}. 3953 * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt> 3954 * otherwise we use <tt>receive(timeout)</tt>. 3955 * 3956 * @param resourceRef Reference of resource endpoint for obtaining additional data. 3957 * @param timeout timeout in millis to wait at most for data to be available. 3958 * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data. 3959 * @param aggregateOnException whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if 3960 * an exception was thrown. 3961 * @return the builder 3962 * @see org.apache.camel.processor.PollEnricher 3963 * @deprecated use pollEnrich with a <tt>ref:id</tt> as the resourceUri parameter. 3964 */ 3965 @Deprecated 3966 @SuppressWarnings("unchecked") 3967 public Type pollEnrichRef(String resourceRef, long timeout, String aggregationStrategyRef, boolean aggregateOnException) { 3968 PollEnrichDefinition pollEnrich = new PollEnrichDefinition(); 3969 pollEnrich.setExpression(new SimpleExpression("ref:" + resourceRef)); 3970 pollEnrich.setTimeout(timeout); 3971 pollEnrich.setAggregationStrategyRef(aggregationStrategyRef); 3972 pollEnrich.setAggregateOnException(aggregateOnException); 3973 addOutput(pollEnrich); 3974 return (Type) this; 3975 } 3976 3977 /** 3978 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 3979 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 3980 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 3981 * <p/> 3982 * The difference between this and {@link #enrich(String)} is that this uses a consumer 3983 * to obtain the additional data, where as enrich uses a producer. 3984 * <p/> 3985 * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}. 3986 * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt> 3987 * otherwise we use <tt>receive(timeout)</tt>. 3988 * 3989 * @param expression to use an expression to dynamically compute the endpoint to poll from 3990 * @param timeout timeout in millis to wait at most for data to be available. 3991 * @param aggregationStrategyRef Reference of aggregation strategy to aggregate input data and additional data. 3992 * @param aggregateOnException whether to call {@link org.apache.camel.processor.aggregate.AggregationStrategy#aggregate(org.apache.camel.Exchange, org.apache.camel.Exchange)} if 3993 * an exception was thrown. 3994 * @return the builder 3995 * @see org.apache.camel.processor.PollEnricher 3996 */ 3997 @SuppressWarnings("unchecked") 3998 public Type pollEnrich(@AsEndpointUri Expression expression, long timeout, String aggregationStrategyRef, boolean aggregateOnException) { 3999 PollEnrichDefinition pollEnrich = new PollEnrichDefinition(); 4000 pollEnrich.setExpression(new ExpressionDefinition(expression)); 4001 pollEnrich.setTimeout(timeout); 4002 pollEnrich.setAggregationStrategyRef(aggregationStrategyRef); 4003 pollEnrich.setAggregateOnException(aggregateOnException); 4004 addOutput(pollEnrich); 4005 return (Type) this; 4006 } 4007 4008 /** 4009 * The <a href="http://camel.apache.org/content-enricher.html">Content Enricher EIP</a> 4010 * enriches an exchange with additional data obtained from a <code>resourceUri</code> 4011 * using a {@link org.apache.camel.PollingConsumer} to poll the endpoint. 4012 * <p/> 4013 * The difference between this and {@link #enrich(String)} is that this uses a consumer 4014 * to obtain the additional data, where as enrich uses a producer. 4015 * <p/> 4016 * The timeout controls which operation to use on {@link org.apache.camel.PollingConsumer}. 4017 * If timeout is negative, we use <tt>receive</tt>. If timeout is 0 then we use <tt>receiveNoWait</tt> 4018 * otherwise we use <tt>receive(timeout)</tt>. 4019 * 4020 * @return a expression builder clause to set the expression to use for computing the endpoint to poll from 4021 * @see org.apache.camel.processor.PollEnricher 4022 */ 4023 @AsEndpointUri 4024 public ExpressionClause<PollEnrichDefinition> pollEnrich() { 4025 PollEnrichDefinition answer = new PollEnrichDefinition(); 4026 addOutput(answer); 4027 return ExpressionClause.createAndSetExpression(answer); 4028 } 4029 4030 /** 4031 * Adds a onComplection {@link org.apache.camel.spi.Synchronization} hook that invoke this route as 4032 * a callback when the {@link org.apache.camel.Exchange} has finished being processed. 4033 * The hook invoke callbacks for either onComplete or onFailure. 4034 * <p/> 4035 * Will by default always trigger when the {@link org.apache.camel.Exchange} is complete 4036 * (either with success or failed). 4037 * <br/> 4038 * You can limit the callback to either onComplete or onFailure but invoking the nested 4039 * builder method. 4040 * <p/> 4041 * For onFailure the caused exception is stored as a property on the {@link org.apache.camel.Exchange} 4042 * with the key {@link org.apache.camel.Exchange#EXCEPTION_CAUGHT}. 4043 * 4044 * @return the builder 4045 */ 4046 public OnCompletionDefinition onCompletion() { 4047 OnCompletionDefinition answer = new OnCompletionDefinition(); 4048 // we must remove all existing on completion definition (as they are global) 4049 // and thus we are the only one as route scoped should override any global scoped 4050 answer.removeAllOnCompletionDefinition(this); 4051 popBlock(); 4052 addOutput(answer); 4053 pushBlock(answer); 4054 return answer; 4055 } 4056 4057 // DataFormat support 4058 // ------------------------------------------------------------------------- 4059 4060 /** 4061 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a> 4062 * Unmarshals the in body using a {@link DataFormat} expression to define 4063 * the format of the input message and the output will be set on the out message body. 4064 * 4065 * @return the expression to create the {@link DataFormat} 4066 */ 4067 public DataFormatClause<ProcessorDefinition<Type>> unmarshal() { 4068 return new DataFormatClause<ProcessorDefinition<Type>>(this, DataFormatClause.Operation.Unmarshal); 4069 } 4070 4071 /** 4072 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a> 4073 * Unmarshals the in body using the specified {@link DataFormat} 4074 * and sets the output on the out message body. 4075 * 4076 * @param dataFormatType the dataformat 4077 * @return the builder 4078 */ 4079 @SuppressWarnings("unchecked") 4080 public Type unmarshal(DataFormatDefinition dataFormatType) { 4081 addOutput(new UnmarshalDefinition(dataFormatType)); 4082 return (Type) this; 4083 } 4084 4085 /** 4086 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a> 4087 * Unmarshals the in body using the specified {@link DataFormat} 4088 * and sets the output on the out message body. 4089 * 4090 * @param dataFormat the dataformat 4091 * @return the builder 4092 */ 4093 public Type unmarshal(DataFormat dataFormat) { 4094 return unmarshal(new DataFormatDefinition(dataFormat)); 4095 } 4096 4097 /** 4098 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a> 4099 * Unmarshals the in body using the specified {@link DataFormat} 4100 * reference in the {@link org.apache.camel.spi.Registry} and sets 4101 * the output on the out message body. 4102 * 4103 * @param dataTypeRef reference to a {@link DataFormat} to lookup in the registry 4104 * @return the builder 4105 */ 4106 @SuppressWarnings("unchecked") 4107 public Type unmarshal(String dataTypeRef) { 4108 addOutput(new UnmarshalDefinition(dataTypeRef)); 4109 return (Type) this; 4110 } 4111 4112 /** 4113 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a> 4114 * Marshals the in body using a {@link DataFormat} expression to define 4115 * the format of the output which will be added to the out body. 4116 * 4117 * @return the expression to create the {@link DataFormat} 4118 */ 4119 public DataFormatClause<ProcessorDefinition<Type>> marshal() { 4120 return new DataFormatClause<ProcessorDefinition<Type>>(this, DataFormatClause.Operation.Marshal); 4121 } 4122 4123 /** 4124 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a> 4125 * Marshals the in body using the specified {@link DataFormat} 4126 * and sets the output on the out message body. 4127 * 4128 * @param dataFormatType the dataformat 4129 * @return the builder 4130 */ 4131 @SuppressWarnings("unchecked") 4132 public Type marshal(DataFormatDefinition dataFormatType) { 4133 addOutput(new MarshalDefinition(dataFormatType)); 4134 return (Type) this; 4135 } 4136 4137 /** 4138 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a> 4139 * Marshals the in body using the specified {@link DataFormat} 4140 * and sets the output on the out message body. 4141 * 4142 * @param dataFormat the dataformat 4143 * @return the builder 4144 */ 4145 public Type marshal(DataFormat dataFormat) { 4146 return marshal(new DataFormatDefinition(dataFormat)); 4147 } 4148 4149 /** 4150 * <a href="http://camel.apache.org/data-format.html">DataFormat:</a> 4151 * Marshals the in body the specified {@link DataFormat} 4152 * reference in the {@link org.apache.camel.spi.Registry} and sets 4153 * the output on the out message body. 4154 * 4155 * @param dataTypeRef reference to a {@link DataFormat} to lookup in the registry 4156 * @return the builder 4157 */ 4158 @SuppressWarnings("unchecked") 4159 public Type marshal(String dataTypeRef) { 4160 addOutput(new MarshalDefinition(dataTypeRef)); 4161 return (Type) this; 4162 } 4163 4164 /** 4165 * Sets whether or not to inherit the configured error handler. 4166 * <br/> 4167 * The default value is <tt>true</tt>. 4168 * <p/> 4169 * You can use this to disable using the inherited error handler for a given 4170 * DSL such as a load balancer where you want to use a custom error handler strategy. 4171 * 4172 * @param inheritErrorHandler whether to not to inherit the error handler for this node 4173 * @return the builder 4174 */ 4175 @SuppressWarnings("unchecked") 4176 public Type inheritErrorHandler(boolean inheritErrorHandler) { 4177 // set on last output 4178 int size = getOutputs().size(); 4179 if (size == 0) { 4180 // if no outputs then configure this DSL 4181 setInheritErrorHandler(inheritErrorHandler); 4182 } else { 4183 // configure on last output as its the intended 4184 ProcessorDefinition<?> output = getOutputs().get(size - 1); 4185 if (output != null) { 4186 output.setInheritErrorHandler(inheritErrorHandler); 4187 } 4188 } 4189 return (Type) this; 4190 } 4191 4192 // Properties 4193 // ------------------------------------------------------------------------- 4194 public ProcessorDefinition<?> getParent() { 4195 return parent; 4196 } 4197 4198 public void setParent(ProcessorDefinition<?> parent) { 4199 this.parent = parent; 4200 } 4201 4202 public List<InterceptStrategy> getInterceptStrategies() { 4203 return interceptStrategies; 4204 } 4205 4206 public void addInterceptStrategy(InterceptStrategy strategy) { 4207 this.interceptStrategies.add(strategy); 4208 } 4209 4210 public Boolean isInheritErrorHandler() { 4211 return inheritErrorHandler; 4212 } 4213 4214 public void setInheritErrorHandler(Boolean inheritErrorHandler) { 4215 this.inheritErrorHandler = inheritErrorHandler; 4216 } 4217 4218 @Override 4219 public Map<QName, Object> getOtherAttributes() { 4220 return otherAttributes; 4221 } 4222 4223 @Override 4224 public void setOtherAttributes(Map<QName, Object> otherAttributes) { 4225 this.otherAttributes = otherAttributes; 4226 } 4227 4228 /** 4229 * Returns a label to describe this node such as the expression if some kind of expression node 4230 */ 4231 public String getLabel() { 4232 return ""; 4233 } 4234}