Dynamically calling several back-end endpoints from within Azure APIM policy - azure

I'm calling a back-end API from Azure API Management (APIM) and I need to provide the JSON schema for my custom connector in Logic Apps/Flow.
Depending on the content of the response I'm getting, I need to perform additional calls in order to provide an enumeration/drop down.
Consider a response from the back-end API, like this:
{
"member1": {
"prop": "content"
},
"member2": {
"prop": "content",
"datasource": "http://someurl.com/api/member2/content"
},
"member3": {
"prop": "content"
},
"member4": {
"prop": "content"
"datasource": "http://someurl.com/api/memberfour/content"
}
}
I need to perform additional calls to the URLs in the "datasource" members in order to provide additional data, but these are obviously dynamic, depending on the call I'm performing. I'm a bit stuck since I can't seem to perform a send-request policy for a dynamic number of calls and URLs. How would I best approach this?

If I understand the scenario correctly, I don't think you want to use APIM to make the calls to the datasource URLs because then you wouldn't be able to get those results back to logic apps. I think what you are looking for is the x-ms-dynamic-values which is documented here
You can use this extension to describe both the primary operation which will provide your content and some secondary operations that will return the lists used to fill the drop downs for the Logic Apps UI. You will probably need to create additional APIM operations to surface those lists.

Related

Azure Data Catalog Assets are not editable when I register an asset via REST API

I am using the REST API of Azure Data Catalog to register new assets. My users need to be able to add/change tags and description. However, when I register new assets over REST API, add tag buttons and description text field disappear.
I suspect I need to pass a parameter in the json to make the fields editable. In the official documentation I couldn't find anything related.
I have all of the admin rights in all of my users, so I don't think it is an access rights issue.
How can I make the assets editable?
The solution is explained here. By default, the assets that are created by REST API are only editable by their owners. In order to change that behaviour, the following json object should be added to the payload:
{
"roles": [
{
"role": "Contributor",
"members": [
{
"objectId": "00000000-0000-0000-0000-000000000201"
}
]
}
],
//properties start here
//"properties": {
//...
// }
}
if it is still unclear, please check the following sample code.

Is there a way to get user permissions in a specific Azure Devops Project using rest api?

Hi I want to check the permissions of a user in a specific Azure Devops Project. Is there a possible way to get it? As far as I know project level permission is different than organization level permissions. Thanks.
Already test some several rest apis but still I can't have the project level permission.
There is currently no out-of-the-box rest api to get the user's permission in project.
To achieve this demand, you can use this rest api :
https://dev.azure.com/{org}/_apis/Contribution/HierarchyQuery?api-version=5.0-preview.1
Request body:
{
"contributionIds": ["ms.vss-admin-web.org-admin-permissions-pivot-data-provider"],
"dataProviderContext": {
"properties": {
"subjectDescriptor": "msa.ZjE1ZTk0NmMtOTI4OS03Mjg5LTljMGUtMDIwMTdlYmM2Nzhj",
"sourcePage": {
"url": "https://dev.azure.com/xxx/xxxx/_settings/permissions",
"routeId": "ms.vss-admin-web.project-admin-hub-route",
"routeValues": {
"action": "Execute",
"adminPivot": "permissions",
"controller": "ContributedPage",
"project": "XXX",
"serviceHost": "0933e8b2-f504-4b7e-9e9e-xxxxx (xxx)"
}
}
}
}
}
You can track this rest api by press F12 in browser then select Network .Then looking for the record that response body included returned permission. From this record you can get the rest api and request body.
I tested with postman , with this api ,I can successful get user's permission in project. As shown below:

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/

Getting all B2B directories user is member of

Since we have Azure AD's B2B feature in GA, I am curious how to make use of B2B in multi-tenant applications. More specifically, how to get a list of directories which the user is member of? For example, the Azure Portal does this by calling https://portal.azure.com/AzureHubs/api/tenants/List, Microsoft's My Apps calls https://account.activedirectory.windowsazure.com/responsive/multidirectoryinfo to get the information - is there a public endpoint for this?
The use case is to enable B2B cooperation across a multi-tenant application which is provisioned in each user's directory so they have their own instances, but there is no way to centrally pull the information about user's directories.
A simple workaround would be to query all tenants which have the application provisioned for the user's UPN and if found, display it in the list, but imagine if there were hundreds of tenants... I believe that this is quite crucial for app developers who want to leverage the B2B functions in multi-tenant applications.
Update: It seems like there is a way to do this by accessing the Azure Service Management API, however this API and method is undocumented and I suppose that if any issues would occur, Microsoft would say that it is not a supported scenario.
Update 2: I wrote an article about the whole setup, including a sample project of how to make use of this in a scenario, it can be found here https://hajekj.net/2017/07/24/creating-a-multi-tenant-application-which-supports-b2b-users/
There is a publicly documented Azure Management API that allows you to do this: https://learn.microsoft.com/en-us/rest/api/resources/tenants
GET https://management.azure.com/tenants?api-version=2016-06-01 HTTP/1.1
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUz...
...
The response body looks something like this:
{
"value" : [{
"id" : "/tenants/d765d508-7139-4851-b9c5-74d6dbb1edf0",
"tenantId" : "d765d508-7139-4851-b9c5-74d6dbb1edf0"
}, {
"id" : "/tenants/845415f3-7a05-45c2-8376-ee67080661e2",
"tenantId" : "845415f3-7a05-45c2-8376-ee67080661e2"
}, {
"id" : "/tenants/97bcb93f-8dee-48ed-afa3-356ba40f3a61",
"tenantId" : "97bcb93f-8dee-48ed-afa3-356ba40f3a61"
}
]
}
The resource for which you need to acquire an access token is https://management.azure.com/ (with the trailing slash!).

Building SOAP Listener with Azure Functions

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!

Resources