التشغيل السريع: إنشاء تطبيق Java Durable Functions

استخدم Durable Functions، وهي ميزة من ميزات Azure Functions، لكتابة وظائف ذات حالة في بيئة بلا خادم. تدير Durable Functions الحالة ونقاط التحقق وإعادة التشغيل في التطبيق الخاص بك.

في هذا التشغيل السريع، يمكنك إنشاء واختبار تطبيق Durable Functions "hello world" في Java.

يحتوي تطبيق Durable Functions الأساسي على ثلاث وظائف:

  • دالة المنسق: سير عمل ينسق دالات أخرى.
  • دالة النشاط: دالة يتم استدعاؤها بواسطة دالة المنسق، وتؤدي العمل، وترجع قيمة اختياريا.
  • دالة العميل: دالة عادية في Azure تبدأ دالة منسق. يستخدم هذا المثال دالة مشغلة من HTTP.

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

المتطلبات الأساسية

للتشغيل السريع، تحتاج إلى:

إذا لم يكن لديك اشتراك في Azure، فأنشئ حساب Azure مجاني قبل أن تبدأ.

إضافة التبعيات والمكونات الإضافية المطلوبة إلى مشروعك

أضف التعليمات البرمجية التالية إلى ملف pom.xml الخاص بك:

<properties>
  <azure.functions.maven.plugin.version>1.18.0</azure.functions.maven.plugin.version>
  <azure.functions.java.library.version>3.0.0</azure.functions.java.library.version>
  <durabletask.azure.functions>1.0.0</durabletask.azure.functions>
  <functionAppName>your-unique-app-name</functionAppName>
</properties>

<dependencies>
  <dependency>
    <groupId>com.microsoft.azure.functions</groupId>
    <artifactId>azure-functions-java-library</artifactId>
    <version>${azure.functions.java.library.version}</version>
  </dependency>
  <dependency>
    <groupId>com.microsoft</groupId>
    <artifactId>durabletask-azure-functions</artifactId>
    <version>${durabletask.azure.functions}</version>
  </dependency>
</dependencies>

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.1</version>
    </plugin>
    <plugin>
      <groupId>com.microsoft.azure</groupId>
      <artifactId>azure-functions-maven-plugin</artifactId>
      <version>${azure.functions.maven.plugin.version}</version>
      <configuration>
        <appName>${functionAppName}</appName>
        <resourceGroup>java-functions-group</resourceGroup>
        <appServicePlanName>java-functions-app-service-plan</appServicePlanName>
        <region>westus</region>
        <runtime>
          <os>windows</os>
          <javaVersion>11</javaVersion>
        </runtime>
        <appSettings>
          <property>
            <name>FUNCTIONS_EXTENSION_VERSION</name>
            <value>~4</value>
          </property>
        </appSettings>
      </configuration>
      <executions>
        <execution>
          <id>package-functions</id>
          <goals>
            <goal>package</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <artifactId>maven-clean-plugin</artifactId>
      <version>3.1.0</version>
    </plugin>
  </plugins>
</build>

إضافة ملفات JSON المطلوبة

أضف ملف host.json إلى دليل المشروع. يجب أن يبدو مشابها للمثال التالي:

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "DurableTask.AzureStorage": "Warning",
      "DurableTask.Core": "Warning"
    }
  },
  "extensions": {
    "durableTask": {
      "hubName": "JavaTestHub"
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  }
}

إشعار

من المهم ملاحظة أن حزمة ملحق Azure Functions v4 فقط لديها حاليا الدعم اللازم ل Durable Functions ل Java. لا يتم دعم Durable Functions ل Java في حزم الملحقات الأولية والإصدار 3. لمزيد من المعلومات حول حزم الملحقات، راجع وثائق حزم الملحقات.

تحتاج Durable Functions إلى موفر تخزين لتخزين حالة وقت التشغيل. أضف ملف local.settings.json إلى دليل المشروع لتكوين موفر التخزين. لاستخدام Azure Storage كموفر، قم بتعيين قيمة AzureWebJobsStorage إلى سلسلة الاتصال لحساب Azure Storage الخاص بك:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "<your storage account connection string>",
    "FUNCTIONS_WORKER_RUNTIME": "java"
  }
}

إنشاء دوالك الخاصة

يظهر نموذج التعليمات البرمجية التالي مثالا أساسيا لكل نوع من أنواع الدالات:

import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.*;
import java.util.*;

