簡體   English   中英

如何在 Spring 集成中處理 http 響應異常並繼續流程直到聚合

[英]How to handle http response exception and continue the flow till aggregate in Spring integration

我在我的項目中使用 Spring-integration,使用的模式是分散聚集。 這里正在執行三個並行過程。 flow2 是一個出站網關方法,如果該服務關閉,那么我想處理 Httpstatus 異常並希望發送 null。 實際上,如果該服務關閉,那么整個流程就會停止。 但我想處理該異常並發送 null,然后想繼續使用聚合方法並結束流程。

下面是代碼——

//配置文件

 @Configuration
        public class IntegrationConfiguration {
          @Autowired LionsServiceImpl lionsService;
        
          long dbId = new SequenceGenerator().nextId();
      //   Main flow
      @Bean
  public IntegrationFlow flow() {
    return flow ->
        flow.handle(validatorService, "validateRequest")
            .split()
            .channel(c -> c.executor(Executors.newCachedThreadPool()))
            .scatterGather(
                scatterer ->
                    scatterer
                        .applySequence(true)
                        .recipientFlow(flow1())
                        .recipientFlow(flow2())
                        .recipientFlow(flow3()),
                gatherer ->
                    gatherer
                        .releaseLockBeforeSend(true)
                        .releaseStrategy(group -> group.size() == 2))
            .aggregate(prepareSomeRequest())
            .to(getDec());
  }

  //   Saving the request to the database
  @Bean
  public IntegrationFlow flow1() {
    return integrationFlowDefinition ->
        integrationFlowDefinition
            .channel(c -> c.executor(Executors.newCachedThreadPool()))
            .handle(
                (payload, header) -> {
                  ObjectMapper mapper = new ObjectMapper();
                  try {
                    String jsonString = mapper.writeValueAsString(payload);
                    JsonNode request = mapper.readTree(jsonString);
                    JsonNode csID = request.get("ApplicationDetails").get("CustomerId");
                    int customerID = mapper.treeToValue(csID, Integer.class);

                    return lionService.saveRequest(
                        payload,
                        String.valueOf(dbId),
                        customerID,
                        ((SourceSystem) Objects.requireNonNull(header.get("sourceSystem")))
                            .getSourceSystemCode());
                  } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                  }
                }
                )
            .nullChannel();
  }

  // 
  @Bean
  public IntegrationFlow flow3() {
    return integrationFlowDefinition ->
        integrationFlowDefinition
            .channel(c -> c.executor(Executors.newCachedThreadPool()))
            .transform(
                message ->
                    loansService.someMethod(
                        (LionRequest) message));
  }

 //Here I'm calling a service through HTTPOUTBOUNDGATEWAY and if that called service is down then it throws HTTP STAtus error so I want to handle that and want to send null from this flow.
  @Bean
  public IntegrationFlow flow2() {
    return integrationFlowDefinition ->
        integrationFlowDefinition
            .channel(c -> c.executor(Executors.newCachedThreadPool()))
            .handle(
                (payload, header) ->
                    loansService.someMethod2(
                        (LionRequest) payload,
                        (SourceSystem) (Objects.requireNonNull(header.get("sourceSystem")))))
            .handle(
                Http.outboundGateway(someurl)
                    .httpMethod(HttpMethod.POST)
                    .expectedResponseType(String.class)
                       );
  }


  @Bean
  public IntegrationFlow getDec() {
    return flow ->
        flow.handle(
            Http.outboundGateway(ServiceURL)
                .httpMethod(HttpMethod.POST)
                .expectedResponseType(CrResponse.class));
  }


  @Bean
  public MessageChannel replyChannel() {
    return MessageChannels.executor("output-flow", outputExecutor()).get();
  }

  @Bean
  public ThreadPoolTaskExecutor outputExecutor() {
    ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
    pool.setCorePoolSize(4);
    pool.setMaxPoolSize(4);
    return pool;
  }


