Camel route fails to generate random UUID

时间:2016-03-02 11:03:02

标签: java java-8 apache-camel uuid

I want to generate a random UUID in a Camel route. (Camel version 2.15.3)

I expect the UUID to be different for each run of the route, even if the route runs twice without restarting the Camel context. I am using java.util.UUID (Java 1.8.0) to generate a random UUID.

But the route generates the same UUID for each run of the route, but generates a new UUID if the Camel context is restarted.

The Camel route:

import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;

import java.util.UUID;

public class UuidLogger extends RouteBuilder {
    private final String loggerID = getClass().getName();

    @Override
    public void configure() throws Exception {
        from("direct:uuidLogger").routeId("uuidLogger")
                .log(LoggingLevel.INFO, loggerID, "UuidLogger triggered with $simple{body}, headers: $simple{headers}")
                .onException(Exception.class)
                    .log(LoggingLevel.ERROR, loggerID, "Fail: Exception. Body: $simple{body}, Headers: $simple{headers}, Stacktrace: $simple{exception.stacktrace}")
                    .handled(true)
                .end()
                .setBody(simple(UUID.randomUUID().toString()))
                .log(LoggingLevel.INFO, loggerID, "Generated UUID: $simple{body}")
                .to("mock:uuidLoggerMock")
                .log(LoggingLevel.INFO, loggerID, "UuidLogger done");
    }
}

A JUnit test that shows the failure:

import com.systematic.cura.integration.vans.common.UuidLogger;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.junit.Test;

public class UuidLoggerTest extends CamelTestSupport {
    @Override
    protected RouteBuilder createRouteBuilder() throws Exception {
        return new UuidLogger();
    }

    @Test
    public void testUuidLogger() throws Exception {
        template.sendBody("direct:uuidLogger", "1");
        template.sendBody("direct:uuidLogger", "2");

        MockEndpoint validateStuff = getMockEndpoint("mock:uuidLoggerMock");

        validateStuff.expectedMessageCount(2);
        validateStuff.setAssertPeriod(1500);
        validateStuff.assertIsSatisfied();

        String uuid1 = validateStuff.getExchanges().get(0).getIn().getBody(String.class);
        String uuid2 = validateStuff.getExchanges().get(1).getIn().getBody(String.class);
        assertNotEquals("UUIDs were equal", uuid1, uuid2);
    }
}

Output from the test:

[2016-03-02 11:38:56,816] [INFO ] UuidLoggerTest: ********************************************************************************
[2016-03-02 11:38:56,817] [INFO ] UuidLoggerTest: Testing: testUuidLogger(UuidLoggerTest)
[2016-03-02 11:38:56,817] [INFO ] UuidLoggerTest: ********************************************************************************
[2016-03-02 11:38:57,185] [INFO ] org.apache.camel.impl.DefaultCamelContext: Apache Camel 2.15.3 (CamelContext: camel-1) is starting
[2016-03-02 11:38:57,188] [INFO ] org.apache.camel.management.DefaultManagementStrategy: JMX is disabled
[2016-03-02 11:38:57,285] [INFO ] org.apache.camel.impl.converter.DefaultTypeConverter: Loaded 197 type converters
[2016-03-02 11:38:57,383] [INFO ] org.apache.camel.impl.DefaultCamelContext: AllowUseOriginalMessage is enabled. If access to the original message is not needed, then its recommended to turn this option off as it may improve performance.
[2016-03-02 11:38:57,383] [INFO ] org.apache.camel.impl.DefaultCamelContext: StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
[2016-03-02 11:38:57,387] [INFO ] org.apache.camel.impl.DefaultCamelContext: Route: uuidLogger started and consuming from: Endpoint[direct://uuidLogger]
[2016-03-02 11:38:57,388] [INFO ] org.apache.camel.impl.DefaultCamelContext: Total 1 routes, of which 1 is started.
[2016-03-02 11:38:57,390] [INFO ] org.apache.camel.impl.DefaultCamelContext: Apache Camel 2.15.3 (CamelContext: camel-1) started in 0.205 seconds
[2016-03-02 11:38:57,405] [INFO ] UuidLogger: UuidLogger triggered with 1, headers: {breadcrumbId=ID-pc-4538-51425-1456915136858-0-1}
[2016-03-02 11:38:57,408] [INFO ] UuidLogger: Generated UUID: 783f0ae6-b9a5-45ab-babc-f02494dafdcb
[2016-03-02 11:38:57,409] [INFO ] UuidLogger: UuidLogger done
[2016-03-02 11:38:57,410] [INFO ] UuidLogger: UuidLogger triggered with 2, headers: {breadcrumbId=ID-pc-4538-51425-1456915136858-0-3}
[2016-03-02 11:38:57,410] [INFO ] UuidLogger: Generated UUID: 783f0ae6-b9a5-45ab-babc-f02494dafdcb
[2016-03-02 11:38:57,410] [INFO ] UuidLogger: UuidLogger done
[2016-03-02 11:38:57,411] [INFO ] org.apache.camel.component.mock.MockEndpoint: Asserting: Endpoint[mock://uuidLoggerMock] is satisfied
[2016-03-02 11:38:58,911] [INFO ] org.apache.camel.component.mock.MockEndpoint: Re-asserting: Endpoint[mock://uuidLoggerMock] is satisfied after 1500 millis
[2016-03-02 11:38:58,911] [INFO ] UuidLoggerTest: ********************************************************************************
[2016-03-02 11:38:58,911] [INFO ] UuidLoggerTest: Testing done: testUuidLogger(UuidLoggerTest)
[2016-03-02 11:38:58,912] [INFO ] UuidLoggerTest: Took: 1.520 seconds (1520 millis)
[2016-03-02 11:38:58,912] [INFO ] UuidLoggerTest: ********************************************************************************
[2016-03-02 11:38:58,913] [INFO ] org.apache.camel.impl.DefaultCamelContext: Apache Camel 2.15.3 (CamelContext: camel-1) is shutting down
[2016-03-02 11:38:58,914] [INFO ] org.apache.camel.impl.DefaultShutdownStrategy: Starting to graceful shutdown 1 routes (timeout 10 seconds)
[2016-03-02 11:38:58,923] [INFO ] org.apache.camel.impl.DefaultShutdownStrategy: Route: uuidLogger shutdown complete, was consuming from: Endpoint[direct://uuidLogger]
[2016-03-02 11:38:58,924] [INFO ] org.apache.camel.impl.DefaultShutdownStrategy: Graceful shutdown of 1 routes completed in 0 seconds
[2016-03-02 11:38:58,927] [INFO ] org.apache.camel.impl.DefaultCamelContext: Apache Camel 2.15.3 (CamelContext: camel-1) uptime 1.743 seconds
[2016-03-02 11:38:58,927] [INFO ] org.apache.camel.impl.DefaultCamelContext: Apache Camel 2.15.3 (CamelContext: camel-1) is shutdown in 0.013 seconds

java.lang.AssertionError: UUIDs were equal. Actual: 783f0ae6-b9a5-45ab-babc-f02494dafdcb

Process finished with exit code -1

Any ideas how I can make the route generate a new UUID each time?

3 个答案:

答案 0 :(得分:4)

被覆盖的RouteBuilder的configure方法只运行一次。解决方案是改为调用bean。

Bean代码:

import java.util.UUID;

public class UuidGenerator {
    public String getUuid(){
        return UUID.randomUUID().toString();
    }
}

路线中的代码:

import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;

import java.util.UUID;

public class UuidLogger extends RouteBuilder {
    private final String loggerID = getClass().getName();

    @Override
    public void configure() throws Exception {
        from("direct:uuidLogger").routeId("uuidLogger")
                .log(LoggingLevel.INFO, loggerID, "UuidLogger triggered with $simple{body}, headers: $simple{headers}")
                .onException(Exception.class)
                    .log(LoggingLevel.ERROR, loggerID, "Fail: Exception. Body: $simple{body}, Headers: $simple{headers}, Stacktrace: $simple{exception.stacktrace}")
                    .handled(true)
                .end()
                .bean(UuidGenerator.class)
                .log(LoggingLevel.INFO, loggerID, "Generated UUID: $simple{body}")
                .to("mock:uuidLoggerMock")
                .log(LoggingLevel.INFO, loggerID, "UuidLogger done");
    }
}

答案 1 :(得分:1)

我认为更简单的解决方案是在以下过程中生成UUID:

   .process(exchange -> {
                        exchange.getIn().setHeader("uid", UidUtils.getUid());
                    })

答案 2 :(得分:0)

如果同时使用log4j和apache骆驼,那么这也是一个很好的解决方案。 http://www.boxjar.com/logging-a-unique-id-for-every-request-using-log4j/

在MDC类下面使用。

import org.apache.log4j.MDC;