import com.microsoft.durabletask.*;
import com.microsoft.durabletask.azurefunctions.DurableActivityTrigger;
import com.microsoft.durabletask.azurefunctions.DurableClientContext;
import com.microsoft.durabletask.azurefunctions.DurableClientInput;
import com.microsoft.durabletask.azurefunctions.DurableOrchestrationTrigger;

public class DurableFunctionsSample {
    /**
     * This HTTP-triggered function starts the orchestration.
     */
    @FunctionName("StartOrchestration")
    public HttpResponseMessage startOrchestration(
            @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
            @DurableClientInput(name = "durableContext") DurableClientContext durableContext,
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        DurableTaskClient client = durableContext.getClient();
        String instanceId = client.scheduleNewOrchestrationInstance("Cities");
        context.getLogger().info("Created new Java orchestration with instance ID = " + instanceId);
        return durableContext.createCheckStatusResponse(request, instanceId);
    }

    /**
     * This is the orchestrator function, which can schedule activity functions, create durable timers,
     * or wait for external events in a way that's completely fault-tolerant.
     */
    @FunctionName("Cities")
    public String citiesOrchestrator(
            @DurableOrchestrationTrigger(name = "taskOrchestrationContext") TaskOrchestrationContext ctx) {
        String result = "";
        result += ctx.callActivity("Capitalize", "Tokyo", String.class).await() + ", ";
        result += ctx.callActivity("Capitalize", "London", String.class).await() + ", ";
        result += ctx.callActivity("Capitalize", "Seattle", String.class).await() + ", ";
        result += ctx.callActivity("Capitalize", "Austin", String.class).await();
        return result;
    }

    /**
     * This is the activity function that is invoked by the orchestrator function.
     */
    @FunctionName("Capitalize")
    public String capitalize(@DurableActivityTrigger(name = "name") String name, final ExecutionContext context) {
        context.getLogger().info("Capitalizing: " + name);
        return name.toUpperCase();
    }
}

إنشاء مشروع محلي باستخدام الأمر Maven

قم بتشغيل الأمر التالي لإنشاء مشروع يحتوي على الوظائف الأساسية لتطبيق Durable Functions:

mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DarchetypeVersion=1.51 -Dtrigger=durablefunctions

في المطالبات، قم بتوفير المعلومات التالية:

المطالبة الإجراء
groupId أدخل com.function.
artifactId أدخل myDurableFunction.
إصدار حدد 1.0-SNAPSHOT.
الحزمة أدخل com.function.
السنة أدخل Y وحدد Enter للتأكيد.

الآن لديك مشروع محلي يحتوي على الوظائف الثلاث الموجودة في تطبيق Durable Functions الأساسي.

تحقق للتأكد من com.microsoft:durabletask-azure-functions تعيينه كتبعية في ملف pom.xml .

تكوين موفر التخزين الخلفي

تحتاج Durable Functions إلى موفر تخزين لتخزين حالة وقت التشغيل. يمكنك تعيين Azure Storage كموفر تخزين في local.settings.json. استخدم سلسلة الاتصال حساب تخزين Azure كقيمة ل AzureWebJobsStorage مثل في هذا المثال:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "<your storage account connection string>",
    "FUNCTIONS_WORKER_RUNTIME": "java"
  }
}

إنشاء مشروعك المحلي

  1. في Visual Studio Code، حدد F1 (أو حدد Ctrl/Cmd+Shift+P) لفتح لوحة الأوامر. في المطالبة (>)، أدخل ثم حدد Azure Functions: Create New Project.

    لقطة شاشة لأمر إنشاء مشروع وظائف جديدة.

  2. حدد استعراض. في مربع الحوار تحديد مجلد ، انتقل إلى مجلد لاستخدامه لمشروعك، ثم اختر تحديد.

  3. في المطالبات، قم بتوفير المعلومات التالية:

    المطالبة الإجراء
    تحديد لغة حدد Java.
    تحديد إصدار من Java حدد Java 8 أو أحدث. حدد إصدار Java الذي تعمل عليه وظائفك في Azure، وإصدار قمت بالتحقق منه محليا.
    إدخال معرف مجموعة أدخل com.function.
    إدخال معرف بيانات اصطناعية أدخل myDurableFunction.
    إدخال إصدار أدخل 1.0-SNAPSHOT.
    إدخال اسم حزمة أدخل com.function.
    إدخال اسم تطبيق أدخل myDurableFunction.
    تحديد أداة الإنشاء لمشروع Java حدد Maven.
    تحديد الطريقة التي تريد فتح مشروعك بها حدد فتح في نافذة جديدة.

