Azure Durable Function #2–Patterns : Function Chaining


let’s discuss some common implementations of Azure Durable Function. If you want to learn what Azure Durable functions are please read my Previous Article

Azure Durable Functions #1 Introduction


"Function chaining refers to the pattern of executing a sequence of functions in a particular order. Often the output of one function needs to be applied to the input of another function”

Problem to solve :
You have a workflow with 3 steps you need to pass output of the previous step to the next steps.

Lets solve this with Azure Durable Functions.

Step 1: Create a HttpTrigger Function
This will be the starter function which will call the orchestrator function.

Step 2: Add Durable Function Nuget in to your Project
Microsoft.Azure.WebJobs.Extensions.DurableTask

Step 3: Add a new Function with Trigger Type – Durable Function Orchestrator



Once you add the function you would see it comes with set of code for you.

 [FunctionName("Orchestrator")]
        public static async Task<List<string>> RunOrchestrator(
            [OrchestrationTrigger] DurableOrchestrationContext context)
        {
          }


Parameter  DurableOrchestrationContext context is where durable function context is stored and maintained. Keep the code for Orchestrator and remove the other parts.

Step 4: Add a new Function class named “OrderCalculationActivity”.
Add the following code in to it.



using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using System;


namespace FanInFanOut
{
  public  class OrderCalculationActivity
    {
        [FunctionName("OrderCalculationActivity")]
        public static double CalCulateOrderAmount([ActivityTrigger] string OrderId, ILogger log)
        {
            log.LogInformation($"Saying hello to {OrderId}.");
            return new Random().NextDouble();
        }
    }
}
This is the first Activity of the workflow. This will take the orderId and will calculate the order amount. Then it will return the order amount to the orchestrator.

Step 5: Add a anther Function class named “InvoiceGenerationActivity”.
Add the following code in to it.


using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

namespace FanInFanOut
{
   public class InvoiceGenerationActivity
    {
        [FunctionName("InvoiceGenerationActivity")]
        public static bool CalCulateOrderAmount([ActivityTrigger] double orderAmount, ILogger log)
        {
            log.LogInformation($"Invoice Generated with amount {orderAmount}.");
            return true;
        }
    }
}
This is the second activity in the workflow. This will take the order amount and will generate the invoice and will return the status.


Step 6: Lets define the workflow in the orchestrator function.


using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;

namespace FanInFanOut
{
    public static class Orchestrator
    {
        [FunctionName("Orchestrator")]
        public static async Task<string> RunOrchestrator(
            [OrchestrationTrigger] DurableOrchestrationContext context)
        {
            var outputs = new List<string>();

            var orderAmount = await context.CallActivityAsync<double>("OrderCalculationActivity", "112");
            var invoice = await context.CallActivityAsync<bool>("InvoiceGenerationActivity", orderAmount);

            return "Invoice Generated Sucessfully";
        }
    }
}

As you may see it calls the first activity await till it finishes and then pass the result to the second activity. So you can we can clearly see the workflow in the code itself.

Step 7: Calling the orchestrator from the Starter

using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using System.Net.Http;

namespace FanInFanOut
{
    public static class Starter
    {
        [FunctionName("Starter")]
        public static async Task<HttpResponseMessage> HttpStart(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")]HttpRequestMessage req,
            [OrchestrationClient]DurableOrchestrationClient starter,
            ILogger log)
        { 
            // Function input comes from the request content.
            string instanceId = await starter.StartNewAsync("Orchestrator", null);

            log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

            return starter.CreateCheckStatusResponse(req, instanceId);
        }
    }
}

To call the Orchestrator you need to add the DurableOrchestrationClient parameter to your function.
In the last line you can see I have added a line to create a check status response. What this will do is when you call the function it will give you following URL endpoint.




If you click on “statusQueryGetUri” it will show you the status of the workflow.

Following above pattern you can simplify your workflows using azure functions.

You can download the code here.


Happy Coding !!!

Comments

Popular posts from this blog

Responsive Web Design

Contract First Development in WCF 4.5

Affine Cipher in C#