【问题标题】:Calling a list of rest api's from a route builder of a apache camel从 apache camel 的路由构建器调用 rest api 列表
【发布时间】:2016-11-18 06:33:56
【问题描述】:

我想在保存对象时从路由构建器调用 restApi 列表。

其余 API 主机列表将从属性文件中获取,暂时我已将其硬编码在代码本身中。

我没有找到任何用于RouteBuilder 的 forEach 循环

public class userApiRoute extends BaseApiRoute {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Override
    public void configure() throws Exception {

        super.configure(); String   hosts="http://127.0.0.1:10080/api.notification,http://123.123.123.123:10080";
        List<String> hostList = Arrays.asList(hosts.split("\\s*,\\s*"));

        rest("/api/user").post().description("Updates a User document")
        .type(User.class).consumes("application/json").route().routeId("UpdateUser").to("authService")
        .policy("apiUserPolicy").beanRef("userDefService", "save").choice().when(ifCSV)
        .to("userDefinitionFileNotifier").marshal(csv)
        .to("file://{{user.notification.location}}").when(ifMessaging)
        .to("userDefinitionMessageNotifier").wireTap("jms:queue:{{user.notification.location}}").
.to("userDefinitionApiNotifier")
.recipientList(constant("http://localhost:8081/api/test-api,http://localhost:8081/api/test-api2,http://localhost:8081/api/test-ap3"),",").aggregationStrategy(new userAggregationStrategy())
//.recipientList(constant("properties:{{api.hostList}}"),",").aggregationStrategy(new userAggregationStrategy())

        .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(201)).endRest();
    }
}
@Component("userDefinitionApiNotifier")
public class UserDefinitionApiNotifier implements Processor {

private final Logger log = LoggerFactory.getLogger(getClass());

@Override
public void process(Exchange exchange) throws Exception {

    String id = (String) exchange.getIn().getHeader("id");
    log.debug("creating message for - {}", id);
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("RECORD_TYPE", "Config_Update");
    jsonObject.put("ID", id);
    jsonObject.put("TYPE", "UserDefinition");

    if (jsonObject != null) {
        exchange.getOut().setHeader(Exchange.HTTP_METHOD, "POST");
        exchange.getOut().setHeader(Exchange.CONTENT_TYPE, "application/json");
        exchange.getOut().setBody(jsonObject.toString());
    }

}
public class userAggregationStrategy implements AggregationStrategy {

private final Logger log = LoggerFactory.getLogger(getClass());
@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
    log.debug("Aggregrator Start" );
    if (oldExchange == null) {
        log.debug("Aggregrator stop" );
        return newExchange;
    }
    String oldBody = oldExchange.getIn().getBody(String.class);
    String newBody = newExchange.getIn().getBody(String.class);
    String newUri = newExchange.getProperty(Exchange.RECIPIENT_LIST_ENDPOINT, String.class);
    String oldUri = oldExchange.getProperty(Exchange.RECIPIENT_LIST_ENDPOINT, String.class);
    log.debug("Aggregrator old body {}",oldBody );
    log.debug("Aggregrator body {}", newBody );
    log.debug("Aggregrator newuri {}", newUri );
    log.debug("Aggregrator olduri {}", oldUri );
    oldExchange.getIn().setBody(oldBody + "+" + newBody);
    log.debug("Aggregrator End" );
    return oldExchange;
}

}

我提到的网站是httpComponentloop

【问题讨论】:

  • 为什么需要循环?拆分列表并根据您可以在标题属性中设置的每个拆分的值调用 API
  • 我想遍历一个 API 地址列表,并通过设置一些对象数据向每个 Api 发送一个发布请求。
  • 您也可以使用拆分器模式来做到这一点。
  • @SoucianceEqdamRashti 我不知道如何将拆分后的 rest api 作为 uri 发送

标签: java apache rest routes apache-camel


【解决方案1】:

您实际上可以使用收件人列表将消息一次性发布到您的所有地址

.recipientList(method(<return your list of addresses>))

但如果你想迭代和推送,

将作为您的消息正文的消息对象保存在交换属性中,并将拆分应用于您要发布此对象的地址列表。在每次迭代期间,只需将消息从属性发布到正文中的地址。

.setProperty("message",body())
.split(method(<return your list of addresses>))
.setProperty("toAddress" , body())
.transform(exchangeProperty("message"))
.recipientList(exchangeProperty("toAddress"))

注意:确保地址的格式与您的组件的端点结构相匹配

【讨论】:

  • @Component("userDefinitionApiNotifier") public class UserDefinitionApiNotifier implements Processor { private final Logger log = LoggerFactory.getLogger(getClass()); @Override public void process(Exchange exchange) throws Exception { String operation = (String) exchange.getIn().getHeader("OPERATION"); Map message = new HashMap(); message.put("配置", 操作); if (message.isEmpty() == false) { exchange.getOut().setBody(message); } } } 并在路由中 .to("userDefinitionApiNotifier").recipientList(hostList );以上够了吗
  • 是的,逗号分隔的端点字符串将根据文档适用于收件人列表 .. 所以它应该可以工作。你必须像这样给它 .recipientList(constant(hostList),"," );
  • 我们可以将每个调用的响应映射到一个类吗? ,这会是一个发布请求吗?
  • 如果您想处理来自每个收件人的回复,然后使用聚合策略来处理每个回复并生成合并结果 .recipientList(constant(hostList),"," ).aggregationStrategy(new AggregationStrategy(){ public void aggregate(Exchange old , Exchange new){ // 处理来自 new 的主体的代码}})
  • sagar RecepientList 无法满足我的需要,我想将具有相同请求正文的发布请求发送到不同的休息 api。 .但是当我使用收件人列表时。 .它将body作为url并给出nosuch端点异常 jsonObject.put("RECORD_TYPE", "Config_Update"); jsonObject.put("ID", id); jsonObject.put("TYPE", "ProgramDefinition"); exchange.getOut().setHeader(Exchange.HTTP_METHOD, "POST"); exchange.getOut().setHeader(Exchange.CONTENT_TYPE, "application/json"); exchange.getOut().setBody(jsonObject);这就是我创建请求对象并调用 .recipientList(List).tokenize(",") 的方式
【解决方案2】:

尝试使用简单的表达式而不是常量.recipientList(simple("properties:{{api.hostList}}"),",")

如果您发现它仍然无法正常工作 .. 则将该字段保存在交换属性中 .. .setProperty("hostList" , simple("properties:{{api.hostList}}")) 然后使用.recipientList(exchangeProperty("hostList"),",")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多