لديك الآن مشروع يحتوي على مثال لدالة HTTP. يمكنك إزالة هذه الدالة إذا كنت ترغب في ذلك، لأنك تضيف الوظائف الأساسية لتطبيق Durable Functions في الخطوة التالية.

إضافة دالات إلى المشروع

  1. في لوحة الأوامر، أدخل ثم حدد Azure Functions: Create Function.

  2. بالنسبة إلى تغيير عامل تصفية القالب، حدد الكل.

  3. في المطالبات، قم بتوفير المعلومات التالية:

    المطالبة الإجراء
    تحديد قالب لدالتك حدد DurableFunctionsOrchestration.
    إدخال اسم حزمة أدخل com.function.
    توفير اسم دالة أدخل DurableFunctionsOrchestrator.
  4. في مربع الحوار، اختر تحديد حساب تخزين لإعداد حساب تخزين، ثم اتبع المطالبات.

يجب أن يكون لديك الآن الوظائف الأساسية الثلاث التي تم إنشاؤها لتطبيق Durable Functions.

تكوين pom.xml host.json

أضف التبعية التالية إلى ملف pom.xml:

<dependency>
  <groupId>com.microsoft</groupId>
  <artifactId>durabletask-azure-functions</artifactId>
  <version>1.0.0</version>
</dependency>

أضف الخاصية extensions إلى ملف host.json:

"extensions": { "durableTask": { "hubName": "JavaTestHub" }}

اختبِر الدالة محليًا

تمنحك Azure Functions Core Tools القدرة على تشغيل مشروع Azure Functions على كمبيوتر التطوير المحلي.

إشعار

تتطلب Durable Functions ل Java Azure Functions Core Tools الإصدار 4.0.4915 أو أحدث. يمكنك معرفة الإصدار الذي تم تثبيته عن طريق تشغيل func --version الأمر في المحطة الطرفية.

  1. إذا كنت تستخدم Visual Studio Code، فافتح نافذة طرفية جديدة وقم بتشغيل الأوامر التالية لإنشاء المشروع:

    mvn clean package
    

    ثم قم بتشغيل الدالة الدائمة:

    mvn azure-functions:run
    
  2. في لوحة المحطة الطرفية، انسخ نقطة نهاية عنوان URL للدالة التي تم تشغيلها من قبل HTTP.

    لقطة شاشة تظهر الإخراج المحلي الخاص بـ Azure.

  3. استخدم أداة اختبار HTTP لإرسال طلب HTTP POST إلى نقطة نهاية URL.

    يجب أن تبدو الاستجابة مشابهة للنص التالي:

    {
        "id": "d1b33a60-333f-4d6e-9ade-17a7020562a9",
        "purgeHistoryDeleteUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9?code=ACCupah_QfGKo...",
        "sendEventPostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9/raiseEvent/{eventName}?code=ACCupah_QfGKo...",
        "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9?code=ACCupah_QfGKo...",
        "terminatePostUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/d1b33a60-333f-4d6e-9ade-17a7020562a9/terminate?reason={text}&code=ACCupah_QfGKo..."
    }
    

    الاستجابة هي النتيجة الأولية لدالة HTTP. يتيح لك معرفة أن التزامن الدائم بدأ بنجاح. لا يعرض بعد النتيجة النهائية للتنسيق. تتضمن الاستجابة بعض عناوين URL المفيدة. في الوقت الحالي، استعلم عن حالة التنسيق.

  4. انسخ قيمة URL ل statusQueryGetUri، والصقها في شريط عناوين المستعرض، وقم بتنفيذ الطلب. بدلا من ذلك، يمكنك الاستمرار في استخدام أداة اختبار HTTP لإصدار طلب GET.

    يستعلم الطلب عن مثيل التنسيق للحالة. يجب أن ترى أن المثيل قد انتهى وأنه يتضمن مخرجات أو نتائج الدالة الدائمة، كما هو الحال في هذا المثال:

    {
        "name": "Cities",
        "instanceId": "d1b33a60-333f-4d6e-9ade-17a7020562a9",
        "runtimeStatus": "Completed",
        "input": null,
        "customStatus": "",
        "output":"TOKYO, LONDON, SEATTLE, AUSTIN",
        "createdTime": "2022-12-12T05:00:02Z",
        "lastUpdatedTime": "2022-12-12T05:00:06Z"
    }