Przesyłanie wiadomości za pomocą usługi Spring Integration i Google Cloud Pub/Sub

1. Omówienie

Spring Integration udostępnia mechanizm przesyłania wiadomości, który umożliwia wymianę danych Messages za pomocą MessageChannels. Komunikuje się on z systemami zewnętrznymi za pomocą adapterów kanałów.

W tym ćwiczeniu utworzymy 2 aplikacje komunikujące się za pomocą adapterów kanałów w Spring Integration dostępnych w GCP Cloud. Dzięki tym adapterom usługa Spring Integration używa Google Cloud Pub/Sub jako backendu wymiany wiadomości.

Dowiesz się, jak używać Cloud Shell i narzędzia wiersza poleceń gcloud z pakietu Cloud SDK.

W tym samouczku korzystamy z przykładowego kodu z przewodnika wprowadzającego do uruchamiania rozruchu sprężynowego.

Czego się nauczysz

  • Jak wymieniać wiadomości między aplikacjami w Google Cloud Pub/Sub przy użyciu usług Spring Integration i Spring Cloud GCP

Czego potrzebujesz

  • Projekt Google Cloud Platform
  • przeglądarkę, np. Chrome lub Firefox;
  • znajomość standardowych edytorów tekstu systemu Linux, takich jak Vim, EMAC lub Nano;

Jak wykorzystasz ten samouczek?

Tylko do przeczytania Przeczytaj go i wykonaj ćwiczenia

Jak oceniasz swoje doświadczenie z tworzeniem aplikacji internetowych HTML/CSS?

Początkujący Poziom średnio zaawansowany Biegły

Jak oceniasz swoje wrażenia z korzystania z usług Google Cloud Platform?

Początkujący Poziom średnio zaawansowany Biegły
.

2. Konfiguracja i wymagania

Samodzielne konfigurowanie środowiska

  1. Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub wykorzystaj już istniejący. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Nazwa projektu jest wyświetlaną nazwą uczestników tego projektu. To ciąg znaków, który nie jest używany przez interfejsy API Google. W każdej chwili możesz ją zaktualizować.
  • Identyfikator projektu jest unikalny we wszystkich projektach Google Cloud i nie można go zmienić (po jego ustawieniu nie można go zmienić). Cloud Console automatycznie wygeneruje unikalny ciąg znaków. zwykle nieważne, co ona jest. W większości ćwiczeń w Codelabs musisz podać swój identyfikator projektu (zwykle identyfikowany jako PROJECT_ID). Jeśli nie podoba Ci się wygenerowany identyfikator, możesz wygenerować kolejny losowy. Możesz też spróbować własnych sił i sprawdzić, czy jest dostępna. Po wykonaniu tej czynności nie można jej już zmienić. Pozostanie ona przez cały czas trwania projektu.
  • Jest jeszcze trzecia wartość, numer projektu, z którego korzystają niektóre interfejsy API. Więcej informacji o wszystkich 3 wartościach znajdziesz w dokumentacji.
  1. Następnie musisz włączyć płatności w Cloud Console, aby korzystać z zasobów Cloud/interfejsów API. Ukończenie tego ćwiczenia z programowania nic nie kosztuje. Aby wyłączyć zasoby w celu uniknięcia naliczania opłat po zakończeniu tego samouczka, możesz usunąć utworzone zasoby lub projekt. Nowi użytkownicy Google Cloud mogą skorzystać z programu bezpłatnego okresu próbnego o wartości 300 USD.

Google Cloud Shell,

Google Cloud można obsługiwać zdalnie z Twojego laptopa, ale w ramach tego ćwiczenia z programowania wykorzystamy Google Cloud Shell – środowisko wiersza poleceń działające w chmurze.

Aktywowanie Cloud Shell

  1. W konsoli Cloud kliknij Aktywuj Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

Jeśli uruchamiasz Cloud Shell po raz pierwszy, zobaczysz ekran pośredni z opisem tej usługi. Jeśli wyświetlił się ekran pośredni, kliknij Dalej.

9c92662c6a846a5c.png

Uzyskanie dostępu do Cloud Shell i połączenie się z nim powinno zająć tylko kilka chwil.

9f0e51b578fecce5.png

Ta maszyna wirtualna ma 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 uwierzytelnianie. Większość zadań w ramach tego ćwiczenia z programowania można wykonać w przeglądarce.

Po nawiązaniu połączenia z Cloud Shell powinno pojawić się potwierdzenie, że użytkownik jest uwierzytelniony, a projekt jest ustawiony na identyfikator Twojego projektu.

  1. Uruchom to polecenie w Cloud Shell, aby potwierdzić, że jesteś uwierzytelniony:
gcloud auth list

Dane wyjściowe polecenia

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Uruchom to polecenie w Cloud Shell, aby sprawdzić, czy polecenie gcloud zna Twój projekt:
gcloud config list project

Dane wyjściowe polecenia

[core]
project = <PROJECT_ID>

Jeśli tak nie jest, możesz go ustawić za pomocą tego polecenia:

gcloud config set project <PROJECT_ID>

Dane wyjściowe polecenia

Updated property [core/project].

3. Udostępnianie zasobów Pub/Sub

Otwórz stronę tematów Google Cloud Pub/Sub.

Kliknij Utwórz temat.

4c938409dc7169a6.png

Wpisz exampleTopic jako nazwę tematu i kliknij Utwórz.

e2daeec91537f672.png

