无法使用错误的方法聚合邮件?

时间:2017-03-07 18:12:40

标签: java spring spring-integration

我是Spring Integration的新手。我无法弄清楚如何解决以下情况。

我有两个通道为最终消息生成两个关键数据,这些数据将被发送到REST端点。

  1. 轮询频道定期生成OAuth2令牌并发布(供此频道和其他频道使用)
  2. 文件监视通道生成有效负载(从文件加载有效负载的内容)
  3. 我需要将通道1的标记添加到通道2的标题中,类似于此图:

                         other channels            __ Ch3 (uses token)
                         subscribed to the -->    /
                         publishing channel    --+ -- Ch4 (uses token)
                                              /   \__ Ch5 (uses token)
    Ch1 ==> getToken ==> enrich header & publ.
                                              \    Merge
                                               ==> Token &  ==> Send to endpoint
                                              /    Payload
    Ch2 ==>  readFile ==>  create new Payload
    

    我尝试使用聚合器,但我不确定如何使用相关策略或发布策略。

    我的问题是:

    1. 聚合器是否可行? (或者可能还有另一种方法?)
    2. 关于相关/发布策略可能是什么的任何建议?
    3. 任何指示都将不胜感激。

      这是我到目前为止所拥有的:

      <!-- channels -->
      <int:channel id="aggregatedMsgOutChannel"/>
      
      <!-- Token messages are published to here -->
      <int:publish-subscribe-channel id="tokenInChannel" />
      
      <!-- Message Aggregator -->
      <int:aggregator
              id="messageAndOauthTokenAggregator"
              input-channel="tokenInChannel"
              message-store="simpleMessageStore"
              ref="oauthTokenAggregator"
              method="aggregate"
              output-channel="aggregatedMsgOutChannel">
       </int:aggregator>
      
       <!-- Define a store for our messages -->
       <bean id="simpleMessageStore" class="org.springframework.integration.store.SimpleMessageStore" />
      
      <bean id="oauthTokenAggregator" class="c.s.i.OauthTokenAggregator">
      

      OauthTokenAggregator.java

      @Component
      public class OauthTokenAggregator{
          private static final Logger log = LoggerFactory.getLogger(OauthTokenAggregator.class);
      
          @Aggregator
          public Message aggregate(Collection<Message<?>> messages) {
              log.debug("aggregating...");
      
              //.... Unsure as to how to fill this section
      
              return new GenericMessage("test");
          }
      }
      

2 个答案:

答案 0 :(得分:1)

我认为你采用聚合器正确的方式。

  1. 您应该为生成的令牌和文件内容选择一些公共属性。我很确定它必须存在,否则如果没有聚合器或Spring Integration,你会如何连接呢?

  2. 发布策略看起来非常简单 - 只需2 - 令牌和有效负载。

  3. 聚合函数实际上只能根据文件内容生成一条消息作为有效负载 - 来自一条消息。并将令牌放入另一条消息的标题中。您可以通过有效负载类型或其中的某些标头来区分消息。

  4. 只有我不了解你的业务逻辑的问题,所以,我无法为你提供好的建议。也许您不应该使用单独的轮询通道适配器,而是使用文件进程生成令牌?..

    或者......如果它们是单独生成的,那么每个文件只能从某个队列中轮询令牌,并且可以在其他地方使用。

    这是没有聚合器的变体。如果我们坚持使用那个,除非在文件和令牌之间选择一些相关性,否则我们没有选择。

答案 1 :(得分:0)

我最终使用@Artem的建议方法:在文件过程中生成一个令牌。

主要实施的功劳来自此article in DZone。复制代码以获得完整性(完全归功于文章的作者)。

所以,基本上,

  1. 我在第一个chain启动了文件处理,将其检入声明检入并将其UUID放入我的标题中。

  2. 而不是在中间使用chain

  3. <int:service-activator expression="new String('different string')"/>

    我去取了一个令牌并将其添加到我的标题中

    1. 继续上一个chain,从索赔检查中获取我的有效负载并将其发布到REST端点

          

      <int:chain input-channel="claim-check-in-channel"
                 output-channel="processing-channel">
          <int:claim-check-in message-store="simpleMessageStore"/>
          <int:header-enricher>
              <int:header 
      
                  name="#{T(com.l8mdv.sample.ClaimCheckGateway).CLAIM_CHECK_ID}"
                  expression="payload"/>
          </int:header-enricher>
      </int:chain>
      
      <int:chain input-channel="processing-channel"
                 output-channel="claim-check-out-channel">
          <int:service-activator expression="new String('different string')"/>
      </int:chain>
      
      <int:chain input-channel="claim-check-out-channel">
          <int:transformer
                  expression="headers.get('#{T(com.l8mdv.sample.ClaimCheckGateway)
                  .CLAIM_CHECK_ID}')"/>
          <int:claim-check-out message-store="simpleMessageStore"
                               remove-message="true"/>
      </int:chain>