将bean路由模板参数传递到Camel中的bean端点

问题描述 投票:0回答:1

我正在使用 Camel 4.0.0-RC2 并遵循 有关将 beans 绑定到 RouteTemplate 的文档。我有一个简单的路线模板,可以从可配置的

fromEndpointUri
中使用,并将可配置的
foo
传递给我的
fooConsumer
:

routeTemplate("myTemplate")
  // Define the parameters for the route template.
  .templateParameter ("fromEndpointUri")
  .templateBean      ("foo", Foo.class)

  // Define the route.
  .from ("{{fromEndpointUri}}")
  .bean (fooConsumer, "processFoo(${body}, #{{foo}})");

我使用模板创建的路线很简单:

templatedRoute("myTemplate")
  .routeId   ("myTemplateRoute")
  .parameter ("fromEndpointUri", "direct:test")
  .bean      ("foo", Foo.class, ignored -> new Foo());

通过此路由发送消息时,会抛出错误

No type converter available to convert from type: java.lang.String to the required type: com.example.Foo
。相关的堆栈跟踪是:

org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: java.lang.String to the required type: com.example.Foo
    at org.apache.camel.impl.converter.CoreTypeConverterRegistry.mandatoryConvertTo(CoreTypeConverterRegistry.java:279) ~[camel-base-4.0.0-RC2.jar:4.0.0-RC2]
    at org.apache.camel.component.bean.MethodInfo$ParameterExpression.evaluateParameterValue(MethodInfo.java:717) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
    ... 94 more
Wrapped by: org.apache.camel.component.bean.ParameterBindingException: Error during parameter binding on method: public java.util.List com.example.FooConsumer.processFoo(java.lang.String,com.example.Foo) at parameter #1 with type: class com.example.Foo with value type: class java.lang.String and value: #foo-1
    at org.apache.camel.component.bean.MethodInfo$ParameterExpression.evaluateParameterValue(MethodInfo.java:728) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
    at org.apache.camel.component.bean.MethodInfo$ParameterExpression.evaluateParameterExpressions(MethodInfo.java:618) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
    at org.apache.camel.component.bean.MethodInfo$ParameterExpression.evaluate(MethodInfo.java:591) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
    at org.apache.camel.component.bean.MethodInfo.initializeArguments(MethodInfo.java:262) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
    at org.apache.camel.component.bean.MethodInfo.createMethodInvocation(MethodInfo.java:270) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
    at org.apache.camel.component.bean.BeanInfo.createInvocation(BeanInfo.java:266) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
    at org.apache.camel.component.bean.AbstractBeanProcessor.process(AbstractBeanProcessor.java:128) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
    at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:81) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
    ...

如何将路线的

Foo
实例传递给我的
FooConsumer
?我尝试过的一些变化是:

变化 错误
.bean(fooConsumer, "processFoo(${body}, {{foo}})")
No type converter available to convert from type: java.lang.String to the required type: com.example.Foo
.to("bean:fooConsumer?method=processFoo(${body},#{{foo}})")
No type converter available to convert from type: java.lang.String to the required type: com.example.Foo
.to("bean:fooConsumer?method=processFoo(${body},{{foo}})")
No type converter available to convert from type: java.lang.String to the required type: com.example.Foo
.bean(fooConsumer, "processFoo(${body}, ${bean:#{{foo}}})")
No bean could be found in the registry for: #foo-1
.bean(fooConsumer, "processFoo(${body}, ${bean:{{foo}}})")
No bean could be found in the registry for: foo-1

当然可以这样做,因为示例显示使用

myClient
语法将
aws2-s3
bean 传递到
#{{myClient}}
端点。

java apache-camel
1个回答
0
投票

我找到了一种使用这些路线模板的方法,就像我在这里尝试的那样,但感觉不太干净。也许我正在尝试以它们不应该使用的方式使用它们。不管怎样,为了让它工作,我在定义路由模板的类中创建了一个内部

ServiceActivator
类:

private class ServiceActivator {
  private final Foo foo;

  public ServiceActivator(final RouteTemplateContext routeTemplateContext) {
    this.foo = (
      routeTemplateContext
        .getLocalBeanRepository ()
        .lookupByNameAndType    ("foo", Foo.class)
      );
  }

  @Handler
  public void processFoo(@Body final String body) {
    // do something 
  }
}

然后,我将路线模板更新为:

  1. 删除
    foo
    的声明,因为拥有该定义会使 Camel 尝试为其创建默认值。
  2. 在创建路线时创建此
    ServiceActivator
  3. 参考路线定义中的
    ServiceActivator
    中的
    bean
routeTemplate("myTemplate")
  // Define the parameters for the route template
  .templateParameter ("fromEndpointUri")
  .templateBean      ("serviceActivator, ServiceActivator.class, ServiceActivator::new)

  // Define the route.
  .from("{{fromEndpointUri}}")
  .bean("{{serviceActivator}}")

并将我的模板路线保留为:

templatedRoute("myTemplate")
  .routeId   ("myTemplateRoute")
  .parameter ("fromEndpointUri", "direct:test")
  .bean      ("foo", Foo.class, ignored -> new Foo());

再次,这看起来几乎像是一种 hack,而不是按照 Camel 的预期用途来使用该功能。从我单步执行代码来看,路由模板参数和 bean 仅在创建路由时可用,因此这是在路由创建期间捕获所有信息的一种方法,以便在以后执行路由时使用。

© www.soinside.com 2019 - 2024. All rights reserved.