Po utworzeniu tematu pozostań na stronie Tematy. Odszukaj utworzony temat, naciśnij 3 pionowe kropki na końcu wiersza i kliknij Nowa subskrypcja.

975efa26e5054936.png

Wpisz exampleSubscription w polu tekstowym nazwy subskrypcji i kliknij Utwórz.

f7a91d9e1cb48009.png

4. Inicjowanie aplikacji Spring Boot

Po uruchomieniu Cloud Shell możesz użyć wiersza poleceń, aby wygenerować 2 nowe aplikacje Spring Boot za pomocą narzędzia Spring Initializr:

$ curl https://start.spring.io/starter.tgz \
  -d bootVersion=3.0.5 \
  -d dependencies=web,integration,cloud-gcp-pubsub \
  -d type=maven-project \
  -d baseDir=spring-integration-sender | tar -xzvf -

$ curl https://start.spring.io/starter.tgz \
  -d bootVersion=3.0.5 \
  -d dependencies=web,integration,cloud-gcp-pubsub \
  -d type=maven-project \
  -d baseDir=spring-integration-receiver | tar -xzvf -

5. Utwórz aplikację do wysyłania wiadomości

Teraz utwórzmy aplikację do wysyłania wiadomości. Przejdź do katalogu aplikacji wysyłającej.

$ cd spring-integration-sender

Chcemy, aby nasza aplikacja zapisywała wiadomości na kanale. Gdy wiadomość znajdzie się na kanale, zostanie ona odebrana 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 wiadomości Spring Integration. Za pomocą edytora 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 obecnie mechanizm wysyłania wiadomości na kanał, ale gdzie trafiają one, gdy już się na nim znajdą?

Potrzebujemy adaptera kanału wychodzącego, aby przetwarzać nowe wiadomości w kanale i publikować je w temacie Google Cloud Pub/Sub.

src/main/java/com/example/demo/DemoApplication.java

...
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.integration.outbound.PubSubMessageHandler;

import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.ServiceActivator;
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 ta reguła MessageHandler jest stosowana do wszystkich nowych wiadomości w elemencie inputChannel. W tym przypadku wywołujemy nasz adapter kanału wychodzącego PubSubMessageHandler, aby opublikować wiadomość w temacie exampleTopic w Google Cloud Pub/Sub.

Dzięki adapterowi kanału możemy teraz automatycznie podłączyć obiekt PubsubOutboundGateway i wykorzystać go do napisania wiadomości do kanału.

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. Dodanie do klasy DemoApplication adnotacji @RestController oznacza, że jest to kontroler REST.

src/main/java/com/example/demo/DemoApplication.java

import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {
  ...
}

Upewnij się, że zasada JAVA_HOME jest ustawiona na odpowiednią wersję.

export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

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 komunikat na portach 8080 i punkcie końcowym /postMessage, ale tym zajmiemy się później.

6. Utwórz aplikację do odbierania wiadomości

Właśnie stworzyliśmy aplikację, która wysyła wiadomości przez Google Cloud Pub/Sub. Utworzymy teraz kolejną aplikację, która będzie je odbierać i przetwarzać.

Kliknij +, aby otworzyć nową sesję Cloud Shell.

9799bee5fea95aa6.png

Następnie w nowej sesji Cloud Shell zmień katalogi na katalog aplikacji odbierającej:

$ cd spring-integration-receiver

W poprzedniej aplikacji deklaracja dotycząca bramy wiadomości utworzyła dla nas kanał wychodzący. Ponieważ nie używamy bramy do odbierania wiadomości, musimy zadeklarować własny 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 usługi pubsubInputChannel.

src/main/java/com/example/demo/DemoApplication.java

...
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.integration.inbound.PubSubInboundChannelAdapter;

import org.springframework.beans.factory.annotation.Qualifier;

@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 Google Cloud Pub/Sub exampleSubscription.

Mamy kanał, na który wysyłane są wiadomości przychodzące, ale co zrobić z tymi wiadomościami?

Przetwórzmy je za pomocą funkcji @ServiceActivator, która jest wywoływana, gdy nowe wiadomości przychodzą na adres pubsubInputChannel. W tym przypadku rejestrujemy tylko ładunek wiadomości.

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);
  }
}

Upewnij się, że zasada JAVA_HOME jest ustawiona na odpowiednią wersję.

export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

Uruchom aplikację odbierającą.

$ ./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8081"

Teraz wszystkie wiadomości wysyłane do aplikacji nadawcy będą rejestrowane w aplikacji adresata. 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 zapisała wysłaną przez Ciebie wiadomość.

INFO: Message arrived! Payload: Hello world!

7. Czyszczenie

Usuń subskrypcję i temat utworzony w ramach tego ćwiczenia.

$ gcloud pubsub subscriptions delete exampleSubscription
$ gcloud pubsub topics delete exampleTopic

8. Podsumowanie

Konfigurujesz 2 aplikacje Spring Boot korzystające z adapterów kanału Spring Integration dla Google Cloud Pub/Sub. Wymieniają się wiadomościami między sobą bez konieczności interakcji z interfejsem Google Cloud Pub/Sub API.

9. Gratulacje!

Wiesz już, jak używać adapterów kanału integracji Spring w Google Cloud Pub/Sub.

Więcej informacji

Licencja

To zadanie jest licencjonowane na podstawie ogólnej licencji Creative Commons Attribution 2.0.