المراسلة مع Spring Integration وGoogle Cloud Pub/Sub

يزوّدك دمج الربيع بآلية مراسلة لتبادل Messages حتى MessageChannels. تستخدم هذه الميزة مهايئات القنوات للتواصل مع الأنظمة الخارجية.

في هذا التدريب، سننشئ تطبيقين يتصلان باستخدام محوّلات قنوات Spring Integration التي توفّرها شركة Spring Cloud Cloud. تجعل هذه المحولات Spring Integration تستخدم Google Cloud Pub/Sub كخلفية لتبادل الرسائل.

ستتعلّم كيفية استخدام Cloud Shell والأمر Cloud gcloud في الأمر.

يستخدم هذا البرنامج التعليمي نموذج الرمز من دليل بدء تشغيل الربيع.

ما ستتعرّف عليه

  • كيفية تبادل الرسائل بين التطبيقات باستخدام Google Cloud Pub/Sub باستخدام Spring Integration وSpring Cloud Cloud

المتطلبات اللازمة

  • مشروع Google Cloud Platform
  • متصفح، مثل Chrome أو Firefox
  • الإلمام بأدوات تحرير النصوص في Linux مثل Vim أو EMACs أو Nano

كيف ستستخدم هذا البرنامج التعليمي؟

قراءة القراءة فقط قراءة القراءة وإكمال التدريبات

كيف تقيّم تجربة تصميم تطبيقات HTML/CSS على الويب؟

مبتدئ متوسط خبير

كيف تقيّم تجربتك في استخدام خدمات Google Cloud Platform؟

مبتدئ متوسط محترف

إعداد البيئة الذاتية

إذا لم يكن لديك حساب على Google (Gmail أو Google Apps)، يجب إنشاء حساب. تسجيل الدخول إلى وحدة تحكُّم Google Cloud Platform (console.cloud.google.com) وإنشاء مشروع جديد:

لقطة شاشة من 2016-02-10 الساعة 12:45:26.png

عذرًا! وسيُشار إليه لاحقًا في هذا الدرس التطبيقي بعنوان PROJECT_ID.

بعد ذلك، ستحتاج إلى تفعيل الفوترة في Cloud Console لاستخدام موارد Google Cloud.

من المفترض ألا يكلفك العمل على هذا الدرس التطبيقي أكثر من بضعة دولارات، ولكن قد يترتّب عليك أكثر إذا قررت استخدام المزيد من الموارد أو إذا تركتها قيد التشغيل (راجع قسم "عرض الأسعار التقديري" في نهاية هذا المستند).

يكون المستخدمون الجدد لخدمة Google Cloud Platform مؤهَّلين للاستفادة من فترة تجريبية مجانية تبلغ 300 دولار أمريكي.

Google Cloud Shell

علمًا أنه يمكن تشغيل Google Cloud عن بُعد من الكمبيوتر المحمول، فإننا في هذا الدرس التطبيقي سنستخدم Google Cloud Shell، وهو بيئة سطر أوامر يتم تشغيلها في السحابة الإلكترونية.

تفعيل Google Cloud Shell

من وحدة تحكّم Google Cloud Platform، انقر على رمز Cloud Shell في شريط الأدوات العلوي الأيسر:

ثم انقر على "بدء Cloud Shell":

ينبغي ألا تستغرق إدارة الحسابات والاتصال بالبيئة أكثر من بضع لحظات.

يتم تحميل هذه الآلة الافتراضية مزوّدة بكل أدوات التطوير التي ستحتاج إليها. وتوفِّر هذه الآلة دليلاً رئيسيًا دائمًا بسعة 5 غيغابايت ويتمّ تشغيله على Google Cloud، ما يحسّن كثيرًا أداء الشبكة والمصادقة. ويمكن إتمام معظم عملك إن لم يكن كلّه في هذا الدرس ببساطة من خلال متصفّح أو جهاز Google Chromebook فقط.

عند الاتصال بخدمة Cloud Shell، من المفترض أن تتم مصادقتها وأنّ المشروع قد سبق وتم ضبطه على PROJECT_ID.

شغِّل الأمر التالي في Cloud Shell لتأكيد أنّك تمت مصادقته:

gcloud auth list

مخرجات الأوامر

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

مخرجات الأوامر

[core]
project = <PROJECT_ID>

إذا لم يكن كذلك، يمكنك تعيينه من خلال هذا الأمر:

gcloud config set project <PROJECT_ID>

مخرجات الأوامر

Updated property [core/project].

انتقِل إلى صفحة مواضيع Google Cloud Pub/Sub وفعِّل واجهة برمجة التطبيقات.

انقر على إنشاء موضوع.

اكتب exampleTopic كاسم للموضوع، ثم انقر على إنشاء.

بعد إنشاء الموضوع، ابقَ في صفحة "المواضيع". ابحث عن الموضوع الذي أنشأته للتو، اضغط على الثلاث نقاط الرأسية في نهاية السطر وانقر على اشتراك جديد.

اكتب exampleSubscription في مربع نص اسم الاشتراك، ثم انقر على إنشاء.

