ربط إخراج شبكة أحداث Azure لـ Azure Functions

استخدم ربط إخراج "شبكة الأحداث" لكتابة الأحداث إلى موضوع مخصص. يجب أن يكون لديك مفتاح اختصار صالح للموضوع المخصص. لا يدعم ربط إخراج Event Grid الرموز المميزة لتوقيع الوصول المشترك (SAS).

للحصول على معلومات حول تفاصيل الإعداد والتكوين، راجع كيفية العمل مع مشغلات شبكة الأحداث والروابط في Azure Functions.

هام

تستخدم هذه المقالة علامات التبويب لدعم إصدارات متعددة من نموذج البرمجة Node.js. يتوفر نموذج v4 بشكل عام وتم تصميمه للحصول على تجربة أكثر مرونة وبديهية لمطوري JavaScript وTypeScript. لمزيد من التفاصيل حول كيفية عمل نموذج v4، راجع دليل مطور Azure Functions Node.js. لمعرفة المزيد حول الاختلافات بين v3 وv4، راجع دليل الترحيل.

تدعم Azure Functions نموذجي برمجة ل Python. تعتمد الطريقة التي تحدد بها روابطك على نموذج البرمجة الذي اخترته.

يتيح لك نموذج برمجة Python v2 تحديد الروابط باستخدام المحسنات مباشرة في التعليمات البرمجية لدالة Python. لمزيد من المعلومات، راجع دليل مطور Python.

تدعم هذه المقالة كلا نموذجي البرمجة.

هام

ربط إخراج شبكة الأحداث متوفر فقط لـ Functions 2.x وأعلى.

مثال

يعتمد نوع معلمة الإخراج المستخدمة مع ربط إخراج شبكة الأحداث على إصدار وقت تشغيل الوظائف وإصدار ملحق الربط ونمط الدالة C#. يمكن إنشاء الدالة C# باستخدام أحد أوضاع C# التالية:

يوضح المثال التالي كيفية استخدام النوع المخصص في كل من المشغل وربط إخراج شبكة الأحداث:

using System;
using System.Collections.Generic;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace SampleApp
{
    public static class EventGridFunction
    {
        [Function(nameof(EventGridFunction))]
        [EventGridOutput(TopicEndpointUri = "MyEventGridTopicUriSetting", TopicKeySetting = "MyEventGridTopicKeySetting")]
        public static MyEventType Run([EventGridTrigger] MyEventType input, FunctionContext context)
        {
            var logger = context.GetLogger(nameof(EventGridFunction));

            logger.LogInformation(input.Data.ToString());

            var outputEvent = new MyEventType()
            {
                Id = "unique-id",
                Subject = "abc-subject",
                Data = new Dictionary<string, object>
                {
                    { "myKey", "myValue" }
                }
            };

            return outputEvent;
        }
    }

    public class MyEventType
    {
        public string Id { get; set; }

        public string Topic { get; set; }

        public string Subject { get; set; }

        public string EventType { get; set; }

        public DateTime EventTime { get; set; }

        public IDictionary<string, object> Data { get; set; }
    }
}

يظهر المثال التالي دالة Java التي تكتب رسالة إلى موضوع مخصص لشبكة الأحداث. تستخدم الدالة أسلوب setValue للربط لإخراج سلسلة.

public class Function {
    @FunctionName("EventGridTriggerTest")
    public void run(@EventGridTrigger(name = "event") String content,
            @EventGridOutput(name = "outputEvent", topicEndpointUri = "MyEventGridTopicUriSetting", topicKeySetting = "MyEventGridTopicKeySetting") OutputBinding<String> outputEvent,
            final ExecutionContext context) {
        context.getLogger().info("Java EventGrid trigger processed a request." + content);
        final String eventGridOutputDocument = "{\"id\": \"1807\", \"eventType\": \"recordInserted\", \"subject\": \"myapp/cars/java\", \"eventTime\":\"2017-08-10T21:03:07+00:00\", \"data\": {\"make\": \"Ducati\",\"model\": \"Monster\"}, \"dataVersion\": \"1.0\"}";
        outputEvent.setValue(eventGridOutputDocument);
    }
}

يمكنك أيضا استخدام فئة POJO لإرسال رسائل Event Grid.

public class Function {
    @FunctionName("EventGridTriggerTest")
    public void run(@EventGridTrigger(name = "event") String content,
            @EventGridOutput(name = "outputEvent", topicEndpointUri = "MyEventGridTopicUriSetting", topicKeySetting = "MyEventGridTopicKeySetting") OutputBinding<EventGridEvent> outputEvent,
            final ExecutionContext context) {
        context.getLogger().info("Java EventGrid trigger processed a request." + content);

        final EventGridEvent eventGridOutputDocument = new EventGridEvent();
        eventGridOutputDocument.setId("1807");
        eventGridOutputDocument.setEventType("recordInserted");
        eventGridOutputDocument.setEventTime("2017-08-10T21:03:07+00:00");
        eventGridOutputDocument.setDataVersion("1.0");
        eventGridOutputDocument.setSubject("myapp/cars/java");
        eventGridOutputDocument.setData("{\"make\": \"Ducati\",\"model\":\"monster\"");

        outputEvent.setValue(eventGridOutputDocument);
    }
}

class EventGridEvent {
    private String id;
    private String eventType;
    private String subject;
    private String eventTime;
    private String dataVersion;
    private String data;

    public String getId() {
        return id;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getDataVersion() {
        return dataVersion;
    }

    public void setDataVersion(String dataVersion) {
        this.dataVersion = dataVersion;
    }

    public String getEventTime() {
        return eventTime;
    }

    public void setEventTime(String eventTime) {
        this.eventTime = eventTime;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getEventType() {
        return eventType;
    }

    public void setEventType(String eventType) {
        this.eventType = eventType;
    }

    public void setId(String id) {
        this.id = id;
    }  
}

يوضح المثال التالي دالة TypeScript التي تم تشغيلها من خلال المؤقت والتي تقوم إخراج حدث واحد:

import { app, EventGridPartialEvent, InvocationContext, output, Timer } from '@azure/functions';

export async function timerTrigger1(myTimer: Timer, context: InvocationContext): Promise<EventGridPartialEvent> {
    const timeStamp = new Date().toISOString();
    return {
        id: 'message-id',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Henry',
        },
        eventTime: timeStamp,
    };
}

app.timer('timerTrigger1', {
    schedule: '0 */5 * * * *',
    return: output.eventGrid({
        topicEndpointUri: 'MyEventGridTopicUriSetting',
        topicKeySetting: 'MyEventGridTopicKeySetting',
    }),
    handler: timerTrigger1,
});

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

const timeStamp = new Date().toISOString();
return [
    {
        id: 'message-id',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Henry',
        },
        eventTime: timeStamp,
    },
    {
        id: 'message-id-2',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Doe',
        },
        eventTime: timeStamp,
    },
];

يوضح المثال التالي دالة JavaScript التي تم تشغيلها من خلال المؤقت والتي تقوم إخراج حدث واحد:

const { app, output } = require('@azure/functions');

const eventGridOutput = output.eventGrid({
    topicEndpointUri: 'MyEventGridTopicUriSetting',
    topicKeySetting: 'MyEventGridTopicKeySetting',
});

app.timer('timerTrigger1', {
    schedule: '0 */5 * * * *',
    return: eventGridOutput,
    handler: (myTimer, context) => {
        const timeStamp = new Date().toISOString();
        return {
            id: 'message-id',
            subject: 'subject-name',
            dataVersion: '1.0',
            eventType: 'event-type',
            data: {
                name: 'John Henry',
            },
            eventTime: timeStamp,
        };
    },
});

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

const timeStamp = new Date().toISOString();
return [
    {
        id: 'message-id',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Henry',
        },
        eventTime: timeStamp,
    },
    {
        id: 'message-id-2',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Doe',
        },
        eventTime: timeStamp,
    },
];

يوضح المثال التالي كيفية تكوين دالة لإخراج رسالة حدث شبكة الأحداث. القسم حيثما تم تعيين type إلى eventGrid يقوم بتكوين القيم المطلوبة لتأسيس ربط إخراج شبكة الأحداث.

{
  "bindings": [
    {
      "type": "eventGrid",
      "name": "outputEvent",
      "topicEndpointUri": "MyEventGridTopicUriSetting",
      "topicKeySetting": "MyEventGridTopicKeySetting",
      "direction": "out"
    },
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]
}

في الدالة لديك، استخدم Push-OutputBinding لإرسال حدث إلى موضوع مخصص من خلال ربط إخراج "شبكة الأحداث".

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$message = $Request.Query.Message

Push-OutputBinding -Name outputEvent -Value  @{
    id = "1"
    eventType = "testEvent"
    subject = "testapp/testPublish"
    eventTime = "2020-08-27T21:03:07+00:00"
    data = @{
        Message = $message
    }
    dataVersion = "1.0"
}

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = 200
    Body = "OK"
})

يوضح المثال التالي ربط المشغل ودالة Python التي تستخدم الربط. ثم يرسل حدثًا إلى الموضوع المخصص، كما هو محدد بواسطة topicEndpointUri. يعتمد المثال على ما إذا كنت تستخدم نموذج برمجة v1 أو v2 Python.

إليك الدالة في ملف function_app.py:

import logging
import azure.functions as func
import datetime

app = func.FunctionApp()

@app.function_name(name="eventgrid_output")
@app.event_grid_trigger(arg_name="eventGridEvent")
@app.event_grid_output(
    arg_name="outputEvent",
    topic_endpoint_uri="MyEventGridTopicUriSetting",
    topic_key_setting="MyEventGridTopicKeySetting")
def eventgrid_output(eventGridEvent: func.EventGridEvent, 
         outputEvent: func.Out[func.EventGridOutputEvent]) -> None:

    logging.log("eventGridEvent: ", eventGridEvent)

    outputEvent.set(
        func.EventGridOutputEvent(
            id="test-id",
            data={"tag1": "value1", "tag2": "value2"},
            subject="test-subject",
            event_type="test-event-1",
            event_time=datetime.datetime.utcnow(),
            data_version="1.0"))

السمات

تستخدم كل من مكتبات المعالجة والعامل المعزول C# السمة لتكوين الربط. يستخدم البرنامج النصي C# بدلا من ذلك ملف تكوين function.json كما هو موضح في دليل البرمجة النصية C#‎.

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

يوضح الجدول التالي معلمات EventGridOutputAttribute.

المعلمة ‏‏الوصف‬
TopicEndpointUri اسم إعداد تطبيق يحتوي على عنوان URI للموضوع المخصص، مثل MyTopicEndpointUri.
TopicKeySetting اسم إعداد تطبيق يحتوي على مفتاح اختصار للموضوع المخصص.
الاتصال* قيمة البادئة الشائعة للإعداد الذي يحتوي على URI لنقطة نهاية الموضوع. لمزيد من المعلومات حول تنسيق تسمية إعداد التطبيق هذا، راجع المصادقة المستندة إلى الهوية.

تعليقات توضيحية

بالنسبة لفئات Java، استخدم السمة EventGridAttribute.

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

public class Function {
    @FunctionName("EventGridTriggerTest")
    public void run(@EventGridTrigger(name = "event") String content,
            @EventGridOutput(name = "outputEvent", topicEndpointUri = "MyEventGridTopicUriSetting", topicKeySetting = "MyEventGridTopicKeySetting") OutputBinding<String> outputEvent, final ExecutionContext context) {
            ...
    }
}

التكوين

يوضح الجدول التالي الخصائص التي يمكنك تعيينها على الكائن الذي options تم تمريره output.eventGrid() إلى الأسلوب .

الخاصية ‏‏الوصف
topicEndpointUri اسم إعداد تطبيق يحتوي على عنوان URI للموضوع المخصص، مثل MyTopicEndpointUri.
topicKeySetting اسم إعداد تطبيق يحتوي على مفتاح اختصار للموضوع المخصص.
الاتصال* قيمة البادئة الشائعة للإعداد الذي يحتوي على URI لنقطة نهاية الموضوع. عند تعيين الخاصية connection ، topicEndpointUri يجب عدم تعيين الخاصيتين و topicKeySetting . لمزيد من المعلومات حول تنسيق تسمية إعداد التطبيق هذا، راجع المصادقة المستندة إلى الهوية.

