Spring集成使用和方法验证

时间:2017-06-27 14:41:01

标签: spring spring-integration spring-integration-dsl spring-integration-aws

我正在测试使用Spring Integration将目前同一个Spring-Boot应用程序中的不同模块连接在一起,并将服务整合到一个统一的流程中,从单入口点开始。

如果可能,我正在寻找Spring Integration的以下说明:

  1. 下面的代码是使用DSL构建流程的正确方法吗?
  2. 在" C"在下面,我可以将结果冒泡到" B"流?
  3. 使用DSL与XML是比较好的方法吗?
  4. 我很困惑如何正确地"终止"一个流程?
  5. 流程概述

    在下面的代码中,我只是将一个页面发布到目的地。整体流程是这样的。

    1. 发布者流侦听有效负载并将其拆分为多个部分。
    2. 内容流过滤掉页面并将其拆分为多个部分。
      1. AWS流程订阅并处理该部分。
      2. 文件流订阅并处理该部分。
    3. 最终,发布商流程中可能存在其他非常不同类型的消费者,这些消费者不是内容,这就是我将发布者与内容分开的原因。

      A)发布流程(publisher.jar):

      这是我的"主要"通过网关发起的流量。意图是,这可以作为开始触发所有发布流程的入口点。

      1. 收到消息
      2. 预处理邮件并保存。
      3. 将有效负载拆分为其中包含的各个条目。
      4. 使用其余数据填充每个条目
      5. 将每个条目放在输出通道上。
      6. 以下是代码:

        @Bean
        IntegrationFlow flowPublish()
        {
            return f -> f
                .channel(this.publishingInputChannel())
                //Prepare the payload
                .<Package>handle((p, h) -> this.save(p))
                //Split the artifact resolved items
                .split(Package.class, Package::getItems)
                //Find the artifact associated to each item (if available)
                .enrich(
                    e -> e.<PackageEntry>requestPayload(
                        m ->
                        {
                            final PackageEntry item = m.getPayload();
                            final Publishable publishable = this.findPublishable(item);
                            item.setPublishable(publishable);
                            return item;
                        }))
                //Send the results to the output channel
                .channel(this.publishingOutputChannel());
        }
        

        B)内容流(content.jar)

        该模块的职责是处理传入的内容&#34;有效载荷(即本例中为Page)并将它们分割/路由到适当的用户。

        1. 聆听发布商输出频道
        2. 仅按页面类型过滤条目
        3. 将原始有效内容添加到标题中以供日后使用
        4. 将有效负载转换为实际类型
        5. 将页面拆分为各个元素(块)
        6. 将每个元素路由到相应的PubSub频道。
        7. 至少目前,订阅的流程不会返回任何响应 - 它们应该只是触发并忘记但是我想知道在使用pub-sub通道时如何冒泡结果。

          以下是代码:

          @Bean
          @ContentChannel("asset")
          MessageChannel contentAssetChannel()
          {
              return MessageChannels.publishSubscribe("assetPublisherChannel").get();
          
              //return MessageChannels.queue(10).get();
          }
          
          @Bean
          @ContentChannel("page")
          MessageChannel contentPageChannel()
          {
              return MessageChannels.publishSubscribe("pagePublisherChannel").get();
          
              //return MessageChannels.queue(10).get();
          }
          
          @Bean
          IntegrationFlow flowPublishContent()
          {
              return flow -> flow
                  .channel(this.publishingChannel)
                  //Filter for root pages (which contain elements)
                  .filter(PackageEntry.class, p -> p.getPublishable() instanceof Page)
                  //Put the publishable details in the header
                  .enrichHeaders(e -> e.headerFunction("item", Message::getPayload))
                  //Transform the item to a Page
                  .transform(PackageEntry.class, PackageEntry::getPublishable)
                  //Split page into components and put the type in the header
                  .split(Page.class, this::splitPageElements)
                  //Route content based on type to the subscriber
                  .<PageContent, String>route(PageContent::getType, mapping -> mapping
                      .resolutionRequired(false)
                      .subFlowMapping("page", sf -> sf.channel(this.contentPageChannel()))
                      .subFlowMapping("image", sf -> sf.channel(this.contentAssetChannel()))
                      .defaultOutputToParentFlow())
                  .channel(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME);
          }
          

          C)AWS Content(aws-content.jar)

          此模块是内容特定流程的众多潜在订阅者之一。它根据上面发布的路由通道单独处理每个元素。

          1. 订阅相应的频道。
          2. 妥善处理行动。
          3. 可以有多个流程订阅上述路由输出通道的模块,这只是其中之一。

            例如,&#34; contentPageChannel&#34;可以调用下面的flowPageToS3(在aws模块中)和一个flowPageToFile(在另一个模块中)。

            以下是代码:

            @Bean
            IntegrationFlow flowAssetToS3()
            {
                return flow -> flow
                    .channel(this.assetChannel)
                    .publishSubscribeChannel(c -> c
                        .subscribe(s -> s
                            .<PageContent>handle((p, h) ->
                                                 {
                                                     return this.publishS3Asset(p);
                                                 })));
            }
            
            @Bean
            IntegrationFlow flowPageToS3()
            {
                return flow -> flow
                    .channel(this.pageChannel)
                    .publishSubscribeChannel(c -> c
                        .subscribe(s -> s
                            .<Page>handle((p, h) -> this.publishS3Page(p))
                            .enrichHeaders(e -> e.header("s3Command", Command.UPLOAD.name()))
                            .handle(this.s3MessageHandler())));
            }
            

