دوال Google Cloud في C#

1. مقدمة

وظائف Google Cloud Run هي منصّة حوسبة بدون خادم مستندة إلى الأحداث. تتيح لك دوالّ Cloud Run كتابة رمزك البرمجي بدون القلق بشأن توفير الموارد أو التوسّع في الحجم لتلبية المتطلبات المتغيّرة.

هناك نوعان من وظائف Cloud Run:

  • تستجيب دوال HTTP لطلبات HTTP.
  • يتم تنشيط دوالّ الأحداث من خلال الأحداث، مثل رسالة يتم نشرها على Cloud Pub/Sub أو ملف يتم تحميله إلى Cloud Storage.

efb3268e3b74ed4f.png

سيرشدك هذا الدليل التعليمي إلى إنشاء وظائف Cloud Run الخاصة بك في C#. وبشكل أكثر تحديدًا، ستنشر وظائف C# التي تستجيب لطلبات HTTP وCloudEvents من مصادر مختلفة في Google Cloud.

المُعطيات

  • إطار عمل Functions لـ ‎.NET
  • كيفية كتابة دالة HTTP
  • كيفية كتابة دالة يتم تنشيطها من خلال حدث تستجيب لأحداث Cloud Storage
  • كيفية كتابة دالة يتم تنشيطها من خلال حدث تستجيب لأحداث Cloud Pub/Sub
  • كيفية كتابة دالة يتم تنشيطها من خلال حدث وتستجيب لأي نوع من الأحداث

2. الإعداد والمتطلبات

إعداد البيئة حسب السرعة التي تناسبك

  1. سجِّل الدخول إلى Google Cloud Console وأنشئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها واجهات برمجة تطبيقات Google. ويمكنك تعديله في أي وقت.
  • يجب أن يكون معرّف المشروع فريدًا في جميع مشاريع Google Cloud وأن يكون ثابتًا (لا يمكن تغييره بعد ضبطه). تُنشئ وحدة تحكّم Cloud Console سلسلة فريدة تلقائيًا، ولا يهمّك عادةً معرفة محتواها. في معظم ورشات عمل رموز البرامج، ستحتاج إلى الإشارة إلى معرّف المشروع (يُعرَف عادةً باسم PROJECT_ID). إذا لم يعجبك المعرّف الذي تم إنشاؤه، يمكنك إنشاء معرّف آخر عشوائي. يمكنك بدلاً من ذلك تجربة عنوانك ومعرفة ما إذا كان متاحًا. ولا يمكن تغييره بعد هذه الخطوة وسيظلّ ساريًا طوال مدة المشروع.
  • يُرجى العِلم أنّ هناك قيمة ثالثة، وهي رقم المشروع الذي تستخدمه بعض واجهات برمجة التطبيقات. اطّلِع على مزيد من المعلومات عن كلّ من هذه القيم الثلاث في المستندات.
  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام موارد/واجهات برمجة تطبيقات Cloud. من المفترض ألا تتطلّب المشاركة في هذا الدليل التعليمي البرمجي أي تكلفة، أو تكلفة منخفضة جدًا. لإيقاف الموارد كي لا يتم تحصيل رسوم منك بعد انتهاء هذا الدليل التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع بأكمله. المستخدمون الجدد في Google Cloud مؤهّلون للاستفادة من برنامج الفترة التجريبية المجانية التي تقدّم رصيدًا بقيمة 300 دولار أمريكي.

بدء Cloud Shell

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

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

55efc1aaa7a4d3ad.png

من المفترض ألا تستغرق عملية توفير البيئة والاتصال بها سوى بضع لحظات. عند الانتهاء، من المفترض أن يظهر لك ما يلي:

7ffe5cbb04455448.png

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

3- قبل البدء

في Cloud Shell، نفِّذ الأمر التالي لتفعيل الخدمات المطلوبة:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  cloudfunctions.googleapis.com \
  eventarc.googleapis.com \
  run.googleapis.com

بعد ذلك، حدِّد منطقتك.

REGION=<YOUR_REGION>

في هذا الدليل التعليمي حول رموز البرامج، ستنشئ حساب خدمة يتضمّن أذونات EventArc المطلوبة ودور "مُشغِّل Cloud Run" لتلقّي حدث من Cloud Storage وتشغيل وظيفة Cloud Run.

أولاً، أنشئ حساب الخدمة.

PROJECT_ID=$(gcloud config get-value core/project)
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')

SERVICE_ACCOUNT="cloud-run-functions"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Cloud Run functions Eventarc service account"

