Santiago Alzate
Santiago Alzate

Reputation: 407

Configure Thread Names in Apache Camel

I'm kind of new to Apache Camel and am testing it to use it on my application (replacing already implemented Spring Integration).

I've been searching all over the web, Apache Camel's documentation site and stackoverflow for the last days but can't seem to find an answer on how to configure thread's names in Apache Camel via Java DSL. I only got to see this and this other question but it only says how to do it via Spring DSL. Same on Apache Camel documentation page.

To give some context:

Here's the code snippet:

public class SampleCamelRouter extends RouteBuilder {

/**
 * The first operation name
 */
public static final String FIRST_NAME = "first";

/**
 * The second operation name
 */
public static final String SECOND_NAME = "second";

/**
 * The ActiveMQ outbound queue format
 */
public static final String OUTBOUND_QUEUE_FORMAT = "activemq:queue:aq.%1$s.response";

/**
 * The ActiveMQ inbound queue format
 */
public static final String INBOUND_QUEUE_FORMAT = "activemq:queue:aq.%1$s.request"
        + "?concurrentConsumers={{queue.%1$s.concurrentConsumers}}"
        + "&maxConcurrentConsumers={{queue.%1$s.maxConcurrentConsumers}}";

/*
 * (non-Javadoc)
 * @see org.apache.camel.builder.RouteBuilder#configure()
 */
@Override
public void configure() throws Exception {

    from(String.format(INBOUND_QUEUE_FORMAT, FIRST_NAME))
            .unmarshal().json(JsonLibrary.Jackson, FirstRequestMessage.class)
            .bean(TestBean.class, "doFirst")
            .marshal().json(JsonLibrary.Jackson)
            .to(String.format(OUTBOUND_QUEUE_FORMAT, FIRST_NAME));

    from(String.format(INBOUND_QUEUE_FORMAT, SECOND_NAME))
            .unmarshal().json(JsonLibrary.Jackson, SecondRequestMessage.class)
            .bean(TestBean.class, "doSecond")
            .marshal().json(JsonLibrary.Jackson)
            .to(String.format(OUTBOUND_QUEUE_FORMAT, SECOND_NAME));
}

I used to do it in Spring Integration with something like this (per flow):

@Bean
public static IntegrationFlow setUpFirstFlow() {

    final DefaultMessageListenerContainer messageListenerContainer = new DefaultMessageListenerContainer();
    messageListenerContainer.setBeanName("FirstOp");
    messageListenerContainer.setDestinationName("aq.first.request");
    messageListenerContainer.setConcurrentConsumers(concurrentConsumers);
    messageListenerContainer.setMaxConcurrentConsumers(maxConcurrentConsumers);

    return IntegrationFlows.from(Jms.messageDrivenChannelAdapter(messageListenerContainer))
            .transform(new JsonToObjectTransformer(FirstRequestMessage.class))
            .handle(TestBean.class, "doFirst")
            .transform(new ObjectToJsonTransformer())
            .handle(Jms.outboundAdapter(.......)).get();
}

So basically: I created different message listener containers, and that way, I have different thread names per flow. At any time if a thread is stoped, blocked, inside a thread-dump (or even as simple as printing a log) I could easily see, wich flow that thread belongs to.

I see Apache Camel has some kind of workaround (but not per route, but per camelContext) but only implemented using Spring DSL not Java.

I wouldn't mind to change my configuration to XML files if this per-route-configuration is possible only with Spring.

Please help me, it's kind of a tie-breaker for me right now. For the application I'm building, it's very important to be able to identify each thread isolated; and don't really like the default thread names (Camel (camel-1) thread #27 - JmsConsumer[aa.first.request]) :'-(.

Upvotes: 2

Views: 2508

Answers (1)

Miloš Milivojević
Miloš Milivojević

Reputation: 5369

You can set an ExecutorServiceManager per Camel context via org.apache.camel.impl.DefaultCamelContext#setExecutorServiceManager - if you use a DefaultExecutorServiceManager you can set a threadNamePattern.

Alternatively, you can use the Threads DSL and assign a thread pool to a route by using org.apache.camel.model.ProcessorDefinition#threads(int, int, java.lang.String), e.g.

from(String.format(INBOUND_QUEUE_FORMAT, FIRST_NAME))
    .threads(1, 2, "first")
    ...

from(String.format(INBOUND_QUEUE_FORMAT, SECOND_NAME))
    .threads(1, 2, "second")
    ...

Note that using the threads() method would effectively mean that you would be using an asynchronous processing model in Camel.

Upvotes: 1

Related Questions