Azure functions Response Body is missing in Logic Apps - azure

I am processing data from Event Hub. Whenever events are available in event hub series of azure functions are called sequentially to processes the data.
function A is using event data as input --> function B is using output of function A as an input and likewise 2 more functions are there.
Response body is missing in only one function (same, ex.: function B in picture) in some iterations.
Sometimes response body for one of the azure function is missing however response code is 200. I have logged the response body in azure function before returning the response and it(response body) is present in logs.
What can be the reason of not getting the response body.
In the attached image Function B is having this issue.
Update: After adding concurrency control to 1(So that it runs sequentially) issue is resolved however again after removing concurrency control issue is coming. What can be the issue ?

One of the workaround you can follow to resolve the above issue,
Make sure that all of the azure function has been created in the same region that might be the reason for not getting the request body for one function and getting for others.
Would suggest you to create Azure logic app and functions in the same region.
Another workaround is to provide the content type in your event hub to application/json if still having the same the try to set text/plain.
For more information please refer this MICROSOFT DOCUMENTATION| Receive and respond to inbound HTTPS requests in Azure Logic Apps
For the similar issue please refer this MS Q&A| Http Webhook Outputs does not have body content, only headers .

Related

Need help and guidance for accessing operationId in nodejs application

We are using nodejs as my backend application and react native in front end. And azure application insights for logging. In UI side, we are redirecting to Stripe checkout page(external page) for payment and then coming back to our application's confirmation page. Here we are loosing the flow on end-to-end transaction. My requirement is to link pre-stripe and post-stripe operation into one single flow. For this my approach of solving this problem is accessing OPERATIONID and pass it to stripe and receive it back from Stripe and use it in confirmation page so that we will one single flow. I Need help in guiding me to the right documentation/ solution proposals.
I read some articles(eg: How to get Application Insights operation id in javascript?) and figured out that operationId is a uniqueID which gets created out of my application and cant access it in the application. I tried to use below code and got response of that operationID as "ai.operation.id" but seems like this is not the right pattern(value) of operationId.
import { defaultClient } from 'applicationinsights';
const telemetryClient = defaultClient;
// tslint:disable-next-line:no-console
console.log(telemetryClient.context.keys[`operationId`]);
The main function of operationId is to help tracking distributed systems so you can correlate requests. So as given in this documentation in nodejs client, you should set the setDistributedTracingMode to appInsights.DistributedTracingModes.AI_AND_W3C as shown below.
const appInsights = require("applicationinsights");
appInsights
.setup("<your ikey>")
.setDistributedTracingMode(appInsights.DistributedTracingModes.AI_AND_W3C)
.start()
You should be able to get the operation id using the following code snippet.
const AppInsights = require("applicationinsights");
var context = AppInsights.getCorrelationContext();
var oid = context.operation.id;
If it does not solve your problem then, I would suggest you to set telemetry.context.operation.id to be a unique id by yourself and confirm if this is tracked by the Application Insights properly.
Also note that the latest version of the JavaScript SDK (SDK v2) for Application Insights have some changes as given in this document.
Moved context.operation to context.telemetryTrace. Some fields were also changed (operation.id --> telemetryTrace.traceID).
To keep the trace ID unique, where you previously used Util.newId(), now use Util.generateW3CId(). Both ultimately end up being the operation ID.
For more information read this log custom telemetry document.

Azure Build Pipeline - Pause and Enable DefinitionQueueStatus change REST API

We have many dozens of build pipelines and we want to pause and resume (re-enable) build pipelines from a simple webapp interface as we are making config changes frequently. Here is the MS doc explaining this API:
https://learn.microsoft.com/en-us/rest/api/azure/devops/build/builds/update%20build?view=azure-devops-rest-5.0#definitionqueuestatus
From this documentation, it appears I need to hit the REST API and change/toggle the DefinitionQueueStatus -- however, this documentation only shows a sample for a build specific operation, whereas I want to pause then re-enable the entire build pipeline. What is the proper way to make this call?
I'm using fetch - and I've tried many dozen formats in the call - the 'ourorg' and 'ourproject' are correct (we use this call structure for many other calls), but all fails for this call below. I grabbed the 'definitionID' from the URL I can visibly see when in the Azure devops portal on the specific build pipeline page, and I'm using it for the {buildID} as I don't know what else to put there. Any guidance to help here is appreciated - I don't need to use fetch btw - any working sample will help here:
fetch(https://dev.azure.com/our_org/our_projectname/_apis/build/builds/definitionId=1593?retry=true&api-version=5.0 {
method: 'PATCH ',
credentials: 'same-origin',
body: 'DefinitionQueueStatus: "Enabled"'
}).then(function(response) {
console.log(response);
})
It seems that the body is incorrect in your post. Here is sample about how to use POSTMAN to access Azure DevOps Services REST APIs.
Generate the PAT, and then record the token, it is important to use to authorization, please see this document.
Create a new request in POSTMAN, it is recommended to put the request in a collection for Azure DevOps Services REST API;
Select the authorization as Basic Auth, you can input the username as any value, and the password as the token which is generated in step1.
Basic Auth
Set the REST API which you want to use,and select the request method type(GET,POST,FETCH ....), here you use https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}?api-version=5.0.
In the Body tab, you can set the request body as raw in json format, and input the value as following:
{
"buildNumber":"#20190607.2",
"buildNumberRevision":1,
"definition":
{
"id":1,
"createdDate":null,
"queueStatus":"paused"
}
}
Everthing is ready now, you can send the request, if sccuess, you will get the response from the REST API.
In your post, the body content is incorrect, the Request Body should meet the format in the REST API document. The DefinitionQueueStatus is a type in definitions. In addition, if you send the request with parameter retry, you will get the message The request body must be empty when the retry parameter is specified..

