Configuring Routes Startup Ordering and Autostartup

Author: Helen

Sep. 02, 2024

Configuring Routes Startup Ordering and Autostartup

You can also configure the order in which routes are started. Previously Camel started the routes in a non-deterministic order. Now you have fine-grained control in which order the routes should be started. There is a new attribute startupOrder which is an Integer that states the order. Camel then sorts the routes before starting time. The routes with the lowest startupOrder are started first and the ones with the highest are started last.

CAMEL are exported all over the world and different industries with quality first. Our belief is to provide our customers with more and better high value-added products. Let's create a better future together.

All startupOrder defined must be unique among all routes in your CamelContext. Otherwise, if there are clashes in startupOrder numbers among routes, the routes will fail to start up throwing org.apache.camel.FailedToStartRouteException.

Normally you should also use numbers that are lower than , as routes without an explicit startupOrder definition will have a number starting from auto assigned. So view numbers from upwards as reserved internally for Camel itself.

However, you can also utilise much higher numbers than (to avoid collisions with those auto assigned numbers) to specify the last routes to start up. Normally the usage of numbers starting from should be safe for the purpose.

In terms of the startupOrder there are no strict rules that it must start from 1 and increment by 1. You can for example use: 100, 200, 205, 89 if you like. Only rule of thumb is that the numbers must be unique.

Why do you want to control the starting order?

It can help in cases where routes are inter-dependent on each other and also help with graceful shutting down Camel as Camel can stop the routes in the correct order as well.

Camel will stop the routes in the reverse order that they were started.

Let&#;s try a couple of examples.

Startup ordering example

from("seda:foo").startupOrder(1)
    .to("mock:result");

from("direct:start").startupOrder(2)
    .to("seda:foo");

And the same example with XML DSL:

<routes>
    <route startupOrder="1">
        <from uri="seda:foo"/>
        <to uri="mock:result"/>
    </route>

    <route startupOrder="2">
        <from uri="direct:start"/>
        <to uri="seda:foo"/>
    </route>
</routes>

In this example we have two routes in which we have started that the direct:start route should be started after the seda:foo route. Because direct:start is considered the input, and we want seda:foo route to be up and running beforehand.

Using startOrder together with non startOrder

You can also mix and match routes with and without startupOrder defined. The first two routes below have start order defined, and the last route has not.

from("seda:foo").startupOrder(1)
    .to("mock:result");

from("direct:start").startupOrder(2)
    .to("seda:foo");

from("direct:bar")
    .to("seda:bar");

And the same example with XML DSL:

<routes>
    <route startupOrder="1">
        <from uri="seda:foo"/>
        <to uri="mock:result"/>
    </route>

    <route startupOrder="2">
        <from uri="direct:start"/>
        <to uri="seda:foo"/>
    </route>

    <route>
        <from uri="direct:bar"/>
        <to uri="seda:bar"/>
    </route>
</routes>

In the route above we have not defined a startupOrder on the last route direct:bar in which Camel will auto assign a number for it, in which this case will be ; therefore the route will be started last.

So you can use this to your advantage to only assign a startupOrder on the routes which really needs it.

Configuring routes to start up last

You can use a high number in startupOrder to have a specific route startup last as shown below:

// use auto assigned startup ordering
from("direct:start").to("seda:foo");

// should start first
from("seda:foo").startupOrder(1).to("mock:result");

// should start last after the default routes
from("direct:bar").startupOrder().to("seda:bar");

// use auto assigned startup ordering
from("seda:bar").to("mock:other");

In the example above the order of startups of routes should be:

  1. seda:foo

  2. direct:start

  3. seda:bar

  4. direct:bar

Shutting down routes

Camel will shut down the routes in the reverse order that they were started.

See more at Graceful Shutdown.

Chapter 6. Apache Camel in Spring Boot

6.1. Introduction to Camel Spring Boot

The Camel Spring Boot component provides auto configuration for Apache Camel. Auto-configuration of the Camel context auto-detects Camel routes available in the Spring context and registers the key Camel utilities such as producer template, consumer template, and the type converter as beans.

Every Camel Spring Boot application should use dependencyManagement with productized versions, see quickstart pom. Versions that are tagged later can be omitted to not override the versions from BOM.

<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.jboss.redhat-fuse</groupId>
			<artifactId>fuse-springboot-bom</artifactId>
			<version>${fuse.version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

Note

camel-spring-boot jar comes with the spring.factories file which allows you to add that dependency into your classpath and hence Spring Boot will automatically auto-configure Camel.

6.2. Introduction to Camel Spring Boot Starter

Apache Camel includes a Spring Boot starter module that allows you to develop Spring Boot applications using starters.

Note

For more details, see sample application in the source code.

To use the starter, add the following snippet to your Spring Boot pom.xml file:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-spring-boot-starter</artifactId>
</dependency>

The starter allows you to add classes with your Camel routes, as shown in the snippet below. Once these routes are added to the class path the routes are started automatically.

package com.example;

import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;

@Component
public class MyRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        from("timer:foo").to("log:bar");
    }
}

You can customize the Camel application in the application.properties or application.yml file. 

Camel Spring Boot now supports referring to bean by the id name in the configuration files (application.properties or yaml file) when you configure any of the Camel starter components. In the src/main/resources/application.properties (or yaml) file you can now easily configure the options on the Camel that refers to other beans by refering to the beans ID name. For example, the xslt component can refer to a custom bean using the bean ID as follows:

Refer to a custom bean by the id myExtensionFactory as follows:

camel.component.xslt.saxon-extension-functions=myExtensionFactory

Which you can then create using Spring Boot @Bean annotation as follows:

@Bean(name = "myExtensionFactory")
public ExtensionFunctionDefinition myExtensionFactory() {
    }

Or, in case of a Jackson ObjectMapper in the camel-jackson data-format:

camel.dataformat.json-jackson.object-mapper=myJacksonMapper

6.3. Auto-configured Camel context

Camel auto-configuration provides a CamelContext instance and creates a SpringCamelContext. It also initializes and performs shutdown of that context. This Camel context is registered in the Spring application context under camelContext bean name and you can access it like other Spring bean.

For example, you can access the camelContext as shown below:

Contact us to discuss your requirements of camel auto. Our experienced sales team can help you identify the options that best suit your needs.

@Configuration
public class MyAppConfig {

  @Autowired
  CamelContext camelContext;

  @Bean
  MyService myService() {
    return new DefaultMyService(camelContext);
  }

}

6.4. Auto-detecting Camel routes

Camel auto configuration collects all the RouteBuilder instances from the Spring context and automatically injects them into the CamelContext. It simplifies the process of creating new Camel route with the Spring Boot starter. You can create the routes by adding the @Component annotated class to your classpath.

@Component
public class MyRouter extends RouteBuilder {

  @Override
  public void configure() throws Exception {
    from("jms:invoices").to("file:/invoices");
  }

}

To create a new route RouteBuilder bean in your @Configuration class, see below:

@Configuration
public class MyRouterConfiguration {

  @Bean
  RoutesBuilder myRouter() {
    return new RouteBuilder() {

      @Override
      public void configure() throws Exception {
        from("jms:invoices").to("file:/invoices");
      }

    };
  }
 
}

6.5. Camel properties

Spring Boot auto configuration automatically connects to Spring Boot external configuration such as properties placeholders, OS environment variables, or system properties with Camel properties support.

These properties are defined in application.properties file:  

route.from = jms:invoices

Use as system property

java -Droute.to=jms:processed.invoices -jar mySpringApp.jar

Use as placeholders in Camel route:

@Component
public class MyRouter extends RouteBuilder {

  @Override
  public void configure() throws Exception {
    from("{{route.from}}").to("{{route.to}}");
  }

}

6.6. Custom Camel context configuration

To perform operations on CamelContext bean created by Camel auto configuration, you need to register CamelContextConfiguration instance in your Spring context as shown below:

@Configuration
public class MyAppConfig {

  ...

  @Bean
  CamelContextConfiguration contextConfiguration() {
    return new CamelContextConfiguration() {
      @Override
      void beforeApplicationStart(CamelContext context) {
        // your custom configuration goes here
      }
    };
  }

}

Note

The method CamelContextConfiguration and beforeApplicationStart(CamelContext) will be called before the Spring context is started, so the CamelContext instance passed to this callback is fully auto-configured. You can add many instances of CamelContextConfiguration into your Spring context and all of them will be executed.

6.7. Disabling JMX

To disable JMX of the auto-configured CamelContext use camel.springboot.jmxEnabled property as JMX is enabled by default.

For example, you could add the following property to your application.properties file:

camel.springboot.jmxEnabled = false

6.8. Auto-configured consumer and producer templates

Camel auto configuration provides pre-configured ConsumerTemplate and ProducerTemplate instances. You can inject them into your Spring-managed beans:

@Component
public class InvoiceProcessor {

  @Autowired
  private ProducerTemplate producerTemplate;

  @Autowired
  private ConsumerTemplate consumerTemplate;
  public void processNextInvoice() {
    Invoice invoice = consumerTemplate.receiveBody("jms:invoices", Invoice.class);
    ...
    producerTemplate.sendBody("netty-http:http://invoicing.com/received/" + invoice.id());
  }

}

By default consumer templates and producer templates come with the endpoint cache sizes set to . You can change those values using the following Spring properties:

camel.springboot.consumerTemplateCacheSize = 100
camel.springboot.producerTemplateCacheSize = 200

6.9. Auto-configured TypeConverter

Camel auto configuration registers a TypeConverter instance named typeConverter in the Spring context.

@Component
public class InvoiceProcessor {

  @Autowired
  private TypeConverter typeConverter;