بعد إطلاق Cloud Shell، يمكنك استخدام سطر الأوامر لإنشاء تطبيقَي Spring Start جديدين باستخدام 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 -

لنبدأ الآن في إنشاء تطبيق إرسال الرسائل. يمكنك التغيير إلى دليل تطبيق الإرسال.

$ cd spring-integration-sender

نريد أن يكتب تطبيقنا الرسائل إلى إحدى القنوات. بعد أن تصبح الرسالة في القناة، يتم استلامها من خلال محوِّل القناة الصادرة الذي يحوِّلها من رسالة Spring عامة إلى رسالة Google Cloud Pub/Sub وتنشرها في موضوع Google Cloud Pub/Sub.

لنتمكن من الكتابة على قناة، يمكننا استخدام مدخل المراسلة Spring Integration. باستخدام محرِّر نصوص من vim أو emacs أو nano، يمكنك تعريف واجهة PubsubOutboundGateway داخل الصف 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);
        }
}

والآن، تتوفّر لدينا آلية لإرسال الرسائل إلى القناة، ولكن أين تذهب هذه الرسائل بعد نقلها إلى القناة؟

نحتاج إلى محوّل قناة صادرة لعرض الرسائل الجديدة في القناة ونشرها في موضوع 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");
        }
}

يؤدي التعليق التوضيحي @ServiceActivator إلى تطبيق MessageHandler على أي رسائل جديدة في inputChannel. في هذه الحالة، نحن نتصل بمحوّل القنوات الصادرة، PubSubMessageHandler، لنشر الرسالة إلى موضوع Google Cloud Pub/Sub&#39؛ exampleTopic.

بعد إعداد محوّل القناة، يمكننا الآن توصيل كائن PubsubOutboundGateway تلقائيًا واستخدامه لإرسال رسالة إلى قناة.

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، أصبح لدينا الآن نقطة نهاية تستمع إلى طلبات HTTP POST، ولكن لا تضيف أيضًا تعليقًا توضيحيًا إلى @RestController إلى الصف DemoApplication لوضع علامة عليه باعتباره وحدة تحكم REST.

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

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

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

لتشغيل التطبيق، نحتاج فقط إلى إضافة الاعتماديات المطلوبة.

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>

شغِّل تطبيق المُرسِل.

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

يستمع التطبيق إلى طلبات POST التي تحتوي على رسالة على المنفذ 8080 ونقطة النهاية /postMessage، ولكننا سنصل إلى ذلك في وقت لاحق.

لقد أنشأنا للتو تطبيقًا يُرسِل الرسائل عبر Google Cloud Pub/Sub. والآن سننشئ تطبيقًا آخر يتلقى هذه الرسائل ويعالجها.

انقر على + لفتح جلسة جديدة في Cloud Shell.

ثم في جلسة Cloud Shell الجديدة، غيِّر الدلائل إلى دليل تطبيق المُستلِم:

$ cd spring-integration-receiver

في التطبيق السابق، أنشأ بيان بوابة المراسلة القناة الصادرة لنا. بما أننا لا نستخدم مدخل الرسائل لتلقي الرسائل، نحتاج إلى الإعلان عن MessageChannel الخاص بنا الذي ستصل إليه الرسائل الواردة.

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 وإرسالها إلى 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;
        }
}

يربط هذا المحوّل نفسه بـ pubsubInputChannel ويستمع إلى الرسائل الجديدة من اشتراك Google Cloud Pub/Sub exampleSubscription.

لدينا قناة يتم نشر الرسائل الواردة عليها، ولكن كيف يمكن التعامل مع هذه الرسائل؟

لنعالجها باستخدام @ServiceActivator التي يتم تشغيلها عند وصول رسائل جديدة إلى 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);
        }
}

في هذه الحالة، سنسجّل فقط البيانات الأساسية للرسالة.

يجب إضافة التبعيات اللازمة.

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>

شغِّل تطبيق المُستلِم.

$ ./mvnw spring-boot:run

سيتم الآن تسجيل أي رسائل ترسلها إلى تطبيق المُرسِل على تطبيق المُستلِم. لاختبار ذلك، افتح جلسة Cloud Shell جديدة وقدِّم طلب HTTP POST إلى تطبيق المُرسِل.

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

تحقَّق بعد ذلك من أنّ التطبيق المُستلِم سجّل الرسالة التي أرسلتها.

INFO: Message arrived! Payload: Hello world!

احذف الاشتراك والموضوع الذي تم إنشاؤه كجزء من هذا التمرين.

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

يمكنك إعداد تطبيقين Spring Kiosk يستخدمان مهايئات Spring Integration Channel لكل من Google Cloud Pub/Sub. يتبادلون الرسائل بين أنفسهم بدون التفاعل مع واجهة برمجة تطبيقات Google Cloud Pub/Sub.

لقد تعرّفت على كيفية استخدام مهايئات Spring Integration Channel لكل من Google Cloud Pub/Sub.

مزيد من المعلومات

الترخيص

يخضع هذا العمل لترخيص بموجب رخصة المشاع الإبداعي مع نسب العمل إلى مؤلفه 2.0.