javaspring-bootapache-camel

How to return different http response code when Camel idempotent consumer detects duplicate message?


I want to use camel idempotent consumer to ensure that message is consumed only once. I want to return status 409 if message is duplicate and 204 otherwise.

My problem is that while the code works correctly when it comes to running direct:hello route only once which suggests that MemoryIdempotentRepository is working. But it does not give me 409 response code.

When message is sent for the first time it correctly logs Exchange Properties: ${exchange.properties} and Hello World!". When same message arrives for 2nd time it does not even log Exchange Properties: ${exchange.properties} or Duplicate message detected!. Nor does it throw any exceptions.

How can I make it return different http status code in case when message is already consumed?

  @Override
  public void configure() {

    onException(Exception.class)
      .log("Exception occurred: ${exception.message}")
      .handled(true);

    from("platform-http:/api/hello?httpMethodRestrict=PUT")
      .idempotentConsumer(header("MessageId"))
        .idempotentRepository(new MemoryIdempotentRepository())
      .log("Exchange Properties: ${exchange.properties}")
      .choice()
        .when(exchangeProperty(Exchange.DUPLICATE_MESSAGE).isEqualTo(Boolean.TRUE))
          .log("Duplicate message detected!")
          .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(HttpServletResponse.SC_CONFLICT))
        .otherwise()
          .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(HttpServletResponse.SC_NO_CONTENT))
          .to("direct:hello")
      .end();

    from("direct:hello")
      .log("Hello World!");
  }

Solution

  • See the docs on the EIP and you can see there is the skipDuplicate option. You need to set this to false to let Camel still process the duplicate messages.