В качестве примера представьте себе шлюз, который находится в простом интеграционном потоке, который принимает String и переводит данную строку в верхний регистр. Интерфейс шлюза может выглядеть примерно так:
package com.example.demo;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.stereotype.Component;
@Component
@MessagingGateway(defaultRequestChannel="inChannel",
defaultReplyChannel="outChannel")
public interface UpperCaseGateway {
String uppercase(String in);
}
Что удивительно в этом интерфейсе, так это то, что его не нужно реализовывать. Spring Integration автоматически предоставляет реализацию во время выполнения, которая отправляет и получает данные по указанным каналам.
При вызове метода uppercase() данная String публикуется в потоке интеграции в канал с именем inChannel. И, независимо от того, как определяется поток или что он делает, когда данные поступают в канал с именем outChannel, он возвращается из метода верхнего uppercase().
Что касается потока интеграции в верхнем регистре, то это упрощенный процесс интеграции с единственным шагом преобразования String в верхний регистр. Опишем в конфигурации Java DSL:
@Bean
public IntegrationFlow uppercaseFlow() {
return IntegrationFlows
.from("inChannel")
.
.channel("outChannel")
.get();
}
Здесь описано, поток начинается с данных, поступающих в канал с именем inChannel. Затем полезная нагрузка сообщения преобразуется преобразователем, который здесь определен как лямбда-выражение, для выполнения операции преобразования в верхний регистр. Полученное сообщение затем публикуется в канал с именем outChannel, который вы объявили в качестве канала ответа для интерфейса UpperCaseGateway.
9.2.8 Канальные адаптеры
Канальные адаптеры представляют точки входа и выхода потока интеграции. Данные входят в поток интеграции через адаптер входящего канала и выходят из потока интеграции через адаптер исходящего канала. Это показано на рисунке 9.9.
Рис. 9.9. Адаптеры канала - это точки входа и выхода потока интеграции.
Адаптеры входящего канала могут принимать различные формы в зависимости от источника данных, вводимых в поток. Например, вы можете объявить адаптер входящего канала, который вводит инкрементные числа из AtomicInteger в поток. При использовании Java конфигурации это может выглядеть так:
@Bean
@InboundChannelAdapter(
poller=@Poller(fixedRate="1000"), channel="numberChannel")
public MessageSource
return () -> {
return new GenericMessage<>(source.getAndIncrement());
};
}
Этот @Bean метод объявляет компонент адаптера входящего канала, который в соответствии с аннотацией @InboundChannelAdapter отправляет число из введенного AtomicInteger в канал с именем numberChannel каждые 1 секунду (или 1000 мс).
Принимая во внимание, что @InboundChannelAdapter указывает адаптер входящего канала при использовании конфигурации Java, метод from() - это то, как это делается при использовании Java DSL для определения потока интеграции. В следующем фрагменте определения потока показан аналогичный адаптер входящего канала, определенный в Java DSL:
@Bean
public IntegrationFlow someFlow(AtomicInteger integerSource) {
return IntegrationFlows
.from(integerSource, "getAndIncrement", c -> c.poller(Pollers.fixedRate(1000)))
…
.get();
}
Часто адаптеры каналов предоставляются одним из множества модулей конечной точки Spring Integration. Предположим, например, что вам нужен адаптер входящего канала, который отслеживает указанный каталог и отправляет любые файлы, которые записываются в этот каталог, как сообщения в канал с именем file-channel. Следующая конфигурация Java использует FileReadingMessageSource из модуля Spring Integration’s file endpoint для достижения этой цели:
@Bean
@InboundChannelAdapter(channel="file-channel", poller=@Poller(fixedDelay="1000"))
public MessageSource
FileReadingMessageSource sourceReader = new FileReadingMessageSource();
sourceReader.setDirectory(new File(INPUT_DIR));
sourceReader.setFilter(new SimplePatternFileListFilter(FILE_PATTERN));
return sourceReader;
}
При записи эквивалентного адаптера входящего канала для чтения файлов в Java DSL метод inboundAdapter() из класса Files выполняет то же самое. Адаптер внешнего канала - это конец строки для процесса интеграции, передающий окончательное сообщение приложению или какой-либо другой системе:
@Bean
public IntegrationFlow fileReaderFlow() {
return IntegrationFlows
.from(Files.inboundAdapter(new File(INPUT_DIR))
.patternFilter(FILE_PATTERN))
.get();
}
Активаторы сервисов, реализованные как обработчики сообщений, часто служат для адаптера исходящего канала, особенно когда данные должны быть переданы самому приложению. Мы уже обсуждали сервисы активаторы, поэтому нет смысла повторять это обсуждение.
Однако стоит отметить, что модули Spring Integration endpoint предоставляют полезные обработчики сообщений для нескольких распространенных случаев использования. Вы видели пример такого адаптера исходящего канала, FileWritingMessageHandler, в листинге 9.3. Говоря о модулях Spring Integration endpoint, давайте кратко рассмотрим, какие готовые к использованию модули конечных точек интеграции доступны.
9.2.9 Модули конечных точек (endpoint)
Замечательно, что Spring Integration позволяет вам создавать свои собственные адаптеры канала. Но еще лучше то, что Spring Integration предоставляет более двух десятков модулей конечных точек, содержащих адаптеры каналов - как входящие, так и исходящие - для интеграции с различными общими внешними системами, в том числе перечисленными в таблице 9.1.
Таблица 9.1. Spring Integration предоставляет более двух десятков моделей конечных точек для интеграции с внешними системами.
Модуль : Идентификатор артефакта зависимости (идентификатор группы: org.springframework.integration)
AMQP: spring-integration-amqp
Spring application events : spring-integration-event
RSS and Atom : spring-integration-feed
Filesystem : spring-integration-file
FTP/FTPS : spring-integration-ftp
GemFire : spring-integration-gemfire
HTTP : spring-integration-http
JDBC : spring-integration-jdbc
JPA : spring-integration-jpa
JMS : spring-integration-jms
Email : spring-integration-mail
MongoDB : spring-integration-mongodb
MQTT : spring-integration-mqtt
Redis : spring-integration-redis
RMI : spring-integration-rmi
SFTP : spring-integration-sftp
STOMP : spring-integration-stomp
Stream : spring-integration-stream
Syslog : spring-integration-syslog
TCP/UDP : spring-integration-ip
Twitter : spring-integration-twitter
Web Services : spring-integration-ws
WebFlux : spring-integration-webflux
WebSocket : spring-integration-websocket
XMPP : spring-integration-xmpp
ZooKeeper : spring-integration-zookeeper
Из таблицы 9.1 ясно, что Spring Integration предоставляет обширный набор компонентов для удовлетворения многих потребностей интеграции. Большинству приложений никогда не потребуется даже часть того, что предлагает Spring Integration. Но хорошо знать, что Spring Integration может, на случай если вам вдруг что-то из этого перечня понадобится.
Более того, было бы невозможно охватить все адаптеры каналов, предоставляемые модулями, перечисленными в таблице 9.1, в этой главе. Вы уже видели примеры, которые используют модуль файловой системы для записи в файловую систему. И вы скоро будете использовать модуль электронной почты для чтения электронных писем.
Каждый из модулей конечных точек предлагает канальные адаптеры, которые могут быть либо объявлены как bean-ы при использовании Java конфигурации, либо ссылаться на статические методы при использовании Java DSL конфигурации. Я рекомендую вам изучить любые другие endpoint модули, которые вас интересуют больше всего. Вы обнаружите, что они довольно последовательны в том, как они используются. Но сейчас давайте обратим наше внимание на endpoint модуль электронной почты, чтобы узнать, как вы можете использовать его в приложении Taco Cloud.
9.3 Создание интеграционного потока электронной почты
Вы решили, что Taco Cloud должна позволить своим клиентам отправлять свои тако-дизайны и размещать заказы по электронной почте. Вы рассылаете листовки и размещаете рекламу в газетах, предлагая всем отправлять свои заказы тако по электронной почте. Это огромный успех! К сожалению, это слишком успешно. На адрес электронной почты поступает так много писем, что вам нужно нанять отдельного человека, чтобы читать все письма и отправлять детали заказа в систему заказов.
В этом разделе вы реализуете интеграционный поток, который опрашивает почтовый ящик Taco Cloud на наличие электронных писем с заказами, анализирует электронные письма на предмет деталей заказа и отправляет заказы в Taco Cloud для обработки. Короче говоря, поток интеграции, который вам понадобится, будет использовать адаптер входящего канала из модуля конечной точки электронной почты для загрузки электронной почты из папки входящих сообщений Taco Cloud в поток интеграции.
Следующим шагом в процессе интеграции будет разбор электронных писем в объекты заказов, которые передаются другому обработчику для отправки заказов в REST API Taco Cloud, где они будут обрабатываться так же, как и любой заказ. Для начала давайте определим простой класс свойств конфигурации, чтобы отразить особенности обработки электронной почты Taco Cloud: