1. نظرة عامة
يوفّر لك Spring Integration آلية للمراسلة لتبادل Messages
من خلال MessageChannels
. فهو يستخدم محوّلات القناة للاتصال بالأنظمة الخارجية.
في هذا التمرين، سننشئ تطبيقين يتصلان باستخدام محوّلات قنوات Spring Integration المقدَّمة من Spring Cloud GCP. وتجعل هذه المحوّلات Spring Integration تستخدم Google Cloud Pub/Sub كخلفية لتبادل الرسائل.
وستتعلّم كيفية استخدام Cloud Shell وأمر gcloud SDK للسحابة الإلكترونية.
يستخدم هذا البرنامج التعليمي نموذج الرمز الوارد في دليل بدء تشغيل Spring Boot.
المعلومات التي ستطّلع عليها
- طريقة تبادل الرسائل بين التطبيقات من خلال Google Cloud Pub/Sub باستخدام Spring Integration وSpring Cloud GCP
المتطلبات
- مشروع Google Cloud Platform
- متصفح، مثل Chrome أو Firefox
- الإلمام بأدوات تحرير النصوص القياسية في Linux مثل Vim أو EMAC أو Nano
كيف ستستخدم هذا البرنامج التعليمي؟
كيف تقيّم تجربتك في إنشاء تطبيقات ويب بتنسيق HTML/CSS؟
ما هو تقييمك لتجربتك في استخدام خدمات Google Cloud Platform؟
2. الإعداد والمتطلبات
إعداد بيئة ذاتية
- سجِّل الدخول إلى Google Cloud Console وأنشئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.
- اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديلها في أي وقت.
- يكون رقم تعريف المشروع فريدًا في جميع مشاريع Google Cloud وغير قابل للتغيير (لا يمكن تغييره بعد تحديده). تنشئ Cloud Console سلسلة فريدة تلقائيًا. فعادةً لا تهتم بما هو. في معظم الدروس التطبيقية حول الترميز، يجب الإشارة إلى رقم تعريف المشروع (الذي يتم تحديده عادةً على أنّه
PROJECT_ID
). وإذا لم يعجبك رقم التعريف الذي تم إنشاؤه، يمكنك إنشاء رقم تعريف عشوائي آخر. ويمكنك بدلاً من ذلك تجربة طلبك الخاص ومعرفة ما إذا كان متاحًا. ولا يمكن تغييره بعد هذه الخطوة ويبقى طوال مدة المشروع. - لمعلوماتك، هناك قيمة ثالثة، وهي رقم المشروع، الذي تستخدمه بعض واجهات برمجة التطبيقات. اطّلِع على مزيد من المعلومات حول هذه القيم الثلاث في المستندات.
- بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام الموارد/واجهات برمجة التطبيقات في Cloud. لن يؤدي إكمال هذا الدرس التطبيقي حول الترميز إلى فرض أي تكاليف، إن وُجدت. لإيقاف تشغيل الموارد لتجنب تحمُّل الفواتير إلى ما هو أبعد من هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع. يكون مستخدمو Google Cloud الجدد مؤهَّلون للانضمام إلى برنامج فترة تجريبية مجانية بقيمة 300 دولار أمريكي.
Google Cloud Shell
يمكن إدارة Google Cloud عن بُعد من الكمبيوتر المحمول، ولكن في هذا الدرس التطبيقي حول الترميز، سنستخدم Google Cloud Shell، وهي بيئة سطر أوامر يتم تشغيلها في السحابة الإلكترونية.
تفعيل Cloud Shell
- من Cloud Console، انقر على تفعيل Cloud Shell .
إذا كانت هذه هي المرة الأولى التي تبدأ فيها Cloud Shell، ستظهر لك شاشة وسيطة تصف ماهيتها. إذا ظهرت لك شاشة وسيطة، انقر على متابعة.
من المفترَض أن تستغرق عملية توفير المتطلبات اللازمة والاتصال بخدمة Cloud Shell بضع دقائق فقط.
يتم تحميل هذا الجهاز الافتراضي مع جميع أدوات التطوير اللازمة. وتوفّر هذه الشبكة دليلاً رئيسيًا دائمًا بسعة 5 غيغابايت ويتم تشغيله في Google Cloud، ما يحسّن بشكل كبير من أداء الشبكة والمصادقة. يمكنك تنفيذ معظم عملك، إن لم يكن كلّه، في هذا الدرس التطبيقي حول الترميز باستخدام متصفّح.
بعد الربط بخدمة Cloud Shell، من المفترض أن تتأكّد من أنّه تمّت مصادقتك وأنّ المشروع مضبوط على رقم تعريف مشروعك.
- شغِّل الأمر التالي في Cloud Shell لتأكيد مصادقتك:
gcloud auth list
مخرجات الأمر
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- شغّل الأمر التالي في Cloud Shell للتأكد من معرفة الأمر gcloud بمشروعك:
gcloud config list project
مخرجات الأمر
[core] project = <PROJECT_ID>
إذا لم يكن كذلك، يمكنك تعيينه من خلال هذا الأمر:
gcloud config set project <PROJECT_ID>
مخرجات الأمر
Updated property [core/project].
3- توفير موارد النشر/الاشتراك
انتقِل إلى صفحة مواضيع Google Cloud Pub/Sub.
انقر على إنشاء موضوع.
اكتب exampleTopic
كاسم للموضوع، ثم انقر على إنشاء.
بعد إنشاء الموضوع، ابقَ في صفحة "المواضيع". ابحث عن الموضوع الذي أنشأته للتو، واضغط على النقاط العمودية الثلاث في نهاية السطر وانقر على اشتراك جديد.
اكتب exampleSubscription
في مربّع نص اسم الاشتراك وانقر على إنشاء.
4. إعداد تطبيقات التمهيد الربيعي
بعد إطلاق Cloud Shell، يمكنك استخدام سطر الأوامر لإنشاء تطبيقين جديدين لـ Spring Boots باستخدام 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- إنشاء تطبيق لإرسال الرسائل
لننشئ الآن تطبيق إرسال الرسائل. يمكنك التغيير إلى دليل التطبيق المُرسِل.
$ 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 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");
}
}
يتسبب التعليق التوضيحي @ServiceActivator
في تطبيق MessageHandler
هذا على أي رسائل جديدة في inputChannel
. في هذه الحالة، نستدعي محوّل القناة الصادرة، PubSubMessageHandler
، لنشر الرسالة في موضوع exampleTopic
في Google Cloud Pub/Sub.
بعد تنفيذ محوِّل القناة في مكانه الصحيح، يمكننا الآن توصيل كائن 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 {
...
}
تأكَّد من ضبط JAVA_HOME
على الإصدار الصحيح.
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
شغِّل تطبيق المُرسِل.
# 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
، لكننا سنتطرق إليه لاحقًا.
6- إنشاء تطبيق لتلقّي الرسائل
لقد أنشأنا للتو تطبيقًا لإرسال الرسائل من خلال 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 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;
}
}
يربط هذا المحوِّل نفسه بـ 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);
}
}
تأكَّد من ضبط JAVA_HOME
على الإصدار الصحيح.
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
شغِّل تطبيق جهاز الاستقبال.
$ ./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8081"
سيتم الآن تسجيل أي رسائل ترسلها إلى تطبيق المرسِل في تطبيق المُستلِم. لاختبار ذلك، افتح جلسة Cloud Shell جديدة وأرسِل طلب HTTP POST إلى تطبيق المُرسِل.
$ curl --data "message=Hello world!" localhost:8080/postMessage
بعد ذلك، تحقَّق من أنّ تطبيق المُستلِم سجّل الرسالة التي أرسلتها.
INFO: Message arrived! Payload: Hello world!
7. تنظيف
احذف الاشتراك والموضوع اللذين تم إنشاؤهما كجزء من هذا التمرين.
$ gcloud pubsub subscriptions delete exampleSubscription
$ gcloud pubsub topics delete exampleTopic
8. ملخّص
يمكنك إعداد تطبيقَين في Spring Boot يستخدمان محوّلات قنوات Spring Integration في Google Cloud Pub/Sub. حيث يتبادلون الرسائل فيما بينهم بدون التفاعل على الإطلاق مع واجهة برمجة تطبيقات Google Cloud Pub/Sub.
9. تهانينا!
لقد تعلّمت كيفية استخدام Spring Integration Channel Adapters في Google Cloud Pub/Sub.
مزيد من المعلومات
- Google Cloud Pub/Sub: https://cloud.google.com/pubsub/
- بدء مشروع Google Cloud Platform: http://cloud.spring.io/spring-cloud-gcp/
- الانتقال إلى مستودع GitHub في Google Cloud Platform: https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- Java على Google Cloud Platform: https://cloud.google.com/java/
الترخيص
هذا العمل مرخّص بموجب رخصة المشاع الإبداعي 2.0 مع نسب العمل إلى مؤلف عام.