Messaging dengan Integrasi Spring dan Google Cloud Pub/Sub

Spring Integration memberi Anda mekanisme pengiriman pesan untuk bertukar Messages melalui MessageChannels. Menggunakan adaptor saluran untuk berkomunikasi dengan sistem eksternal.

Dalam latihan ini, kita akan membuat dua aplikasi yang berkomunikasi menggunakan adaptor saluran Spring Integration yang disediakan oleh Spring Cloud GCP. Adaptor ini menjadikan Integrasi Spring menggunakan Google Cloud Pub/Sub sebagai backend pertukaran pesan.

Anda akan mempelajari cara menggunakan Cloud Shell dan perintah gcloud Cloud SDK.

Tutorial ini menggunakan kode contoh dari panduan Memulai Booting Musim Semi.

Yang akan Anda pelajari

  • Cara bertukar pesan antara aplikasi dengan Google Cloud Pub/Sub menggunakan Spring Integration dan Spring Cloud GCP

Yang Anda butuhkan

  • Project Google Cloud Platform
  • Browser, seperti Chrome atau Firefox
  • Pemahaman tentang editor teks Linux standar, seperti Vim, EMAC, atau Nano

Bagaimana Anda akan menggunakan tutorial ini?

Hanya membacanya Membacanya dan menyelesaikan latihan

Bagaimana Anda menilai pengalaman membuat aplikasi web HTML/CSS Anda?

Pemula Menengah Mahir

Bagaimana penilaian Anda terhadap pengalaman menggunakan layanan Google Cloud Platform?

Pemula Menengah Mahir

Penyiapan lingkungan mandiri

Jika belum memiliki Akun Google (Gmail atau Google Apps), Anda harus membuatnya. Login ke Google Cloud Platform console (console.cloud.google.com) dan buat project baru:

Screenshot dari 10-02-2016 12:45:26.png

Ingat project ID, nama unik di semua project Google Cloud (maaf, nama di atas telah digunakan dan tidak akan berfungsi untuk Anda!) Project ID tersebut selanjutnya akan dirujuk di codelab ini sebagai PROJECT_ID.

Selanjutnya, Anda harus mengaktifkan penagihan di Cloud Console untuk menggunakan resource Google Cloud.

Menjalankan melalui codelab ini tidak akan menghabiskan biaya lebih dari beberapa dolar, tetapi bisa lebih jika Anda memutuskan untuk menggunakan lebih banyak resource atau jika Anda membiarkannya berjalan (lihat bagian "pembersihan" di akhir dokumen ini).

Pengguna baru Google Cloud Platform memenuhi syarat untuk mendapatkan uji coba gratis senilai $300.

Google Cloud Shell

Meskipun Google Cloud dapat dioperasikan dari jarak jauh dari laptop Anda, dalam codelab ini, kita akan menggunakan Google Cloud Shell, lingkungan command line yang berjalan di Cloud.

Mengaktifkan Google Cloud Shell

Dari GCP Console, klik ikon Cloud Shell di toolbar kanan atas:

Kemudian klik "Mulai Cloud Shell":

Hanya perlu waktu beberapa saat untuk penyediaan dan terhubung ke lingkungan:

Mesin virtual ini berisi semua alat pengembangan yang Anda perlukan. Layanan ini menawarkan direktori beranda tetap sebesar 5 GB, dan berjalan di Google Cloud, sehingga sangat meningkatkan performa dan autentikasi jaringan. Sebagian besar pekerjaan Anda di lab ini dapat dilakukan hanya dengan browser atau Google Chromebook.

Setelah terhubung ke Cloud Shell, Anda akan melihat bahwa Anda sudah diautentikasi dan project sudah ditetapkan ke PROJECT_ID.

Jalankan perintah berikut di Cloud Shell untuk mengonfirmasi bahwa Anda telah diautentikasi:

gcloud auth list

Output perintah

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

Output perintah

[core]
project = <PROJECT_ID>

Jika tidak, Anda dapat menyetelnya dengan perintah ini:

gcloud config set project <PROJECT_ID>

Output perintah

Updated property [core/project].

Buka halaman topik Google Cloud Pub/Sub dan aktifkan API.

Klik Buat Topik.

Ketik exampleTopic sebagai nama topik, lalu klik Buat.

Setelah topik dibuat, tetaplah berada di halaman Topik. Cari topik yang baru saja Anda buat, tekan tiga titik vertikal di akhir baris dan klik Langganan Baru.

Ketik exampleSubscription di kotak teks nama langganan, lalu klik Buat.

Setelah Cloud Shell diluncurkan, Anda dapat menggunakan command line untuk membuat dua aplikasi Spring Boot baru dengan 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 -

Sekarang mari kita buat aplikasi pengirim pesan kita. Ubah ke direktori aplikasi pengirim.

$ cd spring-integration-sender

Kita ingin aplikasi menulis pesan ke saluran. Setelah pesan berada di saluran, pesan akan diambil oleh adaptor saluran keluar, yang mengubahnya dari pesan Musim Semi generik menjadi pesan Google Cloud Pub/Sub dan memublikasikannya ke topik Google Cloud Pub/Sub.

Agar aplikasi dapat menulis ke saluran, kita dapat menggunakan Gateway pesan Integrasi Spring. Dengan menggunakan editor teks dari vim, emacs, atau nano, deklarasikan antarmuka PubsubOutboundGateway di dalam class 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);
        }
}

Sekarang kita memiliki mekanisme untuk mengirim pesan ke channel, tetapi ke mana pesan tersebut dipindahkan setelah pesan berada di channel?

Kita memerlukan adaptor saluran keluar untuk menggunakan pesan baru di saluran dan memublikasikannya ke topik 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");
        }
}

Anotasi @ServiceActivator menyebabkan MessageHandler ini diterapkan ke pesan baru di inputChannel. Dalam hal ini, kita memanggil adaptor saluran keluar, PubSubMessageHandler, untuk memublikasikan pesan ke topik exampleTopic Google Cloud Pub/Sub.

Dengan menerapkan adaptor saluran, kita sekarang dapat otomatis menghubungkan objek PubsubOutboundGateway dan menggunakannya untuk menulis pesan ke saluran.

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("/");
        }
}

Karena anotasi @PostMapping, kita sekarang memiliki endpoint yang memproses permintaan POST HTTP, tetapi tanpa menambahkan anotasi @RestController ke class DemoApplication untuk menandainya sebagai pengontrol REST.

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

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

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

Agar aplikasi berjalan, kita hanya perlu menambahkan dependensi yang diperlukan.

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>

Jalankan aplikasi pengirim.

# Set the Project ID in environmental variable
$ export GOOGLE_CLOUD_PROJECT=`gcloud config list \
  --format 'value(core.project)'`
$ ./mvnw spring-boot:run

Aplikasi memproses permintaan POST yang berisi pesan di port 8080 dan endpoint /postMessage, tetapi kita akan membahasnya nanti.

Kita baru saja membuat aplikasi yang mengirimkan pesan melalui Google Cloud Pub/Sub. Sekarang, kita akan membuat aplikasi lain yang menerima pesan tersebut dan memprosesnya.

Klik + untuk membuka sesi Cloud Shell baru.

Kemudian, pada sesi Cloud Shell yang baru, ubah direktori ke direktori aplikasi penerima:

$ cd spring-integration-receiver

Pada aplikasi sebelumnya, deklarasi gateway pesan membuat saluran keluar untuk kita. Karena tidak menggunakan gateway pesan untuk menerima pesan, kita perlu mendeklarasikan MessageChannel tempat pesan masuk akan diterima.

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

Kita memerlukan adaptor saluran masuk untuk menerima pesan dari Google Cloud Pub/Sub dan menyampaikannya ke 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;
        }
}

Adaptor ini mengikat diri ke pubsubInputChannel dan mendengarkan pesan baru dari langganan Google Cloud Pub/Sub exampleSubscription.

Kami memiliki channel tempat pesan masuk diposting, namun apa yang harus dilakukan dengan pesan tersebut?

Mari kita proses aplikasi tersebut dengan @ServiceActivator yang dipicu saat pesan baru masuk ke 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);
        }
}

Dalam hal ini, kami hanya akan mencatat payload pesan.

Kita perlu menambahkan dependensi yang diperlukan.

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>

Jalankan aplikasi penerima.

$ ./mvnw spring-boot:run

Sekarang, semua pesan yang Anda kirim ke aplikasi pengirim akan dicatat dalam log di aplikasi penerima. Untuk mengujinya, buka sesi Cloud Shell baru dan buat permintaan HTTP POST ke aplikasi pengirim.

$ curl --data "message=Hello world!" localhost:8080/postMessage

Kemudian, pastikan bahwa aplikasi penerima mencatat pesan yang Anda kirim.

INFO: Message arrived! Payload: Hello world!

Hapus langganan dan topik yang dibuat sebagai bagian dari latihan ini.

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

Anda menyiapkan dua aplikasi Spring Boot yang menggunakan Adaptor Saluran Integrasi Spring untuk Google Cloud Pub/Sub. Mereka bertukar pesan di antara mereka sendiri tanpa pernah berinteraksi dengan Google Cloud Pub/Sub API.

Anda telah mempelajari cara menggunakan Adaptor Saluran Integrasi Musim Semi untuk Google Cloud Pub/Sub.

Pelajari Lebih Lanjut

Lisensi

Karya ini dilisensikan berdasarkan Lisensi Umum Creative Commons Attribution 2.0.