简体   繁体   中英

Spring Integration Queue Error Handling

I have a Spring Integration DSL flow which pulls in data from a rest API, transforms it and sends it through to a different rest API.

After data is fetched, it sends a message into a queue channel which does the rest of the processing. While the queue is working the original thread goes and fetches more data.

The issue that I am having is that any errors thrown from the queue are not processed until it has finished processing all the data, but I want it to stop the processing and throw the error right away because the whole process can take a long time but I want it to stop on the first error found.

Gateway:

@MessagingGateway(errorChannel = "syncErrorChannel")
@Service
public interface CrmGateway {
  @Gateway(requestChannel = "departmentSyncInput", replyChannel = "departmentSyncOutput")
  @Payload("new String()")
  Object syncDepartments();
}

Flow:

/**
   * Fetches data from the source api and passes it on to the split channel to process it If the
   * response indicates it has more data to fetch then it is also loaded
   *
   * @return {@link IntegrationFlow}
   */
  @Bean
  IntegrationFlow sync() {
    return IntegrationFlows
      .from("departmentSyncInput")
      .handle(this::fetchDomain)
      .enrichHeaders(s -> s.headerExpressions(h -> h.put("nextLink", "payload.getNext()")))
      .routeToRecipients(r -> r
        .recipient("departmentSplitChannel")
        .recipient(
          "departmentSyncInput",
          p -> p.getPayload() instanceof Wrapper
            && ((Wrapper) p.getPayload()).getNext() != null
        ))
      .get();
  }

  /**
   * Split data from the api into individual models and send them to the target service
   *
   * @return {@link IntegrationFlow}
   */
  @Bean
  IntegrationFlow split() {
    return IntegrationFlows
      .from("departmentSplitChannel")
      .transform(Wrapper.class, Wrapper::getContent)
      .split()
      .channel(c -> c.executor(Executors.newScheduledThreadPool(100)))
      .enrichHeaders(h -> h.header("errorChannel", "syncErrorChannel"))
      .handle((payload, headers) -> log("Syncing", payload, payload))
      .transform(Department.class, transformer)
      // exception happens here
      .handle(DepartmentDTO.class, (payload, headers) -> service.upsertDepartment(payload))
      .handle((payload, headers) -> log("Synced", payload, payload))
      .aggregate()
      .get();
  }

Error handler:

@Bean
  IntegrationFlow errorHandler() {
    return IntegrationFlows
      .from("syncErrorChannel")
      .handle(Exception.class, (payload, headers) -> {
        payload.printStackTrace();
        return payload;
      })
      .get();
  }

I also tried using IntegrationFlows.from("errorChannel") with the same results.

I have tried using a Future too and it behaves the same so that when I call get() I get the error, but this is still happening at the end.

Thanks for any help.

There is no queue channel definition in your flow, but I guess you mean that .channel(c -> c.executor()) . Would be better if you share logs on the matter as well.

What I can say that you try to override errorChannel header which is TemporaryReplyChannel in case of Gateway.

So, the error is send to the gateway's process and crashes it in case of split .

I suggest you to try with the h.header("errorChannel", "syncErrorChannel", true) to really override that header.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM