Spring Integration udostępnia mechanizm przesyłania wiadomości do wymiany Messages
za pomocą MessageChannels
. Do komunikacji z systemami zewnętrznymi używa adapterów kanałów.
W tym ćwiczeniu utworzymy 2 aplikacje, które komunikują się za pomocą adapterów kanałów Spring Integration udostępnianych przez Spring Cloud GCP. Te adaptery sprawiają, że Spring Integration używa Google Cloud Pub/Sub jako backendu do wymiany wiadomości.
Dowiesz się, jak używać Cloud Shell i narzędzia wiersza poleceń gcloud z pakietu Cloud SDK.
W tym samouczku używamy przykładowego kodu z przewodnika dla początkujących dotyczącego Spring Boot.
Czego się nauczysz
- Wymiana wiadomości między aplikacjami za pomocą Google Cloud Pub/Sub przy użyciu Spring Integration i Spring Cloud GCP
Czego potrzebujesz
- Projekt Google Cloud Platform
- przeglądarka, np. Chrome lub Firefox;
- Znajomość standardowych edytorów tekstu systemu Linux, takich jak Vim, EMACS lub Nano.
Jak zamierzasz korzystać z tego samouczka?
Jak oceniasz swoje doświadczenie w tworzeniu aplikacji internetowych w HTML/CSS?
Jak oceniasz korzystanie z usług Google Cloud Platform?
Samodzielne konfigurowanie środowiska
Jeśli nie masz jeszcze konta Google (Gmail lub Google Apps), musisz je utworzyć. Zaloguj się w konsoli Google Cloud Platform (console.cloud.google.com) i utwórz nowy projekt:
Zapamiętaj identyfikator projektu, czyli unikalną nazwę we wszystkich projektach Google Cloud (podana powyżej nazwa jest już zajęta i nie będzie działać w Twoim przypadku). W dalszej części tego laboratorium będzie on nazywany PROJECT_ID
.
Następnie musisz włączyć płatności w konsoli Cloud, aby móc korzystać z zasobów Google Cloud.
Wykonanie tego samouczka nie powinno kosztować więcej niż kilka dolarów, ale może okazać się droższe, jeśli zdecydujesz się wykorzystać więcej zasobów lub pozostawisz je uruchomione (patrz sekcja „Czyszczenie” na końcu tego dokumentu).
Nowi użytkownicy Google Cloud Platform mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.
Google Cloud Shell
Google Cloud można obsługiwać zdalnie z laptopa, ale w tym module praktycznym będziemy używać Google Cloud Shell, czyli środowiska wiersza poleceń działającego w chmurze.
Aktywuj Google Cloud Shell
W konsoli GCP kliknij ikonę Cloud Shell na pasku narzędzi w prawym górnym rogu:
Następnie kliknij „Uruchom Cloud Shell”:
Udostępnienie środowiska i połączenie się z nim powinno zająć tylko kilka chwil:
Ta maszyna wirtualna zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i uwierzytelniania. Większość, jeśli nie wszystkie, zadań w tym laboratorium można wykonać za pomocą przeglądarki lub Chromebooka Google.
Po połączeniu z Cloud Shell zobaczysz, że jesteś już uwierzytelniony, a projekt jest już ustawiony na PROJECT_ID.
Aby potwierdzić, że masz autoryzację, uruchom w Cloud Shell to polecenie:
gcloud auth list
Wynik polecenia
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
Wynik polecenia
[core] project = <PROJECT_ID>
Jeśli nie, możesz ustawić go za pomocą tego polecenia:
gcloud config set project <PROJECT_ID>
Wynik polecenia
Updated property [core/project].
Otwórz stronę tematów Google Cloud Pub/Sub i włącz interfejs API.
Kliknij Utwórz temat.
Wpisz exampleTopic
jako nazwę tematu, a następnie kliknij Utwórz.
Po utworzeniu tematu pozostań na stronie Tematy. Znajdź utworzony przez siebie temat, kliknij 3 kropki na końcu wiersza i wybierz Nowa subskrypcja.
Wpisz exampleSubscription
w polu tekstowym nazwy subskrypcji i kliknij Utwórz.
Po uruchomieniu Cloud Shell możesz użyć wiersza poleceń, aby wygenerować 2 nowe aplikacje Spring Boot za pomocą Spring Initializr:
$ curl https://start.spring.io/starter.tgz \
-d bootVersion=2.0.6.RELEASE \
-d dependencies=web \
-d baseDir=spring-integration-sender | tar -xzvf -
$ curl https://start.spring.io/starter.tgz \
-d bootVersion=2.0.6.RELEASE \
-d baseDir=spring-integration-receiver | tar -xzvf -
Teraz utworzymy aplikację do wysyłania wiadomości. Przejdź do katalogu aplikacji do wysyłania.
$ cd spring-integration-sender
Chcemy, aby nasza aplikacja mogła pisać wiadomości na kanale. Gdy wiadomość znajdzie się w kanale, zostanie pobrana przez adapter kanału wychodzącego, który przekształci ją z ogólnej wiadomości Spring w wiadomość Google Cloud Pub/Sub i opublikuje ją w temacie Google Cloud Pub/Sub.
Aby nasza aplikacja mogła zapisywać dane w kanale, możemy użyć bramy przesyłania wiadomości Spring Integration. W edytorze tekstu z vim
, emacs
lub nano
zadeklaruj interfejs PubsubOutboundGateway
w klasie DemoApplication
.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.integration.annotation.MessagingGateway;
@SpringBootApplication
public class DemoApplication {
...
@MessagingGateway(defaultRequestChannel = "pubsubOutputChannel")
public interface PubsubOutboundGateway {
void sendToPubsub(String text);
}
}
Mamy już mechanizm wysyłania wiadomości na kanał, ale co się z nimi dzieje, gdy już tam trafią?
Potrzebujemy adaptera kanału wychodzącego, aby odbierać nowe wiadomości na kanale i publikować je w temacie Google Cloud Pub/Sub.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.cloud.gcp.pubsub.core.PubSubTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.cloud.gcp.pubsub.integration.outbound.PubSubMessageHandler;
import org.springframework.messaging.MessageHandler;
@SpringBootApplication
public class DemoApplication {
...
@Bean
@ServiceActivator(inputChannel = "pubsubOutputChannel")
public MessageHandler messageSender(PubSubTemplate pubsubTemplate) {
return new PubSubMessageHandler(pubsubTemplate, "exampleTopic");
}
}
Adnotacja @ServiceActivator
powoduje, że ten MessageHandler
jest stosowany do wszystkich nowych wiadomości w grupie inputChannel
. W tym przypadku wywołujemy nasz adapter kanału wychodzącego PubSubMessageHandler
, aby opublikować wiadomość w temacie exampleTopic
usługi Google Cloud Pub/Sub.
Po utworzeniu adaptera kanału możemy teraz automatycznie połączyć obiekt PubsubOutboundGateway
i użyć go do zapisania wiadomości w kanale.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.view.RedirectView;
@SpringBootApplication
public class DemoApplication {
...
@Autowired
private PubsubOutboundGateway messagingGateway;
@PostMapping("/postMessage")
public RedirectView postMessage(@RequestParam("message") String message) {
this.messagingGateway.sendToPubsub(message);
return new RedirectView("/");
}
}
Dzięki adnotacji @PostMapping
mamy teraz punkt końcowy, który nasłuchuje żądań HTTP POST, ale nie bez dodania adnotacji @RestController
do klasy DemoApplication
, aby oznaczyć ją jako kontroler REST.
src/main/java/com/example/demo/DemoApplication.java
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class DemoApplication {
...
}
Aby aplikacja działała, musimy dodać wymagane zależności.
pom.xml
<project>
...
<!-- Add Spring Cloud GCP Dependency BOM -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-dependencies</artifactId>
<version>1.0.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
...
<!-- Add Pub/Sub Starter -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
</dependency>
<!-- Add Spring Integration -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
</dependency>
</dependencies>
</project>
Uruchom aplikację nadawcy.
# Set the Project ID in environmental variable
$ export GOOGLE_CLOUD_PROJECT=`gcloud config list \
--format 'value(core.project)'`
$ ./mvnw spring-boot:run
Aplikacja nasłuchuje żądań POST zawierających wiadomość na porcie 8080 i w punkcie końcowym /postMessage
, ale do tego wrócimy później.
Właśnie utworzyliśmy aplikację, która wysyła wiadomości za pomocą Google Cloud Pub/Sub. Teraz utworzymy kolejną aplikację, która będzie odbierać te wiadomości i je przetwarzać.
Kliknij +, aby otworzyć nową sesję Cloud Shell.
Następnie w nowej sesji Cloud Shell przejdź do katalogu aplikacji odbiorcy:
$ cd spring-integration-receiver
W poprzedniej aplikacji deklaracja bramy wiadomości tworzyła dla nas kanał wychodzący. Ponieważ nie używamy bramy do odbierania wiadomości, musimy zadeklarować własny adres MessageChannel
, na który będą przychodzić wiadomości.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.context.annotation.Bean;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.messaging.MessageChannel;
@SpringBootApplication
public class DemoApplication {
...
@Bean
public MessageChannel pubsubInputChannel() {
return new DirectChannel();
}
}
Będziemy potrzebować adaptera kanału przychodzącego, aby odbierać wiadomości z Google Cloud Pub/Sub i przekazywać je do pubsubInputChannel
.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.gcp.pubsub.core.PubSubTemplate;
import org.springframework.cloud.gcp.pubsub.integration.inbound.PubSubInboundChannelAdapter;
@SpringBootApplication
public class DemoApplication {
...
@Bean
public PubSubInboundChannelAdapter messageChannelAdapter(
@Qualifier("pubsubInputChannel") MessageChannel inputChannel,
PubSubTemplate pubSubTemplate) {
PubSubInboundChannelAdapter adapter =
new PubSubInboundChannelAdapter(pubSubTemplate, "exampleSubscription");
adapter.setOutputChannel(inputChannel);
return adapter;
}
}
Ten adapter wiąże się z pubsubInputChannel
i nasłuchuje nowych wiadomości z subskrypcji exampleSubscription
Google Cloud Pub/Sub.
Mamy kanał, na którym publikowane są wiadomości przychodzące, ale co z nimi zrobić?
Przetwórzmy je za pomocą @ServiceActivator
, które jest wywoływane, gdy nowe wiadomości docierają na adres pubsubInputChannel
.
src/main/java/com/example/demo/DemoApplication.java
...
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.integration.annotation.ServiceActivator;
@SpringBootApplication
public class DemoApplication {
...
private static final Log LOGGER = LogFactory.getLog(DemoApplication.class);
@ServiceActivator(inputChannel = "pubsubInputChannel")
public void messageReceiver(String payload) {
LOGGER.info("Message arrived! Payload: " + payload);
}
}
W takim przypadku zarejestrujemy tylko ładunek wiadomości.
Musimy dodać niezbędne zależności.
pom.xml
<project>
...
<!-- Add Spring Cloud GCP Dependency BOM -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-dependencies</artifactId>
<version>1.0.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
...
<!-- Add Pub/Sub Starter -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-pubsub</artifactId>
</dependency>
<!-- Add Spring Integration -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
</dependency>
</dependencies>
</project>
Uruchom aplikację odbiornika.
$ ./mvnw spring-boot:run
Teraz wszystkie wiadomości wysyłane do aplikacji nadawcy będą logowane w aplikacji odbiorcy. Aby to sprawdzić, otwórz nową sesję Cloud Shell i wyślij żądanie HTTP POST do aplikacji nadawcy.
$ curl --data "message=Hello world!" localhost:8080/postMessage
Następnie sprawdź, czy aplikacja odbiorcy zarejestrowała wysłaną przez Ciebie wiadomość.
INFO: Message arrived! Payload: Hello world!
Usuń subskrypcję i temat utworzone w ramach tego ćwiczenia.
$ gcloud beta pubsub subscriptions delete exampleSubscription
$ gcloud beta pubsub topics delete exampleTopic
Skonfigurujesz 2 aplikacje Spring Boot, które korzystają z adapterów kanałów Spring Integration dla Google Cloud Pub/Sub. Wymieniają one między sobą wiadomości bez wchodzenia w interakcję z interfejsem Google Cloud Pub/Sub API.
Wiesz już, jak używać adapterów kanałów Spring Integration dla Google Cloud Pub/Sub.
Więcej informacji
- Google Cloud Pub/Sub: https://cloud.google.com/pubsub/
- Projekt Spring on GCP: http://cloud.spring.io/spring-cloud-gcp/
- Repozytorium Spring on GCP w GitHubie: https://github.com/spring-cloud/spring-cloud-gcp
- Java na Google Cloud Platform: https://cloud.google.com/java/
Licencja
To zadanie jest licencjonowane na podstawie ogólnej licencji Creative Commons Attribution 2.0.