【问题标题】:Camel Reslet Component with async processing带有异步处理的 Camel Reslet 组件
【发布时间】:2014-11-01 02:39:43
【问题描述】:

我有如下要求:

  • 接受包含 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") 行中。

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

所以,我的问题是,我将如何实现这种行为?我曾考虑过使用队列等,但如果可能的话,最好避免使用此类组件。

【问题讨论】:

  • 您是说您响应了两次,一次是同步的,一次是异步的,这充其量是奇怪的,在最坏的情况下是不可能的。您可以做的是使用 Websockets 之类的东西或 Atmosphere 之类的抽象来继续将消息推送到客户端,但是所有消息都是异步的(这对您来说可能是一件好事)。要在 Camel 中获得异步行为,请参阅:camel.apache.org/async.html
  • 它们是我们的业务需求。客户想要一个同步响应来表明我们已成功收到他们的消息,并且他们想要在我们成功处理消息后进行异步回调。

标签: apache-camel


【解决方案1】:

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

来自Camel documentation

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

【讨论】:

    猜你喜欢
    • 2020-10-27
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 2020-02-28
    • 2017-08-29
    • 2018-07-21
    • 2016-09-06
    • 1970-01-01
    相关资源
    最近更新 更多