【发布时间】:2021-10-27 07:55:41
【问题描述】:
基本上,我的用例是在 HttpOutboundGateway 请求中出现 401 时重试 http 请求。该请求来自一个 jms 代理进入集成流。
@Bean
IntegrationFlow bank2wallet(ConnectionFactory jmsConnectionFactory,
MessageHandler creditWalletHttpGateway) {
return IntegrationFlows.from(Jms.messageDrivenChannelAdapter(jmsConnectionFactory)
.destination(cp.getTransactionIn()))
.<String, CreditRequest>transform(
request -> new Gson().fromJson(request, CreditRequest.class))
.enrichHeaders((headerEnricherSpec -> {
// Todo get token from cache
headerEnricherSpec.header(HttpHeaders.AUTHORIZATION, String.join(" ", "Bearer", ""));
headerEnricherSpec.header(HttpHeaders.ACCEPT, "application/json");
headerEnricherSpec.header(HttpHeaders.CONTENT_TYPE, "application/json");
}))
.handle(creditWalletHttpGateway, (e) -> e.advice(retryAdvice()))
.get();
}
@Bean
MessageHandler creditWalletHttpGateway( @Value("${api.base.uri:https:/localhost/v3/sync}") URI uri) {
HttpRequestExecutingMessageHandler httpHandler = new HttpRequestExecutingMessageHandler(uri);
httpHandler.setExpectedResponseType(CreditResponse.class);
httpHandler.setHttpMethod(HttpMethod.POST);
return httpHandler;
}
@Bean
RequestHandlerRetryAdvice retryAdvice() {
RequestHandlerRetryAdvice requestHandlerRetryAdvice = new RequestHandlerRetryAdvice();
requestHandlerRetryAdvice.setRecoveryCallback(errorMessageSendingRecoverer());
return requestHandlerRetryAdvice;
}
@Bean
ErrorMessageSendingRecoverer errorMessageSendingRecoverer() {
return new ErrorMessageSendingRecoverer(recoveryChannel());
}
@Bean
MessageChannel recoveryChannel() {
return new DirectChannel();
}
@Bean
MessageChannel retryChannel() {
return new DirectChannel();
}
@Bean
IntegrationFlow handleRecovery() {
return IntegrationFlows.from("recoveryChannel")
.log(Level.ERROR, "error", m -> m.getPayload())
.<RuntimeException>handle((message) -> {
MessagingException exception = (MessagingException) message.getPayload();
Message<CreditRequest> originalCreditRequest = (Message<CreditRequest>) exception.getFailedMessage();
// String token = gateway.getToken(configProperties);
String token = UUID.randomUUID().toString();
Message<CreditRequest> c = MessageBuilder.fromMessage(originalCreditRequest)
.setHeader(ApiConstants.AUTHORIZATION, String.join(" ", "Bearer", token))
.copyHeaders(message.getHeaders())
.build();
retryChannel().send(c);
})
.get();
}
@Bean
IntegrationFlow creditRequestFlow() {
return IntegrationFlows.from(retryChannel())
.log(Level.INFO, "info", m -> m.getPayload())
.handle(Http.outboundGateway("https://localhost/v3/sync")
.httpMethod(HttpMethod.POST)
.expectedResponseType(CreditResponse.class))
.get();
}
标头使用适当的 http 标头丰富, 然后我有一个建议,用默认的简单策略重试请求,RequestHandlerAdvice 方法的问题是它将 handleRecovery 流中的异常消息默认为无 HttpException 类 (MessageException),因此我无法检查 HttpStatus 代码以重新路由消息。所以我的问题基本上是我如何设计一个基于 HttpStatus 401 重试 HttpOutBoundRequest 的流程。
【问题讨论】:
标签: spring-boot spring-integration spring-integration-dsl