التكوين

يشرح الجدول الآتي خصائص تكوين ربط البيانات التي عليك تعيينها في ملف function.json.

خاصية function.json ‏‏الوصف
النوع يجب تعيينه إلى eventGrid.
الاتجاه يجب تعيينه إلى out. يتم تعيين هذه المعلمة تلقائيًا عند إنشاء الربط في مدخل Azure.
الاسم اسم المتغير المستخدم في التعليمات البرمجية للدالة التي تمثل الحدث.
topicEndpointUri اسم إعداد تطبيق يحتوي على عنوان URI للموضوع المخصص، مثل MyTopicEndpointUri.
topicKeySetting اسم إعداد تطبيق يحتوي على مفتاح اختصار للموضوع المخصص.
الاتصال* قيمة البادئة الشائعة للإعداد الذي يحتوي على URI لنقطة نهاية الموضوع. لمزيد من المعلومات حول تنسيق تسمية إعداد التطبيق هذا، راجع المصادقة المستندة إلى الهوية.

*يتطلب دعم الاتصالات المستندة إلى الهوية الإصدار 3.3.x أو أعلى من الملحق.

عندما تقوم بالتطوير محليًا، أضف إعدادات التطبيق في ملف local.settings.json في المجموعة Values.

هام

تأكد من تعيين قيمة TopicEndpointUri إلى اسم إعداد تطبيق يحتوي على URI للموضوع المخصص. لا تقم بتحديد عنوان URI للموضوع المخصص مباشرة في هذه الخاصية. وينطبق الشيء نفسه عند استخدام Connection.

راجع قسم Example للحصول على أمثلة كاملة.

الاستخدام

يعتمد نوع المعلمة الذي يدعمه ربط مخرجات شبكة الأحداث على إصدار وقت تشغيل الدوال وإصدار حزمة الامتداد ونمط C# المستخدمة.

عندما تريد أن تكتب الدالة حدثا واحدا، يمكن ربط إخراج شبكة الأحداث بالأنواع التالية:

النوع ‏‏الوصف
string الحدث كسلسلة.
byte[] وحدات البايت لرسالة الحدث.
‏‏أنواع قابلة للتسلسل إلى JSON كائن يمثل حدث JSON. تحاول الدالات تسلسل نوع كائن CLR (POCO) قديم عادي في بيانات JSON.

عندما تريد أن تكتب الدالة أحداثا متعددة، يمكن ربط إخراج شبكة الأحداث بالأنواع التالية:

النوع ‏‏الوصف
T[] حيث T هو أحد أنواع الأحداث الفردية صفيف يحتوي على أحداث متعددة. يمثل كل إدخال حدثا واحدا.

بالنسبة لسيناريوهات الإخراج الأخرى، قم بإنشاء واستخدام أنواع من Azure.Messaging.EventGrid مباشرة.

إرسال رسائل فردية عن طريق استدعاء معلمة أسلوب مثل out EventGridOutput paramName، وكتابة رسائل متعددة باستخدام ICollector<EventGridOutput>.

الوصول إلى رسالة الإخراج عن طريق إرجاع القيمة مباشرة أو باستخدام context.extraOutputs.set().

الوصول إلى حدث الإخراج باستخدام أمر cmdlet Push-OutputBinding لإرسال حدث إلى ربط إخراج "شبكة الأحداث".

هناك خياران لإخراج رسالة "شبكة الأحداث" من دالة:

  • القيمة المرجعة: تعيين الخاصية name في function.json إلى $return. مع هذا التكوين، تستمر قيمة الإرجاع الخاصة بالدالة كرسالة شبكة أحداث.
  • أمر حتمي: تمرير قيمة إلى الأسلوب المُحدد الخاص بالمعلمة التي أُعلن عنها باعتبارها نوع Out. القيمة التي تم تمريرها إلى set تستمر على أنها رسالة شبكة أحداث.

الاتصالات

هناك طريقتان للمصادقة على موضوع Event Grid عند استخدام ربط إخراج Event Grid:

أسلوب المصادقة ‏‏الوصف
استخدام مفتاح موضوع قم بتعيين الخاصيتين TopicEndpointUri و TopicKeySetting ، كما هو موضح في استخدام مفتاح موضوع.
استخدام هوية قم بتعيين الخاصية Connection إلى اسم بادئة مشتركة لإعدادات تطبيق متعددة، مع تحديد المصادقة المستندة إلى الهوية معا. يتم اعتماد هذا الأسلوب عند استخدام الإصدار 3.3.x أو أعلى من الملحق.

استخدام مفتاح موضوع

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

  1. اتبع الخطوات الواردة في الحصول على مفاتيح الوصول للحصول على مفتاح الموضوع لموضوع شبكة الأحداث.

  2. في إعدادات التطبيق، قم بإنشاء إعداد يحدد قيمة مفتاح الموضوع. استخدم اسم هذا الإعداد لخاصية TopicKeySetting الربط.

  3. في إعدادات التطبيق الخاص بك، قم بإنشاء إعداد يحدد نقطة نهاية الموضوع. استخدم اسم هذا الإعداد لخاصية TopicEndpointUri الربط.

المصادقة المستندة إلى الهوية

عند استخدام الإصدار 3.3.x أو أعلى من الملحق، يمكنك الاتصال بموضوع Event Grid باستخدام هوية Microsoft Entra لتجنب الحاجة إلى الحصول على مفاتيح الموضوع والعمل معها.

تحتاج إلى إنشاء إعداد تطبيق يقوم بإرجاع URI لنقطة نهاية الموضوع. يجب أن يجمع اسم الإعداد بين بادئة شائعة فريدة (على سبيل المثال، myawesometopic) مع القيمة __topicEndpointUri. بعد ذلك، يجب استخدام هذه البادئة الشائعة (في هذه الحالة، myawesometopic) عند تعريف الخاصية Connection في الربط.

في هذا الوضع، يتطلب الملحق الخصائص التالية:

الخاصية قالب متغير البيئة ‏‏الوصف مثال للقيمة
عنوان URI لنقطة نهاية الموضوع <CONNECTION_NAME_PREFIX>__topicEndpointUri نقطة نهاية الموضوع. https://<topic-name>.centralus-1.eventgrid.azure.net/api/events

يمكن استخدام المزيد من الخصائص لتخصيص الاتصال. راجع الخصائص الشائعة للاتصالات المعتمدة على الهوية.

إشعار

عند استخدام تكوين تطبيق Azure أو Key Vault لتوفير إعدادات للاتصالات المدارة المستندة إلى الهوية، يجب أن تستخدم أسماء الإعدادات فاصل مفاتيح صالحا مثل : أو / بدلا من __ لضمان حل الأسماء بشكل صحيح.

على سبيل المثال، <CONNECTION_NAME_PREFIX>:topicEndpointUri

عند استضافتها في خدمة Azure Functions، تستخدم الاتصالات المستندة إلى الهوية هوية مدارة. تستخدم الهوية المعينة من قبل النظام بشكل افتراضي على الرغم من إمكانية تحديد هوية معينة من قبل المستخدم مع خصائص credential و clientID. لاحظ أن تكوين هوية معينة من المستخدم باستخدام معرف مورد غير معتمد. عند التشغيل في سياقات أخرى، مثل التنمية المحلية، يتم استخدام هوية المطور الخاصة بك بدلًا من ذلك، على الرغم من أنه يمكن تخصيصها. راجع التطوير المحلي من خلال الاتصالات القائمة على الهوية.

منح الإذن للهوية

مهما كانت الهوية المستخدمة يجب أن يكون لديك أذونات لتنفيذ الإجراءات المقصودة. بالنسبة لمعظم خدمات Azure، يعني هذا أنك بحاجة إلى تعيين دور في Azure RBAC، باستخدام أدوار مضمنة أو مخصصة توفر هذه الأذونات.

هام

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

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

نوع الربط مثال على الأدوار المضمنة
ربط بيانات الإخراج EventGrid Contributor، مرسل بيانات EventGrid

الخطوات التالية