  public long parseInvoiceValue(Invoice invoice) {
    String invoiceValue = invoice.grossValue();
    return typeConverter.convertTo(Long.class, invoiceValue);
  }

}

6.10. Spring type conversion API bridge

Spring consist of  type conversion API. Spring API is similar to the Camel type converter API. Due to the similarities between the two APIs Camel Spring Boot automatically registers a bridge converter (SpringTypeConverter) that delegates to the Spring conversion API. That means that out-of-the-box Camel will treat Spring Converters similar to Camel.

This allows you to access both Camel and Spring converters using the Camel TypeConverter API, as shown below:

@Component
public class InvoiceProcessor {

  @Autowired
  private TypeConverter typeConverter;

  public UUID parseInvoiceId(Invoice invoice) {
    // Using Spring's StringToUUIDConverter
    UUID id = invoice.typeConverter.convertTo(UUID.class, invoice.getId());
  }

}

Here, Spring Boot delegates conversion to the Spring&#;s ConversionService instances available in the application context. If no ConversionService instance is available, Camel Spring Boot auto configuration creates an instance of ConversionService.

6.11. Disabling type conversions features

To disable registering type conversion features of Camel Spring Boot such as TypeConverter instance or Spring bridge, set the camel.springboot.typeConversion property to false as shown below:

camel.springboot.typeConversion = false

6.12. Adding XML routes

By default, you can put Camel XML routes in the classpath under the directory camel, which camel-spring-boot will auto detect and include. From Camel version 2.17 onwards you can configure the directory name or disable this feature using the configuration option, as shown below:

// turn off
camel.springboot.xmlRoutes = false
// scan in the com/foo/routes classpath
camel.springboot.xmlRoutes = classpath:com/foo/routes/*.xml

Note

The XML files should be Camel XML routes and not CamelContext such as:

   <routes xmlns="http://camel.apache.org/schema/spring">
        <route id="test">
            <from uri="timer://trigger"/>
            <transform>
                <simple>ref:myBean</simple>
            </transform>
            <to uri="log:out"/>
        </route>
    </routes>

When using Spring XML files with <camelContext>, you can configure Camel in the Spring XML file as well as in the application.properties file. For example, to set a name on Camel and turn On the stream caching, add:

camel.springboot.name = MyCamel
camel.springboot.stream-caching-enabled=true

6.13. Adding XML Rest-DSL

By default, you can put Camel Rest-DSL XML routes in the classpath under the directory camel-rest, which camel-spring-boot will auto detect and include. You can configure the directory name or disable this feature using the configuration option, as shown below:

// turn off
camel.springboot.xmlRests = false
// scan in the com/foo/routes classpath
camel.springboot.xmlRests = classpath:com/foo/rests/*.xml

Note

The Rest-DSL XML files should be Camel XML rests and not CamelContext such as:

   <rests xmlns="http://camel.apache.org/schema/spring">
      <rest>
         <post uri="/persons">
            <to uri="direct:postPersons"/>
         </post>
         <get uri="/persons">
            <to uri="direct:getPersons"/>
         </get>
         <get uri="/persons/{personId}">
             <to uri="direct:getPersionId"/>
         </get>
         <put uri="/persons/{personId}">
             <to uri="direct:putPersionId"/>
         </put>
         <delete uri="/persons/{personId}">
             <to uri="direct:deletePersionId"/>
         </delete>
      </rest>
    </rests>

6.14. Testing with Camel Spring Boot

In case on Camel running on Spring Boot, Spring Boot automatically embeds Camel and all its routes, which are annotated with @Component. When testing with Spring boot you use @SpringBootTest instead of @ContextConfiguration to specify which configuration class to use.

When you have multiple Camel routes in different RouteBuilder classes, Camel Spring Boot will include all these routes. Hence, when you wish to test routes from only one RouteBuilder class you can use the following patterns to include or exclude which RouteBuilders to enable:

  • java-routes-include-pattern: Used for including RouteBuilder classes that match the pattern.
  • java-routes-exclude-pattern: Used for excluding RouteBuilder classes that match the pattern. Exclude takes precedence over include.

You can specify these patterns in your unit test classes as properties to @SpringBootTest annonation, as shown below:

@RunWith(CamelSpringBootRunner.class)
@SpringBootTest(classes = {MyApplication.class);
   properties = {"camel.springboot.java-routes-include-pattern=**/Foo*"})
public class FooTest {

In the FooTest class, the include pattern is **/Foo*, which represents an Ant style pattern. Here, the pattern starts with double asterisk, which matches with any leading package name. /Foo* means the class name must start with Foo, for example, FooRoute. You can run a test using following maven command:

Are you interested in learning more about agm car battery technology? Contact us today to secure an expert consultation!

mvn test -Dtest=FooTest

45

0

Comments

Please Join Us to post.

0/2000

All Comments ( 0 )

Guest Posts

If you are interested in sending in a Guest Blogger Submission,welcome to write for us!

Your Name: (required)

Your Email: (required)

Subject:

Your Message: (required)