Spring Entegrasyonu ve Google Cloud Pub/Sub ile Mesajlaşma

Spring Integration, MessageChannels üzerinden Messages değişimi için bir mesajlaşma mekanizması sağlar. Harici sistemlerle iletişim kurmak için kanal bağdaştırıcılarını kullanır.

Bu alıştırmada, Spring Cloud GCP tarafından sağlanan Spring Integration kanal bağdaştırıcılarını kullanarak iletişim kuran iki uygulama oluşturacağız. Bu bağdaştırıcılar, Spring Integration'ın mesaj değişimi arka ucu olarak Google Cloud Pub/Sub'ı kullanmasını sağlar.

Cloud Shell ve Cloud SDK gcloud komutunu kullanmayı öğreneceksiniz.

Bu eğitimde, Spring Boot Getting Started Guide'daki örnek kod kullanılmaktadır.

Neler öğreneceksiniz?

  • Spring Integration ve Spring Cloud GCP kullanarak Google Cloud Pub/Sub ile uygulamalar arasında mesaj alışverişi yapma

Gerekenler

  • Google Cloud Platform projesi
  • Chrome veya Firefox gibi bir tarayıcı
  • Vim, EMACs veya Nano gibi standart Linux metin düzenleyicileri hakkında bilgi sahibi olmanız gerekir.

Bu eğitimi nasıl kullanacaksınız?

Yalnızca okuyun Okuyun ve alıştırmaları tamamlayın

HTML/CSS web uygulamaları oluşturma deneyiminizi nasıl değerlendirirsiniz?

Yeni başlayan Orta düzey Uzman

Google Cloud Platform hizmetlerini kullanma deneyiminizi nasıl değerlendirirsiniz?

Başlangıç Orta İleri

Kendi hızınızda ortam kurulumu

Henüz bir Google Hesabınız (Gmail veya Google Apps) yoksa oluşturmanız gerekir. Google Cloud Platform Console'da (console.cloud.google.com) oturum açın ve yeni bir proje oluşturun:

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

Proje kimliğini unutmayın. Bu kimlik, tüm Google Cloud projelerinde benzersiz bir addır (Yukarıdaki ad zaten alınmış olduğundan sizin için çalışmayacaktır). Bu codelab'in ilerleyen kısımlarında PROJECT_ID olarak adlandırılacaktır.

Ardından, Google Cloud kaynaklarını kullanmak için Cloud Console'da faturalandırmayı etkinleştirmeniz gerekir.

Bu codelab'i tamamlamak size birkaç dolardan fazla maliyet getirmemelidir. Ancak daha fazla kaynak kullanmaya karar verirseniz veya kaynakları çalışır durumda bırakırsanız maliyet daha yüksek olabilir (bu belgenin sonundaki "temizleme" bölümüne bakın).

Google Cloud Platform'un yeni kullanıcıları 300 ABD doları değerindeki ücretsiz deneme sürümünden yararlanabilir.

Google Cloud Shell

Google Cloud'u dizüstü bilgisayarınızdan uzaktan çalıştırabilirsiniz ancak bu codelab'de bulutta çalışan bir komut satırı ortamı olan Google Cloud Shell'i kullanacağız.

Google Cloud Shell'i etkinleştir

GCP Console'da sağ üstteki araç çubuğunda Cloud Shell simgesini tıklayın:

Ardından "Cloud Shell'i başlat"ı tıklayın:

Ortamın sağlanması ve bağlantının kurulması yalnızca birkaç saniye sürer:

Bu sanal makine, ihtiyaç duyacağınız tüm geliştirme araçlarını içerir. 5 GB boyutunda kalıcı bir ana dizin sunar ve Google Cloud üzerinde çalışır. Bu sayede ağ performansı ve kimlik doğrulama önemli ölçüde iyileştirilir. Bu laboratuvardaki çalışmalarınızın neredeyse tamamını yalnızca bir tarayıcı veya Google Chromebook'unuzla yapabilirsiniz.

Cloud Shell'e bağlandıktan sonra kimliğinizin zaten doğrulandığını ve projenin PROJECT_ID'nize göre ayarlandığını görürsünüz.

Kimliğinizin doğrulandığını onaylamak için Cloud Shell'de aşağıdaki komutu çalıştırın:

gcloud auth list

Komut çıkışı

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

Komut çıkışı

[core]
project = <PROJECT_ID>

Değilse aşağıdaki komutla ayarlayabilirsiniz:

gcloud config set project <PROJECT_ID>

Komut çıkışı

Updated property [core/project].

Google Cloud Pub/Sub konuları sayfasına gidin ve API'yi etkinleştirin.

Konu Oluştur'u tıklayın.

Konu adı olarak exampleTopic yazıp Oluştur'u tıklayın.

Konu oluşturulduktan sonra Konular sayfasında kalın. Yeni oluşturduğunuz konuyu bulun, satırın sonundaki üç dikey noktayı tıklayın ve Yeni Abonelik'i seçin.

Abonelik adı metin kutusuna exampleSubscription yazıp Oluştur'u tıklayın.

Cloud Shell başlatıldıktan sonra, Spring Initializr ile iki yeni Spring Boot uygulaması oluşturmak için komut satırını kullanabilirsiniz:

$ 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 -

Şimdi mesaj gönderme uygulamamızı oluşturalım. Gönderme uygulamasının dizinine geçin.

$ cd spring-integration-sender

Uygulamamızın bir kanala mesaj yazmasını istiyoruz. Bir ileti kanala girdikten sonra, giden kanal bağdaştırıcısı tarafından alınır. Bu bağdaştırıcı, iletiyi genel bir Spring iletisinden Google Cloud Pub/Sub iletisine dönüştürür ve Google Cloud Pub/Sub konusunda yayınlar.

Uygulamamızın bir kanala yazabilmesi için Spring Integration mesajlaşma ağ geçidini kullanabiliriz. vim, emacs veya nano kaynaklı bir metin düzenleyici kullanarak DemoApplication sınıfının içinde bir PubsubOutboundGateway arayüzü tanımlayın.

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

Artık kanala mesaj gönderme mekanizmamız var ancak kanala gönderilen mesajlar daha sonra nereye gidiyor?

Kanalda yeni mesajları kullanmak ve bunları Google Cloud Pub/Sub konusuna yayınlamak için giden kanal bağdaştırıcısına ihtiyacımız var.

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

@ServiceActivator ek açıklaması, MessageHandler öğesinin inputChannel içindeki tüm yeni mesajlara uygulanmasına neden olur. Bu durumda, mesajı Google Cloud Pub/Sub'ın exampleTopic konusuna yayınlamak için giden kanal bağdaştırıcımızı, PubSubMessageHandler, çağırıyoruz.

Kanal bağdaştırıcısı yerindeyken artık bir PubsubOutboundGateway nesnesini otomatik olarak bağlayabilir ve bunu bir kanala mesaj yazmak için kullanabiliriz.

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

@PostMapping notu sayesinde artık HTTP POST isteklerini dinleyen bir uç noktamız var. Ancak DemoApplication sınıfına @RestController notu ekleyerek bu sınıfı REST denetleyicisi olarak işaretlememiz gerekiyor.

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

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

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

Uygulamanın çalışması için gereken bağımlılıkları eklememiz yeterlidir.

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>

Gönderen uygulamasını çalıştırın.

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

Uygulama, 8080 numaralı bağlantı noktasında ve /postMessage uç noktasında mesaj içeren POST isteklerini dinliyor ancak bu konuya daha sonra değineceğiz.

Google Cloud Pub/Sub üzerinden mesaj gönderen bir uygulama oluşturduk. Şimdi bu mesajları alan ve işleyen başka bir uygulama oluşturacağız.

Yeni bir Cloud Shell oturumu açmak için + işaretini tıklayın.

Ardından, yeni Cloud Shell oturumunda dizinleri alıcı uygulamasının diziniyle değiştirin:

$ cd spring-integration-receiver

Önceki uygulamada, mesajlaşma ağ geçidi bildirimi bizim için giden kanal oluşturuyordu. İletileri almak için bir mesajlaşma ağ geçidi kullanmadığımızdan, gelen iletilerin ulaşacağı kendi MessageChannel değerimizi bildirmemiz gerekir.

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

Google Cloud Pub/Sub'dan mesaj almak ve bunları pubsubInputChannel'ya iletmek için gelen kanal bağdaştırıcısına ihtiyacımız olacak.

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

Bu adaptör, pubsubInputChannel'ya bağlanır ve Google Cloud Pub/Sub exampleSubscription aboneliğinden gelen yeni mesajları dinler.

Gelen mesajların yayınlandığı bir kanalımız var ancak bu mesajlarla ne yapmalıyız?

Yeni mesajlar pubsubInputChannel adresine ulaştığında tetiklenen bir @ServiceActivator ile bu mesajları işleyelim.

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

Bu durumda, yalnızca mesaj yükü günlüğe kaydedilir.

Gerekli bağımlılıkları eklememiz gerekiyor.

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>

Alıcı uygulamasını çalıştırın.

$ ./mvnw spring-boot:run

Artık gönderen uygulamasına gönderdiğiniz tüm mesajlar alıcı uygulamasına kaydedilir. Bunu test etmek için yeni bir Cloud Shell oturumu açın ve gönderen uygulamasına bir HTTP POST isteği gönderin.

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

Ardından, alıcı uygulamasının gönderdiğiniz mesajı kaydettiğini doğrulayın.

INFO: Message arrived! Payload: Hello world!

Bu alıştırma kapsamında oluşturulan aboneliği ve konuyu silin.

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

Google Cloud Pub/Sub için Spring Integration Channel Adapters'ı kullanan iki Spring Boot uygulaması ayarlarsınız. Google Cloud Pub/Sub API ile hiçbir zaman etkileşime girmeden kendi aralarında mesaj alışverişi yaparlar.

Google Cloud Pub/Sub için Spring Integration Channel Adapters'ı kullanmayı öğrendiniz.

Daha Fazla Bilgi

Lisans

Bu çalışma, Creative Commons Attribution 2.0 Genel Amaçlı Lisans ile lisans altına alınmıştır.