Question

Tim Cochran on Mon, 11 Sep 2017 19:51:22


I have a simple Azure Function app that triggers on a Event Hub message and writes the message to a SQL Azure database.  This works great.

I added the Twilio output binding (experimental) and I am successfully getting SMS messages for each event.  What I was wondering is, can you make the output binding conditional?  In other words, say I have several event types coming in on the Event Hub.  I want all events written to the database, but only certain event types to trigger the SMS message.  Right now with the standard output binding, all message flow through and I get a SMS message for each event.  I wasn't sure if I can only send some of the messages to the output binding (Twilio).

I know I can create another queue and then send only those events I want to trigger an SMS message to that queue (with a separate function in the pipeline), but was trying to keep it simple with just a single function.

Thanks,

Tim


Sponsored



Replies

xinunix on Wed, 27 Sep 2017 18:24:45


I had this same question and figured out that it can be done as long as you choose the right Binding definition to handle null values properly.  I ran across this document which specifies how each parameter type for the bindings responds to null values.

Azure Web Jobs SDK Quick Reference

We had a similar scenario with an Azure Function that needed to conditionally output to an Azure Queue (service bus queue) or an Azure Event Hub.  The key is that in all cases before the function returns you must assign the out parameters that represent the output bindings a value.  We used the "out string" parameter b/c it will passively accept null and not send a message to that adapter.  So in the conditions of the if statement we set the value of one of the two output bindings to the outbound message and we set the other one to null.

public static HttpResponseMessage Run(HttpRequestMessage req, out string outputEventHubMsg, out string outputQueueMsg, TraceWriter log)
{

   if(you have to return for some reason and not forward any result)
   {
      outputEventHubMsg = null;
      outputQueueMsg = null;
   }

   if(condition A is true) 
   {
      outputEventHubMsg = serializedString;
      outputQueueMsg = null;
   }
   else 
   {
      outputQueueMsg = null;
      outputEventHubMsg = serializedString;
   }
}

Hope that helps!

Mike Stall - MSFT on Wed, 27 Sep 2017 20:08:56


You can also bind to ICollector<T> and IAsyncCollector<T>.  These have an Add() method on them which means you can emit zero or multiple messages. 

The benefit of this over 'out parameters' is:
1. you can emit multiple messages by calling Add() multiple times.
2. you can explicitly flush. 
3. you can use in Async methods (whereas C# does not allow out parameters to be used in async methods). 

xinunix on Thu, 28 Sep 2017 18:27:04


Awesome, an even better solution we will be refactoring to use IAsyncCollector<T> now, much cleaner and we would prefer for the method to be Async.

Thanks!