يا هبر! أقدم انتباهكم إلى ترجمة المقال بواسطة بيرند روكر.
07.07.2020/XNUMX/XNUMX, ترجمة بيرند روكر

غالبًا ما أناقش هندسة الخدمات الصغيرة مع أشخاص لا يستخدمون Java: مطورو C#، أو مطورو Node.JS/JavaScript، أو هواة Golang. يواجه كل منهم حقيقة أنهم بحاجة إلى آلية تنسيق في بنية الخدمات الصغيرة، أو مجرد أداة لتبسيط سير العمل واكتساب القدرة على الطلب والتعامل مع المهلات والملحمة وتعويض المعاملات.
منصة BPM مع عظيم لمثل هذه المهام. تعد سهولة المطور إحدى الميزات الرئيسية للمنتج. ولكن إذا نظرت إلى وثائقها، فقد يكون لديك انطباع بأن "ملاءمة" Camunda تستهدف بشكل أساسي مطوري Java. توفر المنصة الكثير من الخيارات لربط الوظائف والإضافات الخاصة بك، ولكن كل ذلك يتم في Java. هل هو حقا؟
لا! في الواقع، يمكنك بسهولة تشغيل Camunda دون أي معرفة بجافا وإعداد بنية التعليمات البرمجية بأي لغة من اختيارك. في هذا المقال سننظر إلى:
- الهندسة المعمارية الأساسية
- واجهة برمجة تطبيقات REST
- نصيحة بشأن مكتبات العملاء الحالية للغات أخرى غير جافا؛
- مثال باستخدام C# وNode.JS؛
- طرق تشغيل خادم Camunda (Docker أو Tomcat).
هندسة معمارية
Camunda مكتوب بلغة Java ويحتاج إلى Java Virtual Machine (JVM) لتشغيله. توفر Camunda واجهة REST API التي تتيح لك الكتابة بأي لغة تريدها واستخدام REST مع Camunda:

يتم تعريف سير العمل في Camunda في BPMN، وهو في الأساس ملف XML. يمكن تصميمه مع .
تشغيل Camunda من خلال صورة Docker مُعدة مسبقًا
أسهل طريقة لتشغيل Camunda هي استخدام Docker. سيتم وصف الطرق البديلة لإطلاق Camunda لاحقًا في هذه المقالة.

في هذه الحالة، قم ببساطة بتشغيل:
docker run -d -p 8080:8080 camunda/camunda-bpm-platform:latest
لا داعي للقلق بشأن Linuxآلات جافا الافتراضية، أو خوادم تومكات. تتوفر ملفات دوكر والوثائق الأساسية (مثل تعليمات الاتصال بقواعد البيانات المطلوبة) على الموقع الإلكتروني التالي: .
إذا كنت تريد تشغيل Camunda Enterprise Edition، فيمكنك التغيير بسهولة .
ومع ذلك، فإن تشغيل Camunda مع Docker له جانب سلبي واحد: سينتهي بك الأمر بإصدار Tomcat الذي لا يتضمن دائمًا أحدث الإصلاحات. للتغلب على هذه المشكلة، يمكنك إنشاء صورة Docker الخاصة بك استنادًا إلى توزيع Tomcat المطلوب، كما هو موضح في هذا المثال، أو استخدام أحد الحلول الموضحة أدناه.
نشر نموذج العملية
دعونا نلقي نظرة على مثال باستخدام قالب Saga لحجز رحلة كلاسيكي حيث تريد تشغيل ثلاثة إجراءات متتالية والتعويض بأمان عن الإجراءات المكتملة بنجاح في حالة حدوث فشل لاحق. يتم تمثيله في نموذج BPMN، ويبدو كما يلي:

الآن يمكنك استخدام ملفات . لنفترض أنك حفظته باسم trip.bpmn وقمت بتشغيل Camunda عبر Docker بحيث كان متاحًا على المضيف المحلي:8080:
curl -w "n"
-H "Accept: application/json"
-F "deployment-name=trip"
-F "enable-duplicate-filtering=true"
-F "deploy-changed-only=true"
-F "trip.bpmn=@trip.bpmn"
http://localhost:8080/engine-rest/deployment/creat
الآن يمكنك الركض استخدام REST API وتمرير البيانات التي تريد رؤيتها كمتغيرات مثيل سير العمل:
curl
-H "Content-Type: application/json"
-X POST
-d '{"variables":{"someData" : {"value" : "someValue", "type": "String"}},"businessKey" : "12345"}}'
http://localhost:8080/engine-rest/<!-- -->process-definition/key/<!-- -->FlowingTripBookingSaga<!-- -->/start
السؤال التالي المثير للاهتمام هو كيف يمكن لـ Camunda تفعيل إجراءات مثل حجز سيارة؟ لا يمكن لـ Camunda الاتصال بالخدمات على الفور (مبدأ الدفع) فحسب، وذلك باستخدام بعض الميزات المضمنة ، ولكن أيضًا ضع عناصر العمل في نوع من الترتيب المدمج. يمكن للعامل بعد ذلك جلب عناصر العمل عبر REST، وتنفيذ العمل، وإخبار Camunda بإكماله (مبدأ السحب).

لذا عليك أولاً التنفيذ (لأن العمال الآخرين يمكنهم تلقي المهام في نفس الوقت لتوسيع نطاق النظام):
curl
-H "Content-Type: application/json"
-X POST
-d <!-- -->'{"workerId":"worker123","maxTasks":1,"usePriority":true,"topics":[{"topicName": "reserve-car"}, "lockDuration": 10000, "variables": ["someData"]}]}'<!-- -->
http://localhost:8080/engine-rest/external-task/fetchAndLock
ثم أخبر كاموندا بذلك (لاحظ أنه يجب عليك إدخال معرف المهمة الخارجية الذي تلقيته في الطلب الأول):
curl
-H "Content-Type: application/json"
-X POST
-d <!-- -->'{"workerId":"worker123", "variables": {}}'<!-- -->
http://localhost:8080/engine-rest/<!-- -->external-task/EXTERNAL_TASK_ID/complete
هذا كل شيء - مازلت لا تحتاج إلى أي جافا، أليس كذلك؟ وهذا يكفي للبدء!
مكتبات العملاء
يعد الاتصال بـ REST API أمرًا سهلاً بأي لغة برمجة. في JavaScript، يتم ذلك بسهولة باستخدام JQuery، وفي C#، باستخدام System.Net.Http وNewtonsoft.Json. ولكن هذا سوف يستغرق وقتا. لذلك يمكنك فقط استخدام بعض مكتبة العملاء.
تتوفر حاليًا العديد من مكتبات العملاء الجاهزة:
- جافا سكريبت: . بدعم من كاموندا.
- جافا: . بدعم من كاموندا.
- جيم #: и . كلا هذين المشروعين في حالة متوسطة وخاملة من الناحية العملية، ولكن يمكن أن يكونا بمثابة نقطة انطلاق جيدة؛
- PHP: - ليس كاملاً جدًا ولا يتضمن أحدث تغييرات واجهة برمجة التطبيقات، لكنني أعرف المشاريع التي تستخدمه.
باستثناء JavaScript وJava، لا تعد مكتبات العملاء جزءًا من منتج Camunda نفسه. لا تتوقع منهم أن يدعموا جميع ميزات REST API الخاصة بـ Camunda. فقط لأن المكتبة لا توفر وظيفة معينة لا يعني أنها غير موجودة، تحقق دائمًا من REST API الخاص بـ Camunda. تستخدم المشاريع المرجعية المكتبات كنقطة بداية وقالب.
مثال C#
باستخدام مكتبة العميل المذكورة أعلاه، يمكننا ببساطة كتابة:
var camunda = new CamundaEngineClient("http://localhost:8080/engine-rest/engine/default/", null, null);
// Deploy the BPMN XML file from the resources
camunda.RepositoryService.Deploy("trip-booking", new List<object> {
FileParameter.FromManifestResource(Assembly.GetExecutingAssembly(), "FlowingTripBookingSaga.Models.FlowingTripBookingSaga.bpmn")
});
// Register workers
registerWorker("reserve-car", externalTask => {
// here you can do the real thing! Like a sysout :-)
Console.WriteLine("Reserving car now...");
camunda.ExternalTaskService.Complete(workerId, externalTask.Id);
});
registerWorker("cancel-car", externalTask => {
Console.WriteLine("Cancelling car now...");
camunda.ExternalTaskService.Complete(workerId, externalTask.Id);
});
registerWorker("book-hotel", externalTask => {
Console.WriteLine("Reserving hotel now...");
camunda.ExternalTaskService.Complete(workerId, externalTask.Id);
});
// Register more workers...
StartPolling();
string processInstanceId = camunda.BpmnWorkflowService.StartProcessInstance("FlowingTripBookingSaga", new Dictionary<string, object>()
{
{"someBookingData", "..." }
});
يمكن العثور على كود المصدر العامل بالكامل عبر الإنترنت: . مثال آخر متاح في .
مثال مع Node.js
var Workers = require('camunda-worker-node');
var workers = Workers('http://localhost:8080/engine-rest', {
workerId: 'some-worker-id'
});
workers.registerWorker('reserve-car', [ 'someData' ], function(context, callback) {
var someNewData = context.variables.someData + " - added something";
callback(null, {
variables: {
someNewData: someNewData
}
});
});
workers.shutdown();
يمكن العثور على مزيد من المعلومات على الموقع
طرق بديلة لإطلاق Camunda
صورة Docker مخصصة مع "Camunda المستقلة WAR"
كبديل لصورة Docker التي تم إنشاؤها مسبقًا من Camunda، يمكنك إعداد Tomcat بنفسك (على سبيل المثال، استنادًا إلى صور Docker Tomcat الرسمية) ثم نسخ Camunda إليها كأحد ملفات WAR المزعومة.

