Building SOAP Listener with Azure Functions - azure

I am using Azure Functions to build some integrations between various systems. I new requirement is to respond to record updates in Salesforce. Some quick research yielded what seems like a good solution from the Salesforce side. Use Outbound messaging which can send SOAP requests on record modifications.
How to create Salesforce application that will send record to external web service when record created/changed(https://salesforce.stackexchange.com/questions/73425/how-to-create-salesforce-application-that-will-send-record-to-external-web-servi)
The challenge now is to be able create a SOAP listener in Azure Function. I have created basic HTTP Triggers for my other listeners. Is there anything "built-in" to Azure Functions that would allow me to easily consume the incoming SOAP request?
Salesforce has the basics for a solution based on a more traditional web service and an ASMX file but I am not sure if or how that can be applied in Azure Functions. (https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_om_outboundmessaging_listener.htm)

That notification is just a SOAP request that is made over HTTP, so really not too different than a regular HTTP trigger request.
Although you could just treat that as a plain request and parse the contents yourself, Azure Functions does expose the great WebHook support we get from ASP.NET WebHooks, and luckily, there is a Salesforce receiver that significantly simplifies this task.
DISCLAIMER: It's worth noting that although the receiver is technically enabled in Azure Functions, there's no official support for it yet, so you won't find a lot of documentation and help will be limited to what you get on SO and Forums. Official support to this and other receivers will hopefully be coming soon, which means documentation, templates and UI support will become available.
To get started, you need the following:
Create a new function, selecting the GenericWebHook - CSharp template (this works for node as well, but I'll focus on C# here.
Follow the steps outlined on the ASP.NET WebHooks integration with Salesforce post in order to create the outbound message. Here you want to use the Function Url given to you by the portal WITHOUT THE CODE QUERY STRING (having the code there wouldn't hurt, but the receiver does not use that information).
IMPORTANT: Get your Salesforce Organization ID, which will be used for authentication and is located under Administer > Company Profile > Company Information > Salesforce.com Organization ID and back in the Azure Functions portal, open the Keys panel, delete your default function key (not host key) and create a new key, named default (this name is important) using the Organization ID value you got from Salesforce.
Go to Integrate
On the integration page, select Advanced Editor on the upper right (as mentioned, there's no official support, so the UI does not expose this. We're putting our explorer hats on and venturing into a more advanced workflow here :) )
Change the webHookType property value to sfsoap and save the configuration. Your function.json config should look like the following:
function.json:
{
"bindings": [
{
"type": "httpTrigger",
"direction": "in",
"webHookType": "sfsoap",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
],
"disabled": false
}
Switch to the Develop tab. We're ready to write our code.
This is where the ASP.NET WebHooks receiver shines! It will parse the notification for you, exposing strong typed objects you can work with. All you need to do is modify the method/function signature you get withe template to use the SalesforceNotifications type, making sure you're referencing the required assembly (Microsoft.AspNet.WebHooks.Receivers.Salesforce, which is made available to you, so no need for package reference) and namespace reference (Microsoft.AspNet.WebHooks).
Here is a full sample of a function that will receive the request and log the Organization ID, Action ID, grab the first notification and log all of its properties:
#r "Microsoft.AspNet.WebHooks.Receivers.Salesforce"
using Microsoft.AspNet.WebHooks;
public static void Run(SalesforceNotifications req, TraceWriter log)
{
log.Info($"Salesforce webhook was triggered!");
log.Info(req.OrganizationId);
log.Info(req.ActionId);
var notification = req.Notifications.First();
foreach (var p in notification.Keys)
{
log.Info($"{p} = {notification[p]}");
}
}
This process will be a lot smoother when the receiver is officially supported, but even with the added steps, this still beats having to parse the SOAP messages yourself :)
I hope this helps!

Related

azure data factory BlobEventsTrigger : set "advanced filter" programatically

I am trying to set "advanced filter" of BlobEventsTrigger programmatically.
They are reset at each deployment. I need only 3 and having 7 of them are causing the job to start twice. It is super annoying to delete them manually after each deployment.
I have tried to add a field "advancedFilters" or "blobType" to the trigger json file without success.
"typeProperties": {
"blobPathBeginsWith": "/bingofile/blobs/",
"blobPathEndsWith": "/_SUCCESS",
"ignoreEmptyBlobs": false,
"scope": "/subscriptions/bingofilesup/resourceGroups/bingofilesup/providers/Microsoft.Storage/storageAccounts/bingofilesup",
"events": [
"Microsoft.Storage.BlobCreated"
]
I've also tried az eventgrid system-topic event-subscription update but this library does not work when it comes to updating advanced filter. It asks an endpoint (which is normally a facultative argument) , and when provided the existing data factory endpoint, it fails reaching it.
I have checked the documentation about this endpoint and it is said to be the webhook endpoint .
Endpoint where EventGrid should deliver events matching this event
subscription. For webhook endpoint type, this should be the
corresponding webhook URL. For other endpoint types, this should be
the Azure resource identifier of the endpoint. It is expected that the
destination endpoint to be already created and available for use
before executing any Event Grid command.
But it does not work .
Deployment failed. Correlation ID:
95e4fab5-163e-48ab-8cb2-b23432516e53. Webhook validation handshake
failed for [webwook end point provided in the topic]. Http POST
request failed with response code Unknown. For troublehooting, visit
https://aka.ms/esvalidation.
Any observation or suggestion would be great, thanks in advance !
According to my test, the endpoint https://pmeastasia.svc.datafactory.azure.com:4443/triggerevent/BlobEventsTrigger/<> is juts a base URL. When the events are sent to data factory or update subscription, azure will generate an endpoint with the base URL to do auth. So if you want to update the subscription with other tools, I think you need to use fildder to catch the request to get the whole endpoint at first.

Calling the azure tenants REST api doesn't provide the expected json data

When calling the latest (version 2020-01-01) azure tenants api (management.azure.com/tenants) I don't see the same properties in the response as I get when using the "Try it" feature on the "Tenants - List" page in the online Azure REST documentation.
The response that I get only contains the "id", "tenantId" and "tenantCategory" properties. So the cool stuff like countryCode, domains, displayName, etc. are missing. I was using an older api version before which only included the "id" and "tenantId" properties so I do see the additional "tenantCategory" property at least.
When calling the 2020-01-01 version of the subscriptions list API in my code I do get all the same properties that I see when I use the "Try it" feature.
Has anyone else experienced this issue or know what could be the cause?
Thanks in advance!
I tried with https://management.azure.com/tenants?api-version=2020-01-01 in Try it, it returned the properties. Try to use 2020-05-01, 2020-06-01 or 2020-07-01 versions. They all worked for me.
When using Postman to call the API:
So it turns out that if you request the token under user context and use that as bearer token in the authorization header of the API call you get all the properties in the response, i.e. the same properties as you see when using the "Try it" feature online. But in my app I'm requesting it under the application context and then the expected behaviour is to only return the "id", "tenantId" and "tenantCategory" properties. So the tenants api is a bit different than the others and it's supposed to be that way.

How to dynamically pass an argument to a function being called by a logic app with ethereum connector in Azure?

I am using Azure blockchain Service and I made a logic app to call a function inside a smart contract whenever a particular trigger occurs.
While creating the logic app it asks me the argument with which I want to call the function.
Now, I do not want to hard code the argument.
It is something like on my website, there are multiple products available, and whichever product the user chooses, the function should be called with the name of the product as the argument.
You have two options here
HTTP triggered function and pass parameters using POST request
Queue triggered function and pass parameters using Azure Storage Queue
In first case you simply create HTTP trigger
Body configured as
{
"type": "object",
"properties": {
"product": {
"type": "string"
}
}
}
This means logic app request expects JSON like this
{
"product" : "abc"
}
This way you can use product from trigger
And use it as parameter for function call using either HTTP action
or Azure Function action
If you want to learn more about logic apps feel free to check my video intro on it https://youtu.be/ZvsOzji_8ow
If you are worried about publicly accessible webhooks for logic apps use Azure Storage Queue with Azure AD authentication or cover logic app with API management like described here https://marczak.io/posts/2019/08/secure-logic-app-with-api-management/

How to receive messages from azure queue subscription using go

I trying to pull messages from azure service bus queue using Go.Queue topic name,subscription name,service name and shared access key value are the credentials.I'm not getting proper sample code for this.Please help me!!
The Go Cloud Development Kit Pub/Sub API is still a work in progress (it's one of our newer APIs). As of 2019-01-30, there is a pull request out for review that adds support, so stay tuned!
from azure.servicebus.control_client
import ServiceBusService
bus_service=ServiceBusService(service_namespace='<namespace>',
shared_access_key_name='<key_name>',
shared_access_key_value='<acess_key>')
topic_name = "<topic_name>"
subscription_name = "<subscription_name>"
message = bus_service.receive_subscription_message(topic_name,
subscription_name, peek_lock=True)

Azure Event Grid to Azure Relay, Hybrid Connection

I'm testing out Azure Event Grid with a Azure Relay, Hybrid Connection handler. It's not working for me.
I can see messages being published to Azure Event Grid. So far so good.
I've set up a subscription to the Event Grid topic and I've configured it to send events to a handler specified as an Azure Relay with a Hybrid Connection endpoint.
Looking at the metrics for the subscription with the Hybrid Connection handler, I see the following telemetri:
Matched Events
Delivery Failed
Expired Events
… but I see no Delivery Succeeded event???
Also, the Hybrid Connection listener (just a simple Console App) connected to the Azure Relay receives nothing. I've tested the listener by sending some test messages directly to the Relay and that works fine.
The logical conclusion, is that the events published to the Event Grid are not being delivered probably to the Relay Hybrid Connection handler. But why? There are not that many parameters, so I not sure what I'm doing wrong. It seems rather straight forward to configure this.
I'm a the point where I'm beginning to believe that the Event Grid / Hybrid Connection scenario is currently not working. It is in preview after all, so that could explain it.
I know that there is not much to go on here, but I was hoping that others might have some experience with this?
The issue still remains. The issues seems to be related to the formating of the json being passed from the Event Grid Subscription to the Hybrid Connect.
Update
I finally had some time to look more carefully into this.
I set up the Event Grid Tester and every time the Event Grid recieves a message I can see this error in the log:
HybridConnection: Message processing failed - Unable to cast object of type 'Newtonsoft.Json.Linq.JValue' to type 'Newtonsoft.Json.Linq.JObject'.
I'm still not able to fix this, as I do not control the message. The message is generated by Azure Logic App and send to the Event Grid using the Event Grid connector. The Event Grid Connector in Azure Logic Apps is in preview, so that might explain the challenges I'm seeing.
I've successfully tested Event Grid subscriber locally using Azure Relay and documented it here. It is based on a sample Microsoft is providing and implemented using WCF variant of client, not the .NET Standard version.
you can simulate an Event Grid message to the HybridConnection url using a http POST request:
POST https://{myNamespace}.servicebus.windows.net/{myHybridConnectionName}
headers:
content-type: application/json
x-ms-version: 2015-07-08
Aeg-Event-Type: Notification
Authorization: SharedAccessSignature sr=xxx&sig=xxxx&se=11111111&skn=xxxxx
body:
{
"id": "123456",
"eventTime": "2018-07-22T13:09:07.5164877Z",
"eventType": "recordInserted",
"dataVersion": "1.0",
"metadataVersion": "1",
"subject": "/myapp/vehicles/motorcycles",
"data": {
"make": "Ducati",
"model": "Monster"
}
}
Note, that the sasToken for authorization header can be copied from the Azure Event Grid Tester log panel, when the HybridConnection has been opened.
the other option is to generate it by the following code:
using Microsoft.Azure.Relay;
// ...
var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider("hybridconnectionPolicyName", "hybridconnectionPrimaryKey");
var token = tokenProvider.GetTokenAsync("https://{myNamespace}.servicebus.windows.net/{myHybridConnectionName}", TimeSpan.FromDays(10)).Result.TokenString;

Resources