Я использую API, который работает в 2 этапа:
- Он запускает асинхронную обработку документа, предоставляя вам идентификатор, который вы используете для шага 2.
- Он предоставляет конечную точку, где вы можете получить результаты, но только когда они будут готовы. Таким образом, в основном он всегда будет давать вам ответ 200 с некоторыми деталями, такими как статус обработки.
Итак, вопрос в том, как я могу реализовать пользовательские критерии успеха для исходящего HTTP-шлюза. Я также хотел бы объединить его с RetryAdvice, который я уже реализовал.
Я пробовал следующее, но, во-первых, полезная нагрузка сообщения, предоставленная в HandleMessageAdvice, пуста, а во-вторых, повторная попытка не запускается:
.handle(Http.outboundGateway("https://northeurope.api.cognitive.microsoft.com/vision/v3" +
".0/read/analyzeResults/abc")
.mappedRequestHeaders("Ocp-Apim-Subscription-Key")
.httpMethod(HttpMethod.GET), c -> c.advice(this.advices.retryAdvice())
.handleMessageAdvice(new AbstractHandleMessageAdvice() {
@Override
protected Object doInvoke(MethodInvocation invocation, Message<?> message) throws Throwable {
String body = (String) message.getPayload();
if (StringUtils.isEmpty(body))
throw new RuntimeException("Still analyzing");
JSONObject document = new JSONObject(body);
if (document.has("analyzeResult"))
return message;
else
throw new RuntimeException("Still analyzing");
}
}))
Я нашел этот ответ от Артема 4 года назад, но, во-первых, я не нашел метод канала ответа на исходящем шлюзе и, во-вторых, не уверен, был ли этот сценарий уже улучшен в новой версии Spring Integaration: HTTP-повторная попытка исходящего трафика с условиями (для условия проверки).
ОБНОВЛЕНИЕ
По предложению Артема имею следующее:
.handle(Http.outboundGateway("https://northeurope.api.cognitive.microsoft.com/vision/v3" +
".0/read/analyzeResults/abc")
.mappedRequestHeaders("Ocp-Apim-Subscription-Key")
.httpMethod(HttpMethod.GET), c -> c.advice(advices.verifyReplySuccess())
.advice(advices.retryUntilRequestCompleteAdvice()))
И совет:
@Bean
public Advice verifyReplySuccess() {
return new AbstractRequestHandlerAdvice() {
@Override
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) {
try {
Object payload = ((MessageBuilder) callback.execute()).build().getPayload();
String body = (String) ((ResponseEntity) payload).getBody();
JSONObject document = new JSONObject(body);
if (document.has("analyzeResult"))
return message;
} catch (JSONException e) {
throw new RuntimeException(e);
}
throw new RuntimeException("Still analyzing");
}
};
}
Но теперь, когда я отлаживаю метод doInvoke, тело полезной нагрузки имеет значение null. Это странно, когда я выполняю тот же запрос GET с помощью Postman, тело возвращается правильно. Любая идея?
Тело ответа с использованием Postman выглядит так:
{
"status": "succeeded",
"createdDateTime": "2020-09-01T10:55:52Z",
"lastUpdatedDateTime": "2020-09-01T10:55:57Z",
"analyzeResult": {
"version": "3.0.0",
"readResults": [
{
"page": 1,........
Вот полезная нагрузка, которую я получаю от шлюза исходящей почты с помощью обратного вызова:
<200,[Transfer-Encoding:"chunked", Content-Type:"application/json; charset=utf-8", x-envoy-upstream-service-time:"27", CSP-Billing-Usage:"CognitiveServices.ComputerVision.Transaction=1", apim-request-id:"a503c72f-deae-4299-9e32-625d831cfd91", Strict-Transport-Security:"max-age=31536000; includeSubDomains; preload", x-content-type-options:"nosniff", Date:"Tue, 01 Sep 2020 19:48:36 GMT"]>