具有异步处理的Camel Reslet组件

时间:2014-10-31 10:12:25

标签: apache-camel

我的要求如下:

  • 接受包含XML的HTTP POST请求到某个URL。
  • 执行先决条件操作,例如将请求XML保存到文件中。
  • 验证传入的XML是否与相应的架构匹配。
  • 如果架构验证失败,请使用HTTP 400响应代码同步响应。
  • 如果架构验证通过,则使用HTTP 200响应代码同步响应。
  • 传递XML消息以进行进一步处理。
  • 当此进一步处理完成时,使用HTTP 200响应代码异步响应调用方。

目前这是我配置路线的方式:

        onException(IOException.class)
            .log(LoggingLevel.INFO, "Schema validation error on incoming message: ${id}")
            .handled(true)
            .maximumRedeliveries(0)
            .process(schemaValidationErrorProcessor);

        from("restlet:http://localhost:" + portNum + "/api/XX/XXX?restletMethod=POST")
            .log(LoggingLevel.INFO, "Received message")
            .convertBodyTo(String.class)
            .multicast()
            .parallelProcessing()
                .to(SAVE_REQUEST_TO_FILE_QUEUE, PROCESS_PROVISIONING_REQUEST_QUEUE);

        from(SAVE_REQUEST_TO_FILE_QUEUE)
            .log(LoggingLevel.INFO, "Storing message: ${id}")
            .to("file://" + requestLogFolder);

        from(PROCESS_PROVISIONING_REQUEST_QUEUE)
            .log(LoggingLevel.INFO, "Processing provisioning request: ${id}")
            .process(requestGate)
            .choice()
                .when(header(SYSTEM_STATUS_HEADER).isEqualTo(true))
                    .unmarshal(xmlParser)
                    .inOnly("bean:requestHandler?method=handle")
                .when(header(SYSTEM_STATUS_HEADER).isEqualTo(false))
                    .log(LoggingLevel.INFO, "Intentially dropping message")
            .endChoice();

模式验证部分是通过.unmarshal(xmlParser)行实现的(我在其他地方配置了JaxbDataFormat对象,其中设置了模式)。当模式验证失败时,抛出IOException,这由我的schemaValidationErrorProcessor处理,它将HTTP 400添加到响应中。

这一切都正常。

我遇到的问题是传递XML消息以进行进一步处理。基本上,我需要异步完成这个,因为当模式验证通过时,我需要同步响应200响应。我需要处理的是.inOnly(“bean:requestHandler?method = handle”)行。

我天真地认为将路由设置为myOnly会将其设置为异步,并且主路由不会等待响应。但是,情况并非如此,因为当requestHandler.handle方法抛出异常时,会将其抛回REST端点的调用方。我不希望这种情况发生,因为我希望所有这些处理都在“后台”完成,因为消费者已经收到200响应。

所以,我的问题是,我将如何实现这种行为?我曾考虑使用队列等,但如果可能的话,理想情况下要避免使用这些组件。

1 个答案:

答案 0 :(得分:0)

使用Camel Websocket组件异步响应调用者。

来自Camel documentation

from("activemq:topic:newsTopic")
    .routeId("fromJMStoWebSocket")
    .to("websocket://localhost:8443/newsTopic?sendToAll=true&staticResources=classpath:webapp");