8

我是 Camel 的新手,想知道如何使用 Camel 实现下面提到的用例,

我们有一个 REST Web 服务,假设它有两个服务操作 callA 和 callB。现在我们在前面有 ESB 层,它在访问这个实际的 Web 服务 URL 之前拦截客户端请求。

现在我正在尝试做这样的事情 - 在 ESB 中公开一个客户端将实际调用的 URL。在 ESB 中,我们使用 Camel 的 Jetty 组件,它只是代理此服务调用。所以假设这个 URL 是 /my-service/scan/

现在在收到此请求@ESB 时,我想调用这两个 REST 端点(callA 和 callB)-> 获取它们的响应 - resA 和 resB -> 将其聚合到单个响应对象 resScan -> 返回到客户端。

我现在只有——

<route id="MyServiceScanRoute">
<from uri="jetty:http://{host}.{port}./my-service/scan/?matchOnUriPrefix=true&amp;bridgeEndpoint=true"/>
<!-- Set service specific headers, monitoring etc. -->  
<!-- Call performScan -->
<to uri="direct:performScan"/>
</route>

<route id="SubRoute_performScan">
<from uri="direct:performScan"/>
<!--  HOW DO I??
Make callA, callB service calls. 
Get their responses resA, resB.
Aggregate these responses to resScan
 -->
</route>
4

2 回答 2

16

我认为您不必要地使解决方案复杂化了一点。:) 在我看来,调用两个独立的远程 Web 服务并连接结果的最佳方法是:

上述解决方案的路由可能如下所示:

from("direct:serviceFacade")
  .multicast(new GroupedExchangeAggregationStrategy()).parallelProcessing()
    .enrich("http://google.com?q=Foo").enrich("http://google.com?q=Bar")
  .end();

传递给的 Exchangedirect:serviceFacadeResponse将包含Exchange.GROUPED_EXCHANGE设置为调用您的服务的结果列表的属性(在我的示例中为 Google 搜索)。

这就是你如何连接direct:serviceFacade到 Jetty 端点:

from("jetty:http://0.0.0.0:8080/myapp/myComplexService").enrich("direct:serviceFacade").setBody(property(Exchange.GROUPED_EXCHANGE));

现在,您在 ESB 上使用 Jetty 组件公开的对服务 URL 的所有 HTTP 请求都将生成从对子服务的两个调用连接起来的响应。

关于消息和端点的动态部分的进一步考虑

在许多情况下,在端点中使用静态 URL 不足以满足您的需求。您可能还需要准备有效负载,然后再将其传递给每个 Web 服务。

一般来说 - 用于实现动态端点或有效负载参数的路由类型高度依赖于您用于使用 Web 服务的组件(HTTPCXFRSRestlet、RSS 等)。每个组件的程度和您可以动态配置它的方式各不相同。

如果您的端点/有效负载应该受到动态影响,您还可以考虑以下选项:

使用onPrepareRef多播端点的选项对传递给每个端点的交换副本进行预处理。您可以使用它来引用自定义处理器,该处理器将在将有效负载传递到多播端点之前对其进行修改。这可能是使用 HTTP 组件的 Exchange.HTTP_URI 标头组合 onPrepareRef 的好方法。

使用收件人列表(也parallelProcessing像多播一样提供)来动态创建 REST 端点 URL。

使用拆分模式parallelProcessing启用)将请求拆分为专用于每个服务的较小消息。再次,此选项可以很好地与Exchange.HTTP_URIHTTP 组件的标头一起使用。仅当可以使用相同的端点类型定义两个子服务时,这才有效。

如您所见,Camel 非常灵活,可让您以多种方式实现目标。考虑您的问题的背景并选择最适合您的解决方案。

如果您向我展示您希望在对聚合服务的每个请求上调用的 REST URL 的更具体示例,我可以建议您选择哪种解决方案以及如何实现它。特别重要的是要知道请求的哪一部分是动态的。我还需要知道您要使用哪个服务使用者(这取决于您将从服务接收到的数据类型)。

于 2012-05-21T12:56:42.383 回答
2

这看起来是一个很好的例子,应该使用 Content Enricher 模式。在这里描述

<from uri="direct:performScan"/>
   <enrich uri="ServiceA_Uri_Here" strategyRef="aggregateRequestAndA"/>
   <enrich uri="ServiceA_Uri_Here" strategyRef="aggregateAandB"/>
</route>

聚合策略必须用 Java 编写(或者可能是某种脚本语言,Scala/groovy? - 但我没有尝试过)。

聚合策略只需要一个实现 org.apache.camel.processor.aggregate.AggregationStrategy 的 bean,这反过来又需要您实现一个方法:

Exchange aggregate(Exchange oldExchange, Exchange newExchange);

因此,现在由您将请求与来自丰富服务调用的响应合并。你必须做两次,因为你有 callA 和 callB。有两种预定义的聚合策略可能有用也可能没用,UseLatestAggregationStrategy 和 UseOriginalAggregationStrategy。这些名称是非常自我解释的。

祝你好运

于 2012-05-16T09:09:09.397 回答