2016-12-08 6 views
2

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

При создании триггера очереди Service Bus привязки, она автоматически создаются следующим образом:

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

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

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

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

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

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

Можно работать с 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}" и, таким образом, не могу прочитать какие-либо значения из каких-либо документов.

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

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

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

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

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

Я успешно создал это и протестировал его через руководство для веб-сайта. Выполнить с идентификатором строки одного из документов в качестве тестового ввода. Однако, когда я пытался использовать его с приложением, которое автоматически отправляет документы и сообщения, я столкнулся с проблемой 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); 
     } 
    } 
} 

ответ

3

Вот рабочий пример, показывающий, как получить сообщение 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», доступный на портале в разделе «Образцы» :)