إذا كان لديك العديد من المتطلبات الإضافية ويمكنك تخصيص بيئة إنشاء Java، فيمكنك أيضًا تكوين Camunda Standalone war. قم بإعداد بناء Maven كما في هذه الأمثلة: build أو التجمع .
بدء توزيع Camunda Tomcat
هناك خيار آخر يتمثل في تنزيل توزيعة Camunda Tomcat وفك ضغطها وتشغيلها. يتطلب هذا فقط تثبيت Java Runtime Environment (JRE) على جهاز الكمبيوتر الخاص بك. يمكن أن يكون بسهولة .

من أجل تغيير قاعدة البيانات أو القيام بأي شيء آخر تحتاج إلى تكوين Tomcat مثل . أعلم أن Tomcat قد يبدو معقدًا، لكنه في الواقع بسيط جدًا. ولدى Google الإجابات على كل ما قد تحتاجه في هذه العملية.
تشغيل Camunda باستخدام Tomcat
البديل الأخير هو إعداد Tomcat بنفسك وتثبيت Camunda فيه، سيمنحك هذا الخيار استخدام أي إصدار من Tomcat تفضله، أو على سبيل المثال، تثبيته كخدمة. Windows.
إطلاق Camunda في الإنتاج
سيتطلب هذا عادةً بعض الإعداد النهائي لتشغيل Camunda. توجد إرشادات في Camunda تصف ذلك بتفصيل كبير، لكنني لن أخوض فيها في هذه المقالة - سأذكر مثالًا واحدًا فقط: لم يتم تكوين REST API للتوزيع للمصادقة بشكل افتراضي. قد ترغب في تغيير هذا.
بالعرض الذي قدم
كما لاحظت، فإن البدء باستخدام Camunda أمر سهل للغاية، بغض النظر عن اللغة التي تستخدمها. النقطة الأساسية هي أن جميع الاتصالات تتم من خلال REST API. التثبيت أيضًا بسيط جدًا، خاصة عند استخدام Docker.
المصدر: www.habr.com
