骆驼路线无法生成随机 UUID

Camel route fails to generate random UUID

我想在 Camel 路由中生成一个随机 UUID。 (骆驼版本 2.15.3)

我希望每个 运行 路由的 UUID 都不同,即使路由 运行 两次而没有重新启动 Camel 上下文。我正在使用 java.util.UUID (Java 1.8.0) 生成随机 UUID。

但是路由为每个运行路由生成相同的UUID,但是如果重启Camel上下文会生成一个新的UUID。

骆驼路线:

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");
    }
}

显示失败的 JUnit 测试:

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);
    }
}

测试输出:

[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

有什么办法让路由每次都生成一个新的 UUID 吗?

被覆盖的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");
    }
}

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

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

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

在 MDC 下面使用 class。

import org.apache.log4j.MDC;