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?
答案 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;