//here I want to take out null from messages which is sent by flow2 if the called service is down and then I want to send null to someMethod2 method.

  public MessageGroupProcessor prepareSomeRequest() {
    return group -> {
      String cData;
      Object CDReq;

      List<Message<?>> messages = group.streamMessages().collect(Collectors.toList());

      ArrayList<Object> payloads = (ArrayList<Object>) messages.get(0).getPayload();

      if (payloads.get(0).toString().contains("tribv")) {
        cData= payloads.get(0).toString();
        logger.atInfo().log("Customer data from Data Sourcing Service : " + cData);
        CDReq= payloads.get(1);
      } else {
        cData= payloads.get(1).toString();
        logger.atInfo().log("Customer data from Data Sourcing Service : " + cData);
        CDReq = payloads.get(0);
      }

      Object fReq =
          lionservice.someMethod2(cData, CDReq);

      SomeRequest somreq= new SomeRequest();

      ObjectMapper mapper = new ObjectMapper();

      JsonNode req = mapper.valueToTree(freq);
      creditDecisionRequest.setfsfgg(req);
      creditDecisionRequest.setR("234565432");
      creditDecisionRequest.setD(String.valueOf(dbId));
      creditDecisionRequest.setCID("33333333");
      creditDecisionRequest.setSourceSystemCode(SourceSystem.ONE.getSourceSystemCode());

      return somreq;
    };
  }

網關

    @Gateway(requestChannel = "flow.input")
  void processLionRequest(
      @Payload Message lionRequest, @Header("sourceSystem") SourceSystem sourceSystem);

我可以在出站網關中使用類似.errorHandler()的東西嗎? 但是我該如何使用呢?

 @Bean
  public IntegrationFlow flow2() {
    return integrationFlowDefinition ->
        integrationFlowDefinition
            .channel(c -> c.executor(Executors.newCachedThreadPool()))
            .handle(
                (payload, header) ->
                    lionService.prepareSomeRequest(
                        (LionRequest) payload,
                        (SourceSystem) (Objects.requireNonNull(header.get("sourceSystem")))))
            .handle(
                Http.outboundGateway(someurl)
                    .httpMethod(HttpMethod.POST)
                    .expectedResponseType(String.class),
                c -> c.advice(expressionAdvice()));
  }

  @Bean
  public Advice expressionAdvice() {
    ExpressionEvaluatingRequestHandlerAdvice advice =
        new ExpressionEvaluatingRequestHandlerAdvice();
    advice.setFailureChannelName("failure.input");
    advice.setTrapException(true);
    return advice;
  }

  @Bean
  public IntegrationFlow success() {
    return f -> f.handle(System.out::println);
  }

  @Bean
  public IntegrationFlow failure() {
    return f -> f.handle(adviceOnFailure());
  }

  public String adviceOnFailure() {
    return "Failed";
  }

我正在做類似的事情,但出現如下錯誤 -

Caused by: java.lang.IllegalArgumentException: Found ambiguous parameter type [class java.lang.String] for method match: [public byte[] java.lang.String.getBytes(java.nio.charset.Charset), public static java.lang.String java.lang.String.valueOf(double), public boolean java.lang.String.contains(java.lang.CharSequence), public static java.lang.String java.lang.String.copyValueOf(char[]), public java.lang.String[] java.lang.String.split(java.lang.String), public native java.lang.String java.lang.String.intern(), public java.lang.String java.lang.String.repeat(int), public static java.lang.String java.lang.String.valueOf(char), public static java.lang.String java.lang.String.valueOf(boolean), public static java.lang.String java.lang.String.valueOf(java.lang.Object), public static java.lang.String java.lang.String.valueOf(float), public static java.lang.String java.lang.String.valueOf(long), public java.lang.String java.lang.String.toUpperCase(java.util.Locale), public boolean java.lang.String.contentEquals(java.lang.StringBuffer)]

請幫忙。

消息傳遞中沒有null payload概念,因此即使您處理錯誤,也絕對不能返回null作為該出站網關調用的回復。

請參閱框架中的請求處理程序建議模式,特別是ExpressionEvaluatingRequestHandlerAdvice實現。 它確實處理特定消息處理程序的錯誤,並可能返回補償回復,然后您可以分別聚合和處理。

文檔在這里: https ://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints.html#message-handler-advice-chain

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM