001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.camel.model; 018 019 import java.util.ArrayList; 020 import java.util.Collection; 021 import java.util.List; 022 import java.util.StringTokenizer; 023 import java.util.concurrent.atomic.AtomicBoolean; 024 import javax.xml.bind.annotation.XmlAccessType; 025 import javax.xml.bind.annotation.XmlAccessorType; 026 import javax.xml.bind.annotation.XmlAttribute; 027 import javax.xml.bind.annotation.XmlElementRef; 028 import javax.xml.bind.annotation.XmlRootElement; 029 import javax.xml.bind.annotation.XmlTransient; 030 import javax.xml.bind.annotation.XmlType; 031 032 import org.apache.camel.CamelContext; 033 import org.apache.camel.Endpoint; 034 import org.apache.camel.ErrorHandlerFactory; 035 import org.apache.camel.FailedToCreateRouteException; 036 import org.apache.camel.NoSuchEndpointException; 037 import org.apache.camel.Route; 038 import org.apache.camel.ServiceStatus; 039 import org.apache.camel.ShutdownRoute; 040 import org.apache.camel.ShutdownRunningTask; 041 import org.apache.camel.StatefulService; 042 import org.apache.camel.builder.AdviceWithRouteBuilder; 043 import org.apache.camel.builder.AdviceWithTask; 044 import org.apache.camel.builder.ErrorHandlerBuilderRef; 045 import org.apache.camel.builder.RouteBuilder; 046 import org.apache.camel.impl.DefaultRouteContext; 047 import org.apache.camel.processor.interceptor.Delayer; 048 import org.apache.camel.processor.interceptor.HandleFault; 049 import org.apache.camel.processor.interceptor.StreamCaching; 050 import org.apache.camel.spi.LifecycleStrategy; 051 import org.apache.camel.spi.RouteContext; 052 import org.apache.camel.spi.RoutePolicy; 053 import org.apache.camel.util.CamelContextHelper; 054 import org.apache.camel.util.ObjectHelper; 055 056 /** 057 * Represents an XML <route/> element 058 * 059 * @version 060 */ 061 @XmlRootElement(name = "route") 062 @XmlType(propOrder = {"inputs", "outputs"}) 063 @XmlAccessorType(XmlAccessType.PROPERTY) 064 public class RouteDefinition extends ProcessorDefinition<RouteDefinition> { 065 private final AtomicBoolean prepared = new AtomicBoolean(false); 066 private List<FromDefinition> inputs = new ArrayList<FromDefinition>(); 067 private List<ProcessorDefinition<?>> outputs = new ArrayList<ProcessorDefinition<?>>(); 068 private String group; 069 private String streamCache; 070 private String trace; 071 private String handleFault; 072 private String delayer; 073 private String autoStartup; 074 private Integer startupOrder; 075 private List<RoutePolicy> routePolicies; 076 private String routePolicyRef; 077 private ShutdownRoute shutdownRoute; 078 private ShutdownRunningTask shutdownRunningTask; 079 private String errorHandlerRef; 080 private ErrorHandlerFactory errorHandlerBuilder; 081 // keep state whether the error handler is context scoped or not 082 // (will by default be context scoped of no explicit error handler configured) 083 private boolean contextScopedErrorHandler = true; 084 085 public RouteDefinition() { 086 } 087 088 public RouteDefinition(String uri) { 089 from(uri); 090 } 091 092 public RouteDefinition(Endpoint endpoint) { 093 from(endpoint); 094 } 095 096 /** 097 * Prepares the route definition to be ready to be added to {@link CamelContext} 098 * 099 * @param context the camel context 100 */ 101 public void prepare(ModelCamelContext context) { 102 if (prepared.compareAndSet(false, true)) { 103 RouteDefinitionHelper.prepareRoute(context, this); 104 } 105 } 106 107 /** 108 * Marks the route definition as prepared. 109 * <p/> 110 * This is needed if routes have been created by components such as 111 * <tt>camel-spring</tt> or <tt>camel-blueprint</tt>. 112 * Usually they share logic in the <tt>camel-core-xml</tt> module which prepares the routes. 113 */ 114 public void markPrepared() { 115 prepared.set(true); 116 } 117 118 @Override 119 public String toString() { 120 return "Route[" + inputs + " -> " + outputs + "]"; 121 } 122 123 @Override 124 public String getShortName() { 125 return "route"; 126 } 127 128 /** 129 * Returns the status of the route if it has been registered with a {@link CamelContext} 130 */ 131 public ServiceStatus getStatus(CamelContext camelContext) { 132 if (camelContext != null) { 133 ServiceStatus answer = camelContext.getRouteStatus(this.getId()); 134 if (answer == null) { 135 answer = ServiceStatus.Stopped; 136 } 137 return answer; 138 } 139 return null; 140 } 141 142 public boolean isStartable(CamelContext camelContext) { 143 ServiceStatus status = getStatus(camelContext); 144 if (status == null) { 145 return true; 146 } else { 147 return status.isStartable(); 148 } 149 } 150 151 public boolean isStoppable(CamelContext camelContext) { 152 ServiceStatus status = getStatus(camelContext); 153 if (status == null) { 154 return false; 155 } else { 156 return status.isStoppable(); 157 } 158 } 159 160 public List<RouteContext> addRoutes(ModelCamelContext camelContext, Collection<Route> routes) throws Exception { 161 List<RouteContext> answer = new ArrayList<RouteContext>(); 162 163 @SuppressWarnings("deprecation") 164 ErrorHandlerFactory handler = camelContext.getErrorHandlerBuilder(); 165 if (handler != null) { 166 setErrorHandlerBuilderIfNull(handler); 167 } 168 169 for (FromDefinition fromType : inputs) { 170 RouteContext routeContext; 171 try { 172 routeContext = addRoutes(camelContext, routes, fromType); 173 } catch (FailedToCreateRouteException e) { 174 throw e; 175 } catch (Exception e) { 176 // wrap in exception which provide more details about which route was failing 177 throw new FailedToCreateRouteException(getId(), toString(), e); 178 } 179 answer.add(routeContext); 180 } 181 return answer; 182 } 183 184 185 public Endpoint resolveEndpoint(CamelContext camelContext, String uri) throws NoSuchEndpointException { 186 ObjectHelper.notNull(camelContext, "CamelContext"); 187 return CamelContextHelper.getMandatoryEndpoint(camelContext, uri); 188 } 189 190 @Deprecated 191 public RouteDefinition adviceWith(CamelContext camelContext, RouteBuilder builder) throws Exception { 192 return adviceWith((ModelCamelContext)camelContext, builder); 193 } 194 195 /** 196 * Advices this route with the route builder. 197 * <p/> 198 * <b>Important:</b> It is recommended to only advice a given route once (you can of course advice multiple routes). 199 * If you do it multiple times, then it may not work as expected, especially when any kind of error handling is involved. 200 * The Camel team plan for Camel 3.0 to support this as internal refactorings in the routing engine is needed to support this properly. 201 * <p/> 202 * You can use a regular {@link RouteBuilder} but the specialized {@link org.apache.camel.builder.AdviceWithRouteBuilder} 203 * has additional features when using the <a href="http://camel.apache.org/advicewith.html">advice with</a> feature. 204 * We therefore suggest you to use the {@link org.apache.camel.builder.AdviceWithRouteBuilder}. 205 * <p/> 206 * The advice process will add the interceptors, on exceptions, on completions etc. configured 207 * from the route builder to this route. 208 * <p/> 209 * This is mostly used for testing purpose to add interceptors and the likes to an existing route. 210 * <p/> 211 * Will stop and remove the old route from camel context and add and start this new advised route. 212 * 213 * @param camelContext the camel context 214 * @param builder the route builder 215 * @return a new route which is this route merged with the route builder 216 * @throws Exception can be thrown from the route builder 217 * @see AdviceWithRouteBuilder 218 */ 219 @SuppressWarnings("deprecation") 220 public RouteDefinition adviceWith(ModelCamelContext camelContext, RouteBuilder builder) throws Exception { 221 ObjectHelper.notNull(camelContext, "CamelContext"); 222 ObjectHelper.notNull(builder, "RouteBuilder"); 223 224 log.debug("AdviceWith route before: {}", this); 225 226 // inject this route into the advice route builder so it can access this route 227 // and offer features to manipulate the route directly 228 if (builder instanceof AdviceWithRouteBuilder) { 229 ((AdviceWithRouteBuilder) builder).setOriginalRoute(this); 230 } 231 232 // configure and prepare the routes from the builder 233 RoutesDefinition routes = builder.configureRoutes(camelContext); 234 235 log.debug("AdviceWith routes: {}", routes); 236 237 // we can only advice with a route builder without any routes 238 if (!builder.getRouteCollection().getRoutes().isEmpty()) { 239 throw new IllegalArgumentException("You can only advice from a RouteBuilder which has no existing routes." 240 + " Remove all routes from the route builder."); 241 } 242 // we can not advice with error handlers (if you added a new error handler in the route builder) 243 // we must check the error handler on builder is not the same as on camel context, as that would be the default 244 // context scoped error handler, in case no error handlers was configured 245 if (builder.getRouteCollection().getErrorHandlerBuilder() != null 246 && camelContext.getErrorHandlerBuilder() != builder.getRouteCollection().getErrorHandlerBuilder()) { 247 throw new IllegalArgumentException("You can not advice with error handlers. Remove the error handlers from the route builder."); 248 } 249 250 // stop and remove this existing route 251 camelContext.removeRouteDefinition(this); 252 253 // any advice with tasks we should execute first? 254 if (builder instanceof AdviceWithRouteBuilder) { 255 List<AdviceWithTask> tasks = ((AdviceWithRouteBuilder) builder).getAdviceWithTasks(); 256 for (AdviceWithTask task : tasks) { 257 task.task(); 258 } 259 } 260 261 // now merge which also ensures that interceptors and the likes get mixed in correctly as well 262 RouteDefinition merged = routes.route(this); 263 264 // add the new merged route 265 camelContext.getRouteDefinitions().add(0, merged); 266 267 // log the merged route at info level to make it easier to end users to spot any mistakes they may have made 268 log.info("AdviceWith route after: " + merged); 269 270 // If the camel context is started then we start the route 271 if (camelContext instanceof StatefulService) { 272 StatefulService service = (StatefulService) camelContext; 273 if (service.isStarted()) { 274 camelContext.startRoute(merged); 275 } 276 } 277 return merged; 278 } 279 280 // Fluent API 281 // ----------------------------------------------------------------------- 282 283 /** 284 * Creates an input to the route 285 * 286 * @param uri the from uri 287 * @return the builder 288 */ 289 public RouteDefinition from(String uri) { 290 getInputs().add(new FromDefinition(uri)); 291 return this; 292 } 293 294 /** 295 * Creates an input to the route 296 * 297 * @param endpoint the from endpoint 298 * @return the builder 299 */ 300 public RouteDefinition from(Endpoint endpoint) { 301 getInputs().add(new FromDefinition(endpoint)); 302 return this; 303 } 304 305 /** 306 * Creates inputs to the route 307 * 308 * @param uris the from uris 309 * @return the builder 310 */ 311 public RouteDefinition from(String... uris) { 312 for (String uri : uris) { 313 getInputs().add(new FromDefinition(uri)); 314 } 315 return this; 316 } 317 318 /** 319 * Creates inputs to the route 320 * 321 * @param endpoints the from endpoints 322 * @return the builder 323 */ 324 public RouteDefinition from(Endpoint... endpoints) { 325 for (Endpoint endpoint : endpoints) { 326 getInputs().add(new FromDefinition(endpoint)); 327 } 328 return this; 329 } 330 331 /** 332 * Set the group name for this route 333 * 334 * @param name the group name 335 * @return the builder 336 */ 337 public RouteDefinition group(String name) { 338 setGroup(name); 339 return this; 340 } 341 342 /** 343 * Set the route id for this route 344 * 345 * @param id the route id 346 * @return the builder 347 */ 348 public RouteDefinition routeId(String id) { 349 setId(id); 350 return this; 351 } 352 353 /** 354 * Disable stream caching for this route. 355 * 356 * @return the builder 357 */ 358 public RouteDefinition noStreamCaching() { 359 setStreamCache("false"); 360 StreamCaching.noStreamCaching(getInterceptStrategies()); 361 return this; 362 } 363 364 /** 365 * Enable stream caching for this route. 366 * 367 * @return the builder 368 */ 369 public RouteDefinition streamCaching() { 370 setStreamCache("true"); 371 StreamCaching cache = StreamCaching.getStreamCaching(getInterceptStrategies()); 372 if (cache == null) { 373 cache = new StreamCaching(); 374 } 375 376 getInterceptStrategies().add(cache); 377 return this; 378 } 379 380 /** 381 * Disable tracing for this route. 382 * 383 * @return the builder 384 */ 385 public RouteDefinition noTracing() { 386 setTrace("false"); 387 return this; 388 } 389 390 /** 391 * Enable tracing for this route. 392 * 393 * @return the builder 394 */ 395 public RouteDefinition tracing() { 396 setTrace("true"); 397 return this; 398 } 399 400 /** 401 * Disable handle fault for this route. 402 * 403 * @return the builder 404 */ 405 public RouteDefinition noHandleFault() { 406 setHandleFault("false"); 407 return this; 408 } 409 410 /** 411 * Enable handle fault for this route. 412 * 413 * @return the builder 414 */ 415 public RouteDefinition handleFault() { 416 setHandleFault("true"); 417 return this; 418 } 419 420 /** 421 * Disable delayer for this route. 422 * 423 * @return the builder 424 */ 425 public RouteDefinition noDelayer() { 426 setDelayer("0"); 427 return this; 428 } 429 430 /** 431 * Enable delayer for this route. 432 * 433 * @param delay delay in millis 434 * @return the builder 435 */ 436 public RouteDefinition delayer(long delay) { 437 setDelayer("" + delay); 438 return this; 439 } 440 441 /** 442 * Installs the given <a href="http://camel.apache.org/error-handler.html">error handler</a> builder. 443 * 444 * @param errorHandlerBuilder the error handler to be used by default for all child routes 445 * @return the current builder with the error handler configured 446 */ 447 public RouteDefinition errorHandler(ErrorHandlerFactory errorHandlerBuilder) { 448 setErrorHandlerBuilder(errorHandlerBuilder); 449 // we are now using a route scoped error handler 450 contextScopedErrorHandler = false; 451 return this; 452 } 453 454 /** 455 * Disables this route from being auto started when Camel starts. 456 * 457 * @return the builder 458 */ 459 public RouteDefinition noAutoStartup() { 460 setAutoStartup("false"); 461 return this; 462 } 463 464 /** 465 * Sets the auto startup property on this route. 466 * 467 * @param autoStartup - String indicator ("true" or "false") 468 * @return the builder 469 */ 470 public RouteDefinition autoStartup(String autoStartup) { 471 setAutoStartup(autoStartup); 472 return this; 473 } 474 475 /** 476 * Sets the auto startup property on this route. 477 * 478 * @param autoStartup - boolean indicator 479 * @return the builder 480 */ 481 public RouteDefinition autoStartup(boolean autoStartup) { 482 setAutoStartup(Boolean.toString(autoStartup)); 483 return this; 484 } 485 486 /** 487 * Configures the startup order for this route 488 * <p/> 489 * Camel will reorder routes and star them ordered by 0..N where 0 is the lowest number and N the highest number. 490 * Camel will stop routes in reverse order when its stopping. 491 * 492 * @param order the order represented as a number 493 * @return the builder 494 */ 495 public RouteDefinition startupOrder(int order) { 496 setStartupOrder(order); 497 return this; 498 } 499 500 /** 501 * Configures route policies for this route 502 * 503 * @param policies the route policies 504 * @return the builder 505 */ 506 public RouteDefinition routePolicy(RoutePolicy... policies) { 507 if (routePolicies == null) { 508 routePolicies = new ArrayList<RoutePolicy>(); 509 } 510 for (RoutePolicy policy : policies) { 511 routePolicies.add(policy); 512 } 513 return this; 514 } 515 516 /** 517 * Configures a route policy for this route 518 * 519 * @param routePolicyRef reference to a {@link RoutePolicy} to lookup and use. 520 * You can specify multiple references by separating using comma. 521 * @return the builder 522 */ 523 public RouteDefinition routePolicyRef(String routePolicyRef) { 524 setRoutePolicyRef(routePolicyRef); 525 return this; 526 } 527 528 /** 529 * Configures a shutdown route option. 530 * 531 * @param shutdownRoute the option to use when shutting down this route 532 * @return the builder 533 */ 534 public RouteDefinition shutdownRoute(ShutdownRoute shutdownRoute) { 535 setShutdownRoute(shutdownRoute); 536 return this; 537 } 538 539 /** 540 * Configures a shutdown running task option. 541 * 542 * @param shutdownRunningTask the option to use when shutting down and how to act upon running tasks. 543 * @return the builder 544 */ 545 public RouteDefinition shutdownRunningTask(ShutdownRunningTask shutdownRunningTask) { 546 setShutdownRunningTask(shutdownRunningTask); 547 return this; 548 } 549 550 // Properties 551 // ----------------------------------------------------------------------- 552 553 public List<FromDefinition> getInputs() { 554 return inputs; 555 } 556 557 @XmlElementRef 558 public void setInputs(List<FromDefinition> inputs) { 559 this.inputs = inputs; 560 } 561 562 public List<ProcessorDefinition<?>> getOutputs() { 563 return outputs; 564 } 565 566 @XmlElementRef 567 public void setOutputs(List<ProcessorDefinition<?>> outputs) { 568 this.outputs = outputs; 569 570 if (outputs != null) { 571 for (ProcessorDefinition<?> output : outputs) { 572 configureChild(output); 573 } 574 } 575 } 576 577 public boolean isOutputSupported() { 578 return true; 579 } 580 581 /** 582 * The group that this route belongs to; could be the name of the RouteBuilder class 583 * or be explicitly configured in the XML. 584 * <p/> 585 * May be null. 586 */ 587 public String getGroup() { 588 return group; 589 } 590 591 @XmlAttribute 592 public void setGroup(String group) { 593 this.group = group; 594 } 595 596 public String getStreamCache() { 597 return streamCache; 598 } 599 600 @XmlAttribute 601 public void setStreamCache(String streamCache) { 602 this.streamCache = streamCache; 603 } 604 605 public String getTrace() { 606 return trace; 607 } 608 609 @XmlAttribute 610 public void setTrace(String trace) { 611 this.trace = trace; 612 } 613 614 public String getHandleFault() { 615 return handleFault; 616 } 617 618 @XmlAttribute 619 public void setHandleFault(String handleFault) { 620 this.handleFault = handleFault; 621 } 622 623 public String getDelayer() { 624 return delayer; 625 } 626 627 @XmlAttribute 628 public void setDelayer(String delayer) { 629 this.delayer = delayer; 630 } 631 632 public String getAutoStartup() { 633 return autoStartup; 634 } 635 636 public boolean isAutoStartup(CamelContext camelContext) throws Exception { 637 if (getAutoStartup() == null) { 638 // should auto startup by default 639 return true; 640 } 641 Boolean isAutoStartup = CamelContextHelper.parseBoolean(camelContext, getAutoStartup()); 642 return isAutoStartup != null && isAutoStartup; 643 } 644 645 @XmlAttribute 646 public void setAutoStartup(String autoStartup) { 647 this.autoStartup = autoStartup; 648 } 649 650 public Integer getStartupOrder() { 651 return startupOrder; 652 } 653 654 @XmlAttribute 655 public void setStartupOrder(Integer startupOrder) { 656 this.startupOrder = startupOrder; 657 } 658 659 /** 660 * Sets the bean ref name of the error handler builder to use on this route 661 */ 662 @XmlAttribute 663 public void setErrorHandlerRef(String errorHandlerRef) { 664 this.errorHandlerRef = errorHandlerRef; 665 // we use an specific error handler ref (from Spring DSL) then wrap that 666 // with a error handler build ref so Camel knows its not just the default one 667 setErrorHandlerBuilder(new ErrorHandlerBuilderRef(errorHandlerRef)); 668 } 669 670 public String getErrorHandlerRef() { 671 return errorHandlerRef; 672 } 673 674 /** 675 * Sets the error handler if one is not already set 676 */ 677 public void setErrorHandlerBuilderIfNull(ErrorHandlerFactory errorHandlerBuilder) { 678 if (this.errorHandlerBuilder == null) { 679 setErrorHandlerBuilder(errorHandlerBuilder); 680 } 681 } 682 683 @XmlAttribute 684 public void setRoutePolicyRef(String routePolicyRef) { 685 this.routePolicyRef = routePolicyRef; 686 } 687 688 public String getRoutePolicyRef() { 689 return routePolicyRef; 690 } 691 692 public List<RoutePolicy> getRoutePolicies() { 693 return routePolicies; 694 } 695 696 @XmlTransient 697 public void setRoutePolicies(List<RoutePolicy> routePolicies) { 698 this.routePolicies = routePolicies; 699 } 700 701 public ShutdownRoute getShutdownRoute() { 702 return shutdownRoute; 703 } 704 705 @XmlAttribute 706 public void setShutdownRoute(ShutdownRoute shutdownRoute) { 707 this.shutdownRoute = shutdownRoute; 708 } 709 710 public ShutdownRunningTask getShutdownRunningTask() { 711 return shutdownRunningTask; 712 } 713 714 @XmlAttribute 715 public void setShutdownRunningTask(ShutdownRunningTask shutdownRunningTask) { 716 this.shutdownRunningTask = shutdownRunningTask; 717 } 718 719 private ErrorHandlerFactory createErrorHandlerBuilder() { 720 if (errorHandlerRef != null) { 721 return new ErrorHandlerBuilderRef(errorHandlerRef); 722 } 723 724 // return a reference to the default error handler 725 return new ErrorHandlerBuilderRef(ErrorHandlerBuilderRef.DEFAULT_ERROR_HANDLER_BUILDER); 726 } 727 728 @XmlTransient 729 public ErrorHandlerFactory getErrorHandlerBuilder() { 730 if (errorHandlerBuilder == null) { 731 errorHandlerBuilder = createErrorHandlerBuilder(); 732 } 733 return errorHandlerBuilder; 734 } 735 736 /** 737 * Sets the error handler to use with processors created by this builder 738 */ 739 public void setErrorHandlerBuilder(ErrorHandlerFactory errorHandlerBuilder) { 740 this.errorHandlerBuilder = errorHandlerBuilder; 741 } 742 743 @SuppressWarnings("deprecation") 744 public boolean isContextScopedErrorHandler(CamelContext context) { 745 if (!contextScopedErrorHandler) { 746 return false; 747 } 748 // if error handler ref is configured it may refer to a context scoped, so we need to check this first 749 // the XML DSL will configure error handlers using refs, so we need this additional test 750 if (errorHandlerRef != null) { 751 ErrorHandlerFactory routeScoped = getErrorHandlerBuilder(); 752 ErrorHandlerFactory contextScoped = context.getErrorHandlerBuilder(); 753 return routeScoped != null && contextScoped != null && routeScoped == contextScoped; 754 } 755 756 return contextScopedErrorHandler; 757 } 758 759 // Implementation methods 760 // ------------------------------------------------------------------------- 761 protected RouteContext addRoutes(CamelContext camelContext, Collection<Route> routes, FromDefinition fromType) throws Exception { 762 RouteContext routeContext = new DefaultRouteContext(camelContext, this, fromType, routes); 763 764 // configure tracing 765 if (trace != null) { 766 Boolean isTrace = CamelContextHelper.parseBoolean(camelContext, getTrace()); 767 if (isTrace != null) { 768 routeContext.setTracing(isTrace); 769 if (isTrace) { 770 log.debug("Tracing is enabled on route: {}", getId()); 771 // tracing is added in the DefaultChannel so we can enable it on the fly 772 } 773 } 774 } 775 776 // configure stream caching 777 if (streamCache != null) { 778 Boolean isStreamCache = CamelContextHelper.parseBoolean(camelContext, getStreamCache()); 779 if (isStreamCache != null) { 780 routeContext.setStreamCaching(isStreamCache); 781 if (isStreamCache) { 782 log.debug("StreamCaching is enabled on route: {}", getId()); 783 // only add a new stream cache if not already a global configured on camel context 784 if (StreamCaching.getStreamCaching(camelContext) == null) { 785 addInterceptStrategy(new StreamCaching()); 786 } 787 } 788 } 789 } 790 791 // configure handle fault 792 if (handleFault != null) { 793 Boolean isHandleFault = CamelContextHelper.parseBoolean(camelContext, getHandleFault()); 794 if (isHandleFault != null) { 795 routeContext.setHandleFault(isHandleFault); 796 if (isHandleFault) { 797 log.debug("HandleFault is enabled on route: {}", getId()); 798 // only add a new handle fault if not already a global configured on camel context 799 if (HandleFault.getHandleFault(camelContext) == null) { 800 addInterceptStrategy(new HandleFault()); 801 } 802 } 803 } 804 } 805 806 // configure delayer 807 if (delayer != null) { 808 Long delayer = CamelContextHelper.parseLong(camelContext, getDelayer()); 809 if (delayer != null) { 810 routeContext.setDelayer(delayer); 811 if (delayer > 0) { 812 log.debug("Delayer is enabled with: {} ms. on route: {}", delayer, getId()); 813 addInterceptStrategy(new Delayer(delayer)); 814 } else { 815 log.debug("Delayer is disabled on route: {}", getId()); 816 } 817 } 818 } 819 820 // configure route policy 821 if (routePolicies != null && !routePolicies.isEmpty()) { 822 for (RoutePolicy policy : routePolicies) { 823 log.debug("RoutePolicy is enabled: {} on route: {}", policy, getId()); 824 routeContext.getRoutePolicyList().add(policy); 825 } 826 } 827 if (routePolicyRef != null) { 828 StringTokenizer policyTokens = new StringTokenizer(routePolicyRef, ","); 829 while (policyTokens.hasMoreTokens()) { 830 String ref = policyTokens.nextToken().trim(); 831 RoutePolicy policy = CamelContextHelper.mandatoryLookup(camelContext, ref, RoutePolicy.class); 832 log.debug("RoutePolicy is enabled: {} on route: {}", policy, getId()); 833 routeContext.getRoutePolicyList().add(policy); 834 } 835 } 836 837 // configure auto startup 838 Boolean isAutoStartup = CamelContextHelper.parseBoolean(camelContext, getAutoStartup()); 839 if (isAutoStartup != null) { 840 log.debug("Using AutoStartup {} on route: {}", isAutoStartup, getId()); 841 routeContext.setAutoStartup(isAutoStartup); 842 } 843 844 // configure shutdown 845 if (shutdownRoute != null) { 846 log.debug("Using ShutdownRoute {} on route: {}", getShutdownRoute(), getId()); 847 routeContext.setShutdownRoute(getShutdownRoute()); 848 } 849 if (shutdownRunningTask != null) { 850 log.debug("Using ShutdownRunningTask {} on route: {}", getShutdownRunningTask(), getId()); 851 routeContext.setShutdownRunningTask(getShutdownRunningTask()); 852 } 853 854 // should inherit the intercept strategies we have defined 855 routeContext.setInterceptStrategies(this.getInterceptStrategies()); 856 // force endpoint resolution 857 routeContext.getEndpoint(); 858 if (camelContext != null) { 859 for (LifecycleStrategy strategy : camelContext.getLifecycleStrategies()) { 860 strategy.onRouteContextCreate(routeContext); 861 } 862 } 863 864 // validate route has output processors 865 if (!ProcessorDefinitionHelper.hasOutputs(outputs, true)) { 866 RouteDefinition route = routeContext.getRoute(); 867 String at = fromType.toString(); 868 Exception cause = new IllegalArgumentException("Route " + route.getId() + " has no output processors." 869 + " You need to add outputs to the route such as to(\"log:foo\")."); 870 throw new FailedToCreateRouteException(route.getId(), route.toString(), at, cause); 871 } 872 873 List<ProcessorDefinition<?>> list = new ArrayList<ProcessorDefinition<?>>(outputs); 874 for (ProcessorDefinition<?> output : list) { 875 try { 876 output.addRoutes(routeContext, routes); 877 } catch (Exception e) { 878 RouteDefinition route = routeContext.getRoute(); 879 throw new FailedToCreateRouteException(route.getId(), route.toString(), output.toString(), e); 880 } 881 } 882 883 routeContext.commit(); 884 return routeContext; 885 } 886 }