Как использовать входную привязку базы данных DocumentDB с привязкой триггера служебной шины и BrokeredMessage в Функциях Microsoft Azure?

Я пишу простую функцию, которая запускается при поступлении нового сообщения в очередь служебной шины. Входными данными для этой функции является документ DocumentDB. Мне нужно получить доступ к значению в документе и ввести его в журнал консоли.

Когда вы создаете привязку триггера очереди служебной шины, она автоматически создается следующим образом:

public static void Run(string myQueueItem, TraceWriter log)
{
    log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
}

Теперь, чтобы получить доступ к правильному документу в моей базе данных, согласно на этой странице можно настроить привязки так, чтобы вы получали идентификатор документа из сообщения очереди:

id поддерживает привязки, подобные {queueTrigger}, который использует строковое значение сообщения очереди в качестве идентификатора документа.

Это означает, что вы можете отправить сообщение в очередь, а затем привязать его к документу следующим образом:

{
    "name": "inputDocument",
    "type": "documentDB",
    "databaseName": "MyDatabase",
    "collectionName": "MyCollection",
    "id" : "{myQueueItem}",//<<<
    "connection": "MyAccount_DOCUMENTDB",     
    "direction": "in"
}

Пока вроде все работает как задумано. Однако, чтобы отправить сообщение в очередь служебной шины, вы должны отправить его как тип BrokeredMessage (ссылка). И когда вы это сделаете, вы больше не сможете получить доступ к сообщению как к строке, что сделает автоматически созданную функцию бесполезной.

С BrokeredMessages можно работать через это:

project.json:

{
    "frameworks": {
        "net46":{
            "dependencies": {
                "WindowsAzure.ServiceBus": "2.7.6"
            }
        }
    }
}

run.csx:

using Microsoft.ServiceBus.Messaging;
....
log.Info($"C# ID: {queueItem.GetBody<string>()})

Но я не смог узнать, как передать {queueItem.GetBody<string>()} в атрибут id привязки входного документа. Поэтому я больше не могу использовать вышеупомянутый метод привязки моего ввода documentdb через "id" : "{myQueueItem}" и, следовательно, не могу читать какие-либо значения из любых документов.

  • Есть ли способ отправить необработанную строку в Bus Queue или BrokeredMessage действительно единственная возможность? (из того, что мне удалось выяснить, необработанная строка невозможна)

  • Если BrokeredMessage действительно единственный способ, возможно ли получить строковое значение из сообщения и использовать его в качестве идентификатора для документа DocumentDB?

  • Если ничего из вышеперечисленного невозможно, не могли бы вы указать мне правильное направление?

Более полное объяснение моей функции:

Приложение периодически отправляет новые документы в базу данных DocumentDB. Вместе с документом (после ожидания завершения вставки) он отправляет сообщение с идентификатором нового документа в очередь служебной шины. Затем триггер подключается к новому документу и проверяет целочисленное значение внутри него. Если значение больше 10, он отправляет уведомление по электронной почте.

Я успешно создал это и протестировал с помощью руководства веб-редактора Run со строковым идентификатором одного из документов в качестве тестового ввода. Однако, когда я попытался использовать его с приложением, которое автоматически отправляет документы и сообщения, я столкнулся с проблемой BrokeredMessage, как описано выше.

Ниже приведен полный код функции работы без BrokeredMessage:

using System;
using System.Net;
using System.Net.Mail;

public static void Run(string queueItem, dynamic inputDocument, TraceWriter log)
{
    log.Info($"C# ID: {queueItem}, Value: {inputDocument.Value}");

    if (inputDocument.Value > 10)
    {
        var fromAddress = new MailAddress("[email protected]", "From ---");
        var toAddress = new MailAddress("[email protected]", "To ---");
        const string fromPassword = "---";
        const string subject = "Notification";
        const string body = "Temperature too high!";

        var smtp = new SmtpClient
        {
            Host = "smtp.gmail.com",
            Port = 587,
            EnableSsl = true,
            DeliveryMethod = SmtpDeliveryMethod.Network,
            UseDefaultCredentials = false,
            Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
        };
        using (var message = new MailMessage(fromAddress, toAddress)
        {
            Subject = subject,
            Body = body
        })
        {
            smtp.Send(message);
        }
    }
}

person David Piskula    schedule 08.12.2016    source источник


Ответы (1)


Вот рабочий пример, показывающий, как получить сообщение ServiceBus как POCO и привязать его к свойствам.

Если вы отправляете сообщение в очередь с правильным типом содержимого application/json, функция десериализуется в POCO за вас, а входная привязка DB документа привязывается к свойству DocumentId и извлекает документ для вас. Чтобы это работало, вам не нужно ничего добавлять в project.json.

Файл function.json:

{
  "bindings": [
    {
      "name": "input",
      "type": "serviceBusTrigger",
      "direction": "in",
      "queueName": "<your-queue.",
      "connection": "<your-connection>",
      "accessRights": "Manage"
    },
    {
      "type": "documentDB",
      "name": "document",
      "databaseName": "<your-db>",
      "collectionName": "<your-collection>",
      "id": "{DocumentId}",
      "connection": "<your-connection>",
      "direction": "in"
    }
  ]
}

Код функции:

using System;
using System.Threading.Tasks;

public class Input
{
    public string DocumentId { get; set; }
    public int Value { get; set; }
}

public static void Run(Input input, dynamic document, TraceWriter log)
{
    log.Info($"Message received (DocumentId: {input.DocumentId}, Value {input.Value})");
    log.Info($"Document read {document.id}");
}

Для функций C #, чтобы использовать параметры привязки (например, параметр {DocumentId}), вход триггера должен быть привязан к объекту POCO, определяющему эти свойства.

Для отправки сообщений электронной почты вы также можете изучить нашу привязку вывода SendGrid. У нас есть полный образец "SendGrid-CSharp", доступный на портале в разделе "Примеры" :)

person mathewc    schedule 08.12.2016