Error handling in Azure function when used with SendGrid as output binding

I have a C# Azure function with output binding to SendGrid.
This Azure Function gets triggered when a message arrives in a ServiceBus topic. I operate on message and finally returns SendGridMessage. Hereon, SendGrid is responsible for sending out the actual email.
But in this whole scenario, Azure function does not get to know if the email is delivered or failed. Is there any way or hook available which can give me the aforementioned details ?
Any links, examples are appreciated.
Thanks
I don't think there is a way using the Sendgrid binding, as all the sending logic is abstracted away. If you need that, however, it's not much more complicated to instantiate your own Sendgrid client inside your Function:
using SendGrid;
using SendGrid.Helpers.Mail;
static SendGridClient _sendGridClient = new SendGridClient(ConfigurationManager.AppSettings["SendgridApiKey"]);
var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent);
var result = await _sendGridClient.SendEmailAsync(msg);
log.LogDebug($"SendGrid result={result.Body}");

How to receive/access headers of the POST request and 'User Properties' from Data Factory task in Azure Function app

I'm still new to Azure, so please bear with me if this is a newbie question.
I created a task in Azure Data Factory that will invoke a Http-triggered Python function (Consumption plan). The settings and user properties of that task is as shown below:
and here
The function itself is as shown below:
Q1: I'd like to know how to read/access the headers of the POST request in the Python function ('run.py' in the screenshot above). For now, I could only access the body of the HTTP request by using os.environ['req'].
Q2: I'd also like to know if it's possible to access 'User Properties' in the 'run.py' assuming that I run the task in the Data Factory (the first and second screenshot). If so, how would I do that.
The existing resources (e.g., 1 and 2) that I could find online don't tell me yet. Any advice/tip would be greatly appreciated. Thank you in advance!
I finally figured it out and am sharing what I found below so that it helps everyone out there wondering the same thing as i did.
This is the code I wrote in Python Function App to access the body and the request headers.
import os
import json
# This is how I'm currently reading the **body of the POST request**
postreqdata = json.loads(open(os.environ['req']).read())
# This is how we should read **a header of the POST request**;
# here 'excelSourcePath' is one of the header names.
postreqdata['header1'] = os.environ['REQ_HEADERS_EXCELSOURCEPATH']
# 'User Properties' is just for monitoring purpose
# https://social.msdn.microsoft.com/Forums/en-US/8692cd00-307b-4204-a547-bed2030cb762/adfv2-user-property-setting?forum=AzureDataFactory
response = open(os.environ['res'], 'w')
response.write(json.dumps({'This is what I see from POST request now':postreqdata}))
response.close()
Hope this is helpful.

azure method blows up if the records does not exist

I am using this method from the azure mobile services tutorial:
await todoTable.LookupAsync(id). I have 2 rows in a table of id 1,2.
If i do await todoTable.LookupAsync(1), it works and return the record. If i do
await todoTable.LookupAsync(8) to see how it's going to handle null, it just blows up with Not Found exception.
Thanks for help on this.
NULL would mean there is a record for id = 8, but its value is `NULL'. But in your case you do not have a record. Which is different.
What you observe is what you should observe if you do not have a record.
And this is a standard for REST based HTTP services. If record is not there, you get an HTTP 404 from the service.
Azure mobile services is nothing more than a combination of Web API and a wrapping (plumbing) code for your application. And every Web API call to a non-existent record would result into an HTTP 404 error.
And as already said in the comments, you should wrap your code around try - catch blocks and inspect the exception.
In .NET 4.5/4.6 there is new HttpClient type along with HttpResponseMessage and HttpRequestMessatge. The former has EnsureSuccessStatusCode() method. Which, if called will trigger exception.
In the older versions of the Framework there WebClient class, which would throw an exception if the HTTP status code is not 200.
So, again, at the end - you observe absolutely normal behavoir. Just have to read a little more about HTTP REST services, HTTP VERBS and HTTP Status Codes. Then also understand how the particular framework you use (.NET) handles the HTTP Status Codes.

Resources