Komunikacja za pomocą Spring Integration i Google Cloud Pub/Sub

Spring Integration umożliwia mechanizm wymiany wiadomości przez platformę Messages na język MessageChannels. Używamy adapterów kanałów do komunikacji z systemami zewnętrznymi.

W tym ćwiczeniu utworzymy 2 aplikacje komunikujące się za pomocą adapterów kanałów wiosennej integracji oferowanych przez Spring Cloud GCP. Te adaptery sprawiają, że wiosna integracja wykorzystuje Google Cloud Pub/Sub jako backend wymiany wiadomości.

Dowiesz się, jak korzystać z Cloud Shell i polecenia gcloud z pakietu SDK Cloud.

Ten samouczek wykorzystuje przykładowy kod z przewodnika rozpoczynającego wiosnę podczas uruchamiania.

Czego się nauczysz:

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

Czego potrzebujesz

  • Projekt Google Cloud Platform
  • Przeglądarka, na przykład Chrome lub Firefox.
  • znajomość standardowych edytorów tekstu systemu Linux, takich jak Vim, EMAC czy Nano.

Jak będziesz korzystać z tego samouczka?

Przeczytaj tylko Przeczytaj i wykonaj ćwiczenia

Jak oceniasz tworzenie aplikacji internetowych HTML/CSS?

Początkujący Średnio zaawansowany Zaawansowany

Jak oceniasz korzystanie z usług Google Cloud Platform?

Początkujący Średnio zaawansowany Zaawansowany

Konfiguracja środowiska we własnym tempie

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:

Zrzut ekranu z 10 września 2016 r., 12:45:26.png

Zapamiętaj identyfikator projektu, unikalną nazwę we wszystkich projektach Google Cloud (powyższa nazwa została już użyta i nie będzie działać). W ćwiczeniach nazywamy je później PROJECT_ID.

Aby móc używać zasobów Google Cloud, musisz najpierw włączyć płatności w Cloud Console.

Ćwiczenia z programowania nie powinny kosztować więcej niż kilka dolarów, ale mogą być większe, jeśli zdecydujesz się wykorzystać więcej zasobów lub pozostawisz to uruchomione (zobacz sekcję „Czyszczenie” na końcu tego dokumentu).

Nowi użytkownicy Google Cloud Platform mogą skorzystać z bezpłatnej wersji próbnej o wartości 300 USD.

Google Cloud Shell,

Google Cloud można uruchomić zdalnie z laptopa, ale podczas tego ćwiczenia wykorzystamy Google Cloud Shell – środowisko wiersza poleceń działające 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 jest wyposażona we wszystkie potrzebne narzędzia dla programistów. Oferuje trwały katalog domowy o pojemności 5 GB oraz działa w Google Cloud, co znacznie zwiększa wydajność sieci i uwierzytelnianie. Znaczna część (lub nawet całość) zadań wykonywanych w tym module można wykonać w przeglądarce lub na Chromebooku Google.

Po połączeniu z Cloud Shell zobaczysz, że uwierzytelniono już projekt i masz już ustawiony identyfikator PROJECT_ID.

Uruchom następujące polecenie w Cloud Shell, aby potwierdzić, że jesteś uwierzytelniony:

gcloud auth list

Polecenie wyjściowe

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Polecenie wyjściowe

[core]
project = <PROJECT_ID>

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

gcloud config set project <PROJECT_ID>

Polecenie wyjściowe

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 przed chwilą temat, naciśnij trzy pionowe kropki na końcu wiersza, a następnie kliknij Nowa subskrypcja.

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

Po uruchomieniu Cloud Shell możesz użyć wiersza poleceń do wygenerowania 2 nowych aplikacji Spring Run 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 wysyłającej.

$ cd spring-integration-sender

Chcemy, aby nasza aplikacja rejestrowała wiadomości na kanale. Gdy wiadomość znajdzie się na kanale, zostanie odebrana przez adapter kanału wychodzącego, co spowoduje przekonwertowanie jej z ogólnej wiadomości wiosennej na wiadomość Google Cloud Pub/Sub i opublikowanie jej w temacie Google Cloud Pub/Sub.

Aby aplikacja mogła zapisać zmiany na kanale, możemy użyć bramki do wiosennej integracji. W edytorze tekstu 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);
        }
}

Obecnie dysponujemy mechanizmem przesyłania wiadomości na kanał. Gdzie trafiają te wiadomości, gdy znajdują się na kanale?

Potrzebujemy adaptera kanału wychodzącego, aby odbierać nowe wiadomości 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 element 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 Google Cloud Pub/Sub&#39.

Dzięki adapterowi kanału możemy teraz automatycznie połączyć przewodowo obiekt PubsubOutboundGateway i użyć go do zapisu 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("/");
        }
}

Ze względu na adnotację @PostMapping mamy teraz punkt końcowy, który nasłuchuje żądań HTTP POST, ale nie dodaje 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, wystarczy 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 punkcie końcowym /postMessage, ale tym razem zajmiemy się tym później.

Właśnie utworzyliśmy aplikację, która wysyła wiadomości przez Google Cloud Pub/Sub. Teraz utworzymy kolejną aplikację, która je otrzyma i przetworzy.

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

Następnie w nowej sesji Cloud Shell zmień katalogi na katalog odbiorcy:

$ cd spring-integration-receiver

W poprzedniej aplikacji deklaracja bramy wiadomości stworzyła dla nas kanał wychodzący. Nie odbieramy wiadomości przy użyciu bramy wiadomości, dlatego musimy zadeklarować własną pocztę MessageChannel, na którą będą przychodzić wiadomości przychodzące.

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 do odbierania wiadomości z Google Cloud Pub/Sub i przekazywania ich 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 łączy się z usługą pubsubInputChannel i odsłuchuje nowe wiadomości z subskrypcji Google Cloud Pub/Sub exampleSubscription.

Na naszym kanale są publikowane wiadomości przychodzące, ale co z nimi zrobić?

Przetwarzamy je z plikiem @ServiceActivator, który jest wywoływany, gdy nowe wiadomości docierają do 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 zapiszemy ł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, które wyślesz do aplikacji nadawcy, będą rejestrowane w aplikacji odbiornik. 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 odbierająca wysłała wysłaną przez Ciebie wiadomość.

INFO: Message arrived! Payload: Hello world!

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

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

Musisz skonfigurować 2 aplikacje wiosenne rozruchowe, które korzystają z adapterów kanałów Spring Integration na potrzeby Google Cloud Pub/Sub. Wymieniają się ze sobą wiadomościami bez interakcji z interfejsem Google Cloud Pub/Sub API.

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

Więcej informacji

Licencja

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