1 个答案:

答案 0 :(得分:1)

首先,您的问题中有很多内容:在阅读过程中很难保留所有信息。这是你的项目,所以你应该对这个主题非常有信心。但对于我们来说,这是一种新的东西,甚至可能只是放弃阅读,而不是试图回答。

无论如何,我会在一开始就尝试回答你的问题,虽然我觉得你要开始长时间的讨论&#34;什么?,怎么样?为什么?&#34; ...

  

下面的代码是使用DSL构建流的正确方法吗?

这完全取决于你的逻辑。在逻辑组件之间区分它是个好主意,但这可能是在此问题上切断单独jar的开销。看一下对我来说似乎仍然像你一样的代码,你仍然会将所有内容收集到单个Spring Boot应用程序中,只需要@Autowired @Configuration @Configuration个适当的通道。所以,是的,单独的return是个好主意,但是单独的jar是一个开销。 IMHO。

  

In&#34; C&#34;在下面,我可以将结果冒泡到&#34; B&#34;流?

好吧,因为故事是关于发布 - 订阅,等待回复真的很不寻常。你会从这些订阅者那里得到多少回复?是的,这就是问题 - 我们可以发送给很多订阅者,但是我们无法获得所有订阅者的回复。让我们回到Java代码:我们可以有几个方法参数,但我们只有一个void。这在消息传递中也适用。无论如何,您可以查看Scatter-Gather模式实现。

  

使用DSL与XML是更好的方法吗?

两者都只是一个高级API。下面有相同的集成组件。在您的应用中,您将使用XML配置来使用相同的分布式解决方案。没有理由退出Java DSL。至少它对你来说不那么冗长。

  

我很困惑如何正确地&#34;终止&#34;一个流程?

这绝对不清楚你的大描述。如果您发送到S3或文件,这是一个终止。这些组件没有回复,所以无处可去,无事可做。那就是停止。与void的Java方法一样。如果您担心入口点网关,那么只需将其设为 $http({ method: 'POST', headers: { 'Content-Type': 'application/json' }, url: URL }).then(function successCallback(response) { console.log(response.data); }, function errorCallback(response) { console.log(response.status); console.log(response.headers); console.log(response.config); }); 并且不要等待任何回复。有关详细信息,请参阅Messaging Gateway