Recently in the forums, some Logic App users were asking how to query the state of their Logic Apps. The scenario were not uncommon in that the expected Logic App process time could not be determined and for legitimate reasons
can take longer than timeouts or users would accept. There is no easy way to do this with existing services to the level of a specific Logic App instance, but it is very easy to do using other Azure services, specifically Azure Functions and Redis Cache. For clarity, this post is not about security or performance or cache design. All things you should consider separately and apply patterns necessary to meet requirements or goals. Note: These Portal steps are current as of February 2018. The first thing to create is an instance of Azure Redis Cache. That takes only three steps in the Portal. 1. Create your instance of Azure Redis Cache. This one is MyCompanyLogicAppStatus. 2. Next, you will need a connection string from the Access Keys section of the newly created cache instance. And that’s all we need to do when creating a basic Redis Cache instance. Next, we create an Azure Function that will be the interface to our Azure Redis Cache. 1. Click Create a resource 2. Then click Serverless Function App 3. Complete the details for your Function. Be sure to correctly set the
Resource Group and Storage. 4. Select Application Settings and add the connection string for your Redis Cache to the Connection strings list. 5. Modify or create project.json to include the reference to StackExchange.Redis. 6. Modify function.json to support the PUT and GET methods. Basically, change POST to PUT. For simplicity, the function will use either PUT or GET with 3 or 2 parameters. This is merely a sample so feel free to use fewer or more parameters in any composition you need. The PUT code will be called by the Logic App to set it’s current state. In this case, we’re going to use a combination key of [LogicApp Name] + [OrderNumber], ProcessOrder+12345 for example, as the cache key with any text as the
value. The GET code will be called by any client interested in the state of it’s process using the key as it’s parameter. Finally, we need a Logic App to to write some state to our status interface. In this case, all we need is a fake order process which sets our status. The Logic App here consists most of calls to our Function to set the status, and a delay. In more detail, we can see that Azure Function Action calls our status function with the details necessary to cache the current status. The Delay Action is merely to allow us to see the changing status over time. Note, once you
select the Function when adding the Action, the function name is no longer displayed. The process is very easy to test with Postman. First, we submit an Order we need to track the status of during processing. Next, we can use the GET method with the LogicAppName and ID to get the current status of our running LogicApp.Table of Contents
Introduction
Redis Cache Instance
Azure Function
{
"frameworks": {
"net46":{
"dependencies": {
"StackExchange.Redis": "1.2.1"
}
"frameworks": {
"net46":{
}
}
}
{
"bindings": [
{
"authLevel": "function",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"put"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
],
"disabled": false
}
using
System.Net;
using
StackExchange.Redis;
public
static
async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
log.Info(
"C# HTTP trigger function processed a request."
);
string
cstring = System.Configuration.ConfigurationManager.ConnectionStrings[
"SampleLogicAppState"
].ConnectionString;
ConnectionMultiplexer LogicAppStatusConnection = ConnectionMultiplexer.Connect(cstring);
System.Net.Http.Headers.HttpRequestHeaders reqHeaders = req.Headers;
string
LogicApp = reqHeaders.Contains(
"LogicApp"
) ? reqHeaders.GetValues(
"LogicApp"
).First() :
null
;
string
ID = reqHeaders.Contains(
"ID"
) ? reqHeaders.GetValues(
"ID"
).First() :
null
;
string
Status = reqHeaders.Contains(
"Status"
) ? reqHeaders.GetValues(
"Status"
).First() :
null
;
string
cacheKey = LogicApp +
"+"
+ ID;
IDatabase LogicAppStatusCache = LogicAppStatusConnection.GetDatabase();
if
(req.Method == HttpMethod.Put)
{
LogicAppStatusCache.StringSet(cacheKey, Status);
 n>
IDatabase LogicAppStatusCache = LogicAppStatusConnection.GetDatabase(;
return
req.CreateResponse(HttpStatusCode.OK, cacheKey);
}
else
if
(req.Method == HttpMethod.Get)
{
string
cacheStatus = (
string
)LogicAppStatusCache.StringGet(cacheKey) ??
"Unknown"
;
return
req.CreateResponse(HttpStatusCode.OK, cacheStatus);
}
else
{
return
req.CreateResponse(HttpStatusCode.MethodNotAllowed);
}
}
Logic App
Testing
{
"OrderNumber"
:
"34567"
,
"OrderDate"
:
"20180211"
,
"OrderItem"
:
"Send me a fun LogicApp Demo!"
}