У меня есть проблема, которая кажется нерешенной ни в одном из примеров, которые я могу найти.
Мое приложение читает тему ActiveMQ о сообщениях JSON. Он построит совершенно новый исходящий вызов REST на основе этих данных. Обратите внимание, что это не «трансформация». Дана буква "X", произведена буква "Y", т.е. ServiceActivator.
Мои потоки до сих пор
public IntegrationFlow splitInputFlow() {
return IntegrationFlows.from("inboundJmsChannel")
.split()
.log(LoggingHandler.Level.DEBUG)
.route(Message.class, m -> m.getHeaders().get("x-bn-class").equals("Healthcheck.class") ? "healthcheckChannel" : "metricChannel")
.get();
}
public IntegrationFlow healthcheckFlow() {
return IntegrationFlows.from("healthcheckChannel")
.log(LoggingHandler.Level.DEBUG)
.transform(Transformers.fromJson(Healthcheck.class))
.handle("healthcheckActivator", "process")
.get();
}
Есть десятки примеров того, как использовать пружинные трансформаторы. Я даже подумывал попробовать MessageConverter. Но я не понимаю, почему это помогло бы, и это не кажется нормальным подходом.
Основная проблема заключается в том, что интеграция вызывает healthcheckActivator.process (String payload). Сама полезная нагрузка является ожидаемой допустимой строкой JSON.
Я немного удивлен, что он не вызывает healtcheckActivator.process (полезная нагрузка сообщения), но это не поможет, так что это не имеет большого значения.
Реальный вопрос - почему он не вызывает healtcheckActivator.process (Healthcheck healthcheck)?
Ну, на самом деле я понимаю, "почему". Это потому, что DSL генерирует внутренний канал, чтобы связать шаги вместе, и, насколько я понимаю, что-то на канале - это spring.messaging.Message.
Я могу легко создать экземпляр моего объекта Healthcheck, как только попаду внутрь SA. Но это оставляет насущный вопрос: что может быть хорошего во всем шаге преобразования? Если он всегда «сериализует» объект обратно в Сообщение - какой смысл.
Как я уже сказал, я думаю, что мне здесь не хватает чего-то фундаментального.
EDIT
Моя новая (и, вероятно, последняя) идея заключается в том, что, возможно, я публикую это неправильно.
Для публикации я использую
jmsTemplate.convertAndSend(topicName, healthcheck, messagePostProcessor -> {
messagePostProcessor.setJMSType("TextMessage");
messagePostProcessor.setStringProperty("x-bn-class", "Healthcheck.class");
messagePostProcessor.setStringProperty("x-bn-service-name", restEndpoint.getServiceName());
messagePostProcessor.setStringProperty("x-bn-service-endpoint-name", restEndpoint.getEndpointName());
messagePostProcessor.setLongProperty("x-bn-heathcheck-timestamp", queryDate);
messagePostProcessor.setStringProperty("x-bn-healthcheck-status", subsystemStatus.getStatus(subsystemStatus));
messagePostProcessor.setIntProperty("httpStatus", httpStatus.value());
return messagePostProcessor;
});
В методе SI-процесса (String payload) поступает следующее:
LoggingHandler - GenericMessage [payload={"healthcheckType":"LOCAL","outcome":"PASS","dependencyType":"DB","endpoint":"NODE TABLE","description":"Read from DB","durationSecs":0.025}, headers={x-bn-service-name=TG10-CS2, x-bn-service-endpoint-name=TG Q10-CS2 Ready Check, jms_destination=topic://HEALTH_MONITOR, _type=com.healthcheck.response.Healthcheck, x-bn-heathcheck-timestamp=1558356538000, priority=4, jms_timestamp=1558356544244, x-bn-healthcheck-status=SEV0, jms_redelivered=false, x-bn-class=Healthcheck.class, httpStatus=200, jms_type=TextMessage, id=b29ffea7-7128-c543-9a14-8bab450f0ac6, jms_messageId=ID:39479-1558356520091-1:2:1:1:1, timestamp=1558356544409}]
Я раньше не замечал параметр _type в заголовке jms_destination. Но прежде чем я начал разбираться с этим (потому что это не сработало), это правильное имя класса для того, что предоставила другая команда.
Я не реализовал конвертер сообщений JMS. Но прилагаемый SimpleMessageConverter кажется, что он должен делать именно то, что я хочу.