بعد ذلك، امنح دور Eventarc Event Receiver (roles/eventarc.eventReceiver) في المشروع لحساب الخدمة المرتبط بعامل تشغيل Eventarc حتى يتمكّن عامل التشغيل من تلقّي الأحداث من مقدّمي الأحداث.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/eventarc.eventReceiver

بعد ذلك، امنح حساب الخدمة دور "مُشغِّل Cloud Run" حتى يتمكّن من استدعاء الدالة.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/run.invoker

4. إطار عمل Functions لـ ‎ .NET

إطار عمل Functions لـ ‎ .NET هو إطار عمل مفتوح المصدر لوظائف FaaS (Function as a Service) لكتابة وظائف ‎ .NET قابلة للنقل، وهو من تقديم فريق Google Cloud Functions.

يتيح لك إطار عمل Functions Framework كتابة دوال خفيفة الوزن يتم تشغيلها في العديد من البيئات المختلفة، بما في ذلك:

  • دوال Google Cloud Run
  • جهاز التطوير المحلي
  • Cloud Run وCloud Run على GKE
  • البيئات المستندة إلى Knative

في هذا الدليل التعليمي حول الرموز البرمجية، ستستخدم إطار عمل Functions لـ .NET وقوالبه لإنشاء وظائف Cloud Functions ونشرها في C#.

في Cloud Shell، نفِّذ الأمر التالي لتثبيت نماذج Cloud Functions لـ dotnet:

dotnet new install Google.Cloud.Functions.Templates

يؤدي ذلك إلى تثبيت 3 نماذج لـ dotnet. يتوفّر كل نموذج بتنسيق C# وF# وVB (ولكن لن تستخدم سوى C# في هذا التمرين). يمكنك التحقّق من تثبيت النماذج من خلال تنفيذ:

dotnet new list

Templates                                                 Short Name            
-----------------------------------------------------------------------
Google Cloud Functions CloudEvent Function                gcf-event
Google Cloud Functions CloudEvent Function (Untyped)      gcf-untyped-event
Google Cloud Functions HttpFunction                       gcf-http

5- دالة HTTP

ستنشئ ونشر وظيفة HTTP تستجيب لطلبات HTTP.

أنشئ دالة HTTP باستخدام نموذج gcf-http:

mkdir HelloHttp
cd HelloHttp
dotnet new gcf-http

يؤدي ذلك إلى إنشاء مشروع وملف Function.cs يستجيب لطلبات HTTP.

غيِّر الإطار المستهدف إلى net8.0 في ملف .csproj:

<TargetFramework>net8.0</TargetFramework>

لنشر دالة Cloud Run مباشرةً على Cloud Run، نفِّذ الأمر التالي:

gcloud beta run deploy hello-http-function \
    --source . \
    --function HelloHttp.Function \
    --base-image dotnet8 \
    --region $REGION \
    --allow-unauthenticated

إذا كنت تفضّل النشر كخدمة من الجيل الثاني من Cloud Functions، استخدِم الأمر التالي:

gcloud functions deploy hello-http-function \
    --allow-unauthenticated \
    --entry-point HelloHttp.Function \
    --gen2 \
    --region $REGION \
    --runtime dotnet8 \
    --trigger-http

بعد نشر وظيفتك، يمكنك استدعاؤها باستخدام الأمر curl التالي:

SERVICE_URL=$(gcloud run services describe hello-http-function --platform managed --region $REGION --format 'value(status.url)')

curl $SERVICE_URL

6- دالة CloudEvent - مساحة تخزين Google Cloud

ستنشئ ونشر وظيفة CloudEvent تستجيب لأحداث Google Cloud Storage.

أولاً، أنشئ حزمة على Cloud Storage. هذه هي الحزمة التي ستستمع إلى الأحداث منها لاحقًا:

BUCKET_NAME="cloud-functions-bucket-${PROJECT_ID}"
gsutil mb -l us-central1 gs://${BUCKET_NAME}

أنشئ دالة CloudEvent باستخدام نموذج gcf-event:

cd ..
mkdir HelloGcs
cd HelloGcs
dotnet new gcf-event

يؤدي ذلك إلى إنشاء مشروع وملف Function.cs يستجيب لطلبات CloudEvent. ويُحلِّل أيضًا بيانات CloudEvent إلى StorageObjectData.

غيِّر الإطار المستهدف إلى net8.0 في ملف .csproj:

<TargetFramework>net8.0</TargetFramework>

لنشر دالة Cloud Run مباشرةً على Cloud Run، عليك أولاً نشر الدالة ثم إنشاء عامل تشغيل لها.

gcloud beta run deploy hello-gcs-function \
      --source . \
      --function HelloGcs.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated

الآن أنشئ عامل التشغيل لدالة Cloud Run.

BUCKET_REGION=$REGION

gcloud eventarc triggers create hello-gcs-function-trigger \
     --location=$REGION \
     --destination-run-service=hello-gcs-function \
    --destination-run-region=$BUCKET_REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$BUCKET_NAME" \
     --service-account=$SERVICE_ACCOUNT_ADDRESS

إذا كنت تفضّل النشر كجيل ثانٍ من Cloud Functions، يمكنك استخدام الأمر التالي لنشر الدالة باستخدام العلامتَين trigger-event وtrigger-resource:

gcloud functions deploy hello-gcs-function \
    --allow-unauthenticated \
    --entry-point HelloGcs.Function \
    --gen2 \
    --region $REGION \
    --runtime dotnet8 \
    --trigger-event google.storage.object.finalize \
    --trigger-resource ${BUCKET_NAME} \
    --service-account=$SERVICE_ACCOUNT_ADDRESS

بعد بضع دقائق، من المفترض أن تظهر الوظيفة في Cloud Console:

c28654d74bb31420.png

يمكنك بدء الدالة من خلال تحميل ملف إلى حزمة التخزين:

echo "Hello from Storage" > random.txt
gsutil cp random.txt gs://${BUCKET_NAME}

تأكَّد من بدء الدالة من خلال قراءة السجلات:

بالنسبة إلى دالة Cloud Run، يمكنك تنفيذ هذا الأمر:

gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json

بالنسبة إلى الدالة من الجيل الثاني، يمكنك تنفيذ هذا الأمر:

gcloud functions logs read hello-gcs-function \
    --gen2 \
    --region us-central1

7- دالة CloudEvent - Pub/Sub

ستنشئ ونشر وظيفة CloudEvent تستجيب لأحداث Cloud Pub/Sub.

أولاً، أنشئ موضوعًا في Cloud Pub/Sub سيُصدِر الأحداث:

TOPIC_NAME=cloud-functions-topic
gcloud pubsub topics create ${TOPIC_NAME}

أنشئ دالة CloudEvent باستخدام نموذج gcf-event:

cd ..
mkdir HelloPubSub
cd HelloPubSub
dotnet new gcf-event

يؤدي ذلك إلى إنشاء مشروع وملف Function.cs يستجيب لطلبات CloudEvent. ويُحلِّل أيضًا بيانات CloudEvent إلى StorageObjectData تلقائيًا.

غيِّر الإطار المستهدف إلى net8.0 في ملف .csproj:

<TargetFramework>net8.0</TargetFramework>

غيِّر StorageObjectData إلى MessagePublishedData لتحليل رسائل Pub/Sub. غيِّر Google.Events.Protobuf.Cloud.Storage.V1 إلى Google.Events.Protobuf.Cloud.PubSub.V1.

في النهاية، يجب أن تظهر الدالة على النحو التالي:

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using Google.Events.Protobuf.Cloud.PubSub.V1;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace HelloPubSub;

public class Function : ICloudEventFunction<MessagePublishedData>
{
    public Task HandleAsync(CloudEvent cloudEvent, MessagePublishedData data, CancellationToken cancellationToken)
    {
        var nameFromMessage = data.Message?.TextData;
        var name = string.IsNullOrEmpty(nameFromMessage) ? "world" : nameFromMessage;
        Console.WriteLine($"Hello {name}");
        return Task.CompletedTask;
    }
}

لنشر دالة Cloud Run مباشرةً على Cloud Run، عليك أولاً نشر الدالة ثم إنشاء عامل تشغيل لها.

gcloud beta run deploy hello-pubsub-function \
      --source . \
      --function HelloPubSub.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated \
      --service-account=$SERVICE_ACCOUNT_ADDRESS

الآن، أنشئ عامل التشغيل لدالة Cloud Run.

gcloud eventarc triggers create my-pubsub-trigger \
    --location=$REGION \
    --service-account=$SERVICE_ACCOUNT_ADDRESS \
    --destination-run-service=hello-pubsub-function \
    --destination-run-region=$REGION \
    --destination-run-path="/" \
    --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
    --transport-topic=projects/$PROJECT_ID/topics/$TOPIC_NAME

إذا كنت تفضّل النشر كجيل ثانٍ من Cloud Functions، يمكنك استخدام الأمر التالي لنشر الدالة باستخدام العلامة trigger-topic:

gcloud functions deploy hello-pubsub-function \
    --allow-unauthenticated \
    --entry-point HelloPubSub.Function \
    --gen2 \
    --region us-central1 \
    --runtime dotnet8 \
    --trigger-topic ${TOPIC_NAME}

بعد بضع دقائق، من المفترض أن تظهر الوظيفة في Cloud Console:

3443808da7caf3bc.png

يمكنك تنشيط الدالة من خلال نشر رسالة في الموضوع:

gcloud pubsub topics publish ${TOPIC_NAME} --message="World"

تأكَّد من أنّ الدالة قد تم تفعيلها من خلال قراءة السجلات.

بالنسبة إلى دالة Cloud Run، يمكنك تنفيذ هذا الأمر:

gcloud logging read "resource.labels.service_name=hello-pubsub-function AND textPayload: World" --format=json

بالنسبة إلى الدالة من الجيل الثاني، يمكنك تنفيذ هذا الأمر:

gcloud functions logs read hello-pubsub-function \
    --gen2 \
    --region us-central1

8. دالة CloudEvent - غير مُصنَّفة

إذا كنت تختبر CloudEvents ولا يتوفّر لديك حتى الآن نموذج بيانات الحمولة الذي تريد الالتزام به، أو إذا كنت تريد أن تتمكّن وظيفتك من معالجة أي حدث في Cloud، يمكنك استخدام وظيفة CloudEvent غير مُصنَّفة.

أنشئ دالة CloudEvent باستخدام نموذج gcf-untyped-event:

cd ..
mkdir HelloUntyped
cd HelloUntyped
dotnet new gcf-untyped-event

يؤدي ذلك إلى إنشاء مشروع وملف Function.cs يستجيب لطلبات CloudEvent بدون أي محاولة لتحليل بيانات CloudEvent.

غيِّر الإطار المستهدف إلى net8.0 في ملف .csproj:

<TargetFramework>net8.0</TargetFramework>

لنشر دالة Cloud Run مباشرةً على Cloud Run، عليك أولاً نشر الدالة ثم إنشاء عامل تشغيل لها.

gcloud beta run deploy hello-untyped-function \
      --source . \
      --function HelloUntyped.Function \
      --region $REGION \
      --base-image dotnet8 \
      --no-allow-unauthenticated

الآن أنشئ عامل التشغيل لدالة Cloud Run.

BUCKET_REGION=$REGION

gcloud eventarc triggers create hello-untyped-function-trigger \
     --location=$REGION \
     --destination-run-service=hello-untyped-function \
    --destination-run-region=$BUCKET_REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$BUCKET_NAME" \
     --service-account=$SERVICE_ACCOUNT_ADDRESS

إذا كنت تفضّل النشر كجيل ثانٍ من Cloud Functions، يمكنك استخدام الأمر التالي لنشر الدالة باستخدام العلامتَين trigger-event وtrigger-resource:

gcloud functions deploy hello-untyped-function \
    --allow-unauthenticated \
    --entry-point HelloUntyped.Function \
    --gen2 \
    --region us-central1 \
    --runtime dotnet8 \
    --trigger-event google.storage.object.finalize \
    --trigger-resource ${BUCKET_NAME}

سيتم تنشيط الدالة عند تحميل ملف إلى حزمة تخزين.

بعد بضع دقائق، من المفترض أن تظهر الوظيفة في Cloud Console:

afe56530826787c6.png

يمكنك بدء الدالة من خلال تحميل ملف إلى حزمة التخزين:

echo "Hello from Storage" > random.txt
gsutil cp random.txt gs://${BUCKET_NAME}

تأكَّد من أنّ الدالة قد تم تفعيلها من خلال قراءة السجلات.

بالنسبة إلى دالة Cloud Run، يمكنك تنفيذ هذا الأمر:

gcloud logging read "resource.labels.service_name=hello-gcs-function AND textPayload: Name" --format=json

بالنسبة إلى الدالة من الجيل الثاني، يمكنك تنفيذ هذا الأمر:

gcloud functions logs read hello-untyped-function \
    --gen2 \
    --region us-central1

9. تهانينا!

تهانينا على إكمال دورة codelab.

المواضيع التي تناولناها

  • إطار عمل Functions لـ ‎.NET
  • كيفية كتابة دالة HTTP Cloud
  • كيفية كتابة دالة CloudEvent تستجيب لأحداث Cloud Storage
  • كيفية كتابة دالة CloudEvent تستجيب لأحداث Cloud Pub/Sub
  • كيفية كتابة دالة CloudEvent تستجيب لأي نوع من الأحداث