Apache Camel :如何使用toD()有条件地设置头和集体,而不会过早封送?

mzaanser  于 2022-12-18  发布在  Apache
关注(0)|答案(1)|浏览(139)

我刚刚意识到Apache Camel中的choice()是用于动态路由的,所以每个choice()都需要一个to(),它不等同于Java中的if
但是,这是否意味着我不能有条件地将header设置为 Camel 交换?
我想做这样的事情:

from("direct:eventHttpChoice") // last step returns a composite POJO with config details and the actual message and token, let's call it MyCompositePojo
    .log(....) // I see this message in log
    .setHeader("Authorization", simple("Bearer ${body.token}"))
    .setHeader(Exchange.HTTP_METHOD, simple("${body.httpMethod.name}"))
    .choice()
        .when(simple("${body.httpMethod.name} in 'PUT,DELETE'"))
            .setHeader(Exchange.HTTP_PATH, simple("${body.newEvent.number}"))
        .endChoice()
    .end()
    .choice()
        .when(simple("${body.httpMethod.name} in 'POST,PUT'"))
            .setHeader(HttpHeaders.CONTENT_TYPE, constant(MediaType.APPLICATION_JSON))
            .setBody(simple("${body.newEvent}")).marshal().json(JsonLibrary.Jsonb) // marshall here as toD() needs InputStream; and I believe here it converts my message to MyMessagePojo, the actual payload to send
        .endChoice()
        .otherwise() // DELETE
            .when(simple("${body.configDetail.http.deleteSomeField} == 'true' && ${body.newEvent.someField} != null && ${body.newEvent.someField} != ''"))
                .setHeader(Exchange.HTTP_QUERY, simple("someField=${body.newEvent.someField}&operationId=${body.newEvent.operationId}"))
            .endChoice()
            .otherwise()
                .setHeader(Exchange.HTTP_QUERY, simple("operationId=${body.newEvent.operationId}"))
            .endChoice()
        .endChoice()
    .end()
    .log(LoggingLevel.INFO, "Sending to this url: ${body.configDetail.url}") // I don't see this log
    .toD("${body.configDetail.url}", 10) // only cache at most 10 urls; I still need MyCompositePojo here

但我收到错误:
2022-12-14 10:44:49,213错误[org.阿帕.cam.pro.err.默认错误处理程序]( Camel ( Camel -1)线程#6 - JmsConsumer[我的队列])无法传递(消息ID:A9371 D97 F55900 C-000000000000000001,交换机ID为:A9371 D97 F55900 C-0000000000000001)。尝试输送后耗尽:捕获到1个异常:org.apache.camel.language.bean。运行时bean表达式异常:调用方法失败:配置详细信息为空,原因是:组织。apache。camel。组件。bean。未发现方法异常:方法名称:在Bean上找不到configDetail:[B@330cd22d的类型:[B关于交流:交换机[编号:A9371 D97 F55900 C-000000000000001]
MyCompositePojo有这个字段,但我不知道哪里搞错了。
如果你认为我做marshall()太早了,但是如果不是这样,我怎么设置body呢?因为没有.marshal(),我看到这个错误:
2022-12-14 12:25:41,772错误[org.阿帕.cam.pro.err.默认错误处理程序]( Camel ( Camel -1)线程#7 - JmsConsumer[page.large.sm.provisioning.events.online])无法传递(消息ID:65 FF 01 C9 FC 61 E66 - 000000000000011,交换机ID为:65 FF 01 C9 FC 61 E66 - 000000000000011)。尝试输送后耗尽:捕获到1个异常:org.apache.camel.language.bean。运行时bean表达式异常:调用方法失败:配置详细信息为空,原因是:组织。apache。camel。组件。bean。未发现方法异常:方法名称:在Bean上找不到configDetail:我的Pojo {xxx=xxx,...}类型:com.example.MyPojo在交易所上的位置:交换机[65 FF 01 C9 FC 61 E66 - 000000000000011]
所以,这意味着没有.marshal(),它会将消息体更改为MessagePojo;但我不想这样,我只想让body成为我原来的body的一部分,当它是HTTP DELETE时,我不想设置body,而且,在后面的过程中,我仍然需要我的复合pojo,我的意思是,我想设置HTTP body,只是有条件的,我不想改变exchange的body。
那么,如何有条件地设置头并发送到动态URL并设置正文呢?

jei2mxaa

jei2mxaa1#

另一种方法是用定制的(Java)处理器替换(Camel)选择逻辑。

from("direct:demo")
    .process( e -> setDynamicUri(e) );
    .toD("${headers.nextUri}");

private void setDynamicUri(Exchange e) {
    String httpMethod = e.getMessage().getHeader("...", String.class);
    String endpointUrl = ( Arrays.asList("PUT", "DELETE").contains(httpMethod) ? "url1" : "url2" );
    e.getMessage().setHeader("nextUri", endpointUrl);
}

相关问题