401 Unauthorized when querying durable function status - c#

I need some help with Azure Durable Functions.
I created a new durable function with VS Code in C# and deployed it to Azure via the VS Code azure function extension. The function app resource was already created manually in the portal. I use
FUNCTIONS_WORKER_RUNTIME: dotnet
FUNCTIONS_EXTENSION_VERSION: ~2
I can trigger the creation of an durable task and but when I query the status with the statusQueryGetUri, I only get a 401 Unauthrized. The http trigger of the function itself is anonymous and does not require authentication (for debug purpose only).
The requests look like this (I used Postman to send the requests):
HTTP POST https://{function-app}.azurewebsites.net/api/SayHello_HttpStart
Response:
{
"id": "da3259a462084e86a34f8ce9859a6ed6",
"statusQueryGetUri": "https://{function-app}.azurewebsites.net/runtime/webhooks/durabletask/instances/da3259a462084e86a34f8ce9859a6ed6?taskHub=DurableFunctionsHub&connection=Storage&code=ua4tHacVv9JDH5phKCJI1OdKGXQSB/MMUX8WIv1E0OyZANqrRY3L/g==",
"sendEventPostUri": "https://{function-app}.azurewebsites.net/runtime/webhooks/durabletask/instances/da3259a462084e86a34f8ce9859a6ed6/raiseEvent/{eventName}?taskHub=DurableFunctionsHub&connection=Storage&code=ua4tHacVv9JDH5phKCJI1OdKGXQSB/MMUX8WIv1E0OyZANqrRY3L/g==",
"terminatePostUri": "https://{function-app}.azurewebsites.net/runtime/webhooks/durabletask/instances/da3259a462084e86a34f8ce9859a6ed6/terminate?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=ua4tHacVv9JDH5phKCJI1OdKGXQSB/MMUX8WIv1E0OyZANqrRY3L/g==",
"rewindPostUri": "https://{function-app}.azurewebsites.net/runtime/webhooks/durabletask/instances/da3259a462084e86a34f8ce9859a6ed6/rewind?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=ua4tHacVv9JDH5phKCJI1OdKGXQSB/MMUX8WIv1E0OyZANqrRY3L/g==",
"purgeHistoryDeleteUri": "https://{function-app}.azurewebsites.net/runtime/webhooks/durabletask/instances/da3259a462084e86a34f8ce9859a6ed6?taskHub=DurableFunctionsHub&connection=Storage&code=ua4tHacVv9JDH5phKCJI1OdKGXQSB/MMUX8WIv1E0OyZANqrRY3L/g=="
}
The Get Request is then simply:
GET https://{function-app}.azurewebsites.net/runtime/webhooks/durabletask/instances/da3259a462084e86a34f8ce9859a6ed6?taskHub=DurableFunctionsHub&connection=Storage&code=ua4tHacVv9JDH5phKCJI1OdKGXQSB/MMUX8WIv1E0OyZANqrRY3L/g==
Did I miss some configuration I have to set to allow access to the uri? What logs might help me figure out what the problem is?
When I run the code locally there are no problems and everything works as expected.
Thanks a lot for all help!

Note that the statusQueryGetUri is an admin endpoint which always requires a System Key.
GET <rootUrl>/runtime/webhooks/durabletask/instances/<GUID>
?taskHub={taskHub}
&connection={connection}
&code={systemKey}
As an alternative, you could also set the x-functions-key header of the http request with this key.
More info on the usage of the HTTP endpoints in the docs.

Related

How to use CloudFunctions in a Xamarin project

Is there a tutorial on how to properly call a cloud function using Xamarin.Firebase.iOS.CloudFunctions? Or how to setup a regular http request for it, without the library?
I set up my function like this:
exports.IsAppleSubscriptionActive = functions.https.onCall(async (data, context) => {});'''
and deployed it like this:
firebase deploy --only functions
and got and url like this:
https://[region]-[project-id].cloudfunctions.net/IsAppleSubscriptionActive
On the client I installed the nuget and I try calling:
var result = await CloudFunctions.DefaultInstance.HttpsCallable("IsAppleSubscriptionActive").CallAsync(payloadToSend);
where payloadToSend is a NSDictionary.
I get
Foundation.NSErrorException: Error Domain=com.firebase.functions Code=13 "INTERNAL" UserInfo={NSLocalizedDescription=INTERNAL}
What am I missing? I feel like the native tutorials aren't helping either.
When using a regular http request I get a 500 status, in the logs I see something related to permissions accessing the secret manager (I use it for some api keys).
Ok, so there was nothing wrong with the code, I just wasn't giving the proper permissions to the proper user (I was using Secret Manager in my cloud function)

RingCentral ERROR 503: The request could not be satisfied

We are trying to download attachments from RingCentral (Glip), however, we have noticed that the download URL has been changed during the last couple of days. We have tried using the Bearer Token with the new download URL to download the files, however, we have received an error with response code 503.
ERROR
503 ERROR
The request could not be satisfied.
The Lambda function associated with the CloudFront distribution is invalid or doesn't have the required permissions. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
Generated by CloudFront (CloudFront)
Request URL
dl.mvp.devtest.ringcentral.com/file/105660426
The only change necessary for the recent auth change is to add the Bearer Token to the URL. This can be seen in the update notice:
What do I need to do?
To eliminate or minimize the impact of this change, developers will need to modify their application to attach authentication credentials to all file download requests. See downloading protected content in the Media content section of the RingCentral Developer Guide.
https://medium.com/ringcentral-developers/important-changes-to-how-team-messaging-files-are-downloaded-bb13c97b3c89
A 503 HTTP Status Code is a temporary sever-side error so there's generally nothing to be done on your end but the problem should go away on its own. If you cannot wait or it's taking a long time to resolve itself, please create a support case so the team can communicate the status to you.
Here's some information on 503 errors from MDN:
503 Service Unavailable
The HyperText Transfer Protocol (HTTP) 503 Service Unavailable server error response code indicates that the server is not ready to handle the request.
Common causes are a server that is down for maintenance or that is overloaded. This response should be used for temporary conditions and the Retry-After HTTP header should, if possible, contain the estimated time for the recovery of the service.
Caching-related headers that are sent along with this response should be taken care of, as a 503 status is often a temporary condition and responses shouldn't usually be cached.

Disable Azure Function from C# for runtime version 3.x?

How can I disable an Azure Function using code in C#?
I'm using Azure Functions Runtime version 3.x
I'm implementing a distributed circuit-breaker inspired by Serverless circuit breakers with Durable Entities. When the circuit opens I need to disable a queue-trigged Azure Function, instead of stopping the entire function app.
I see from How to disable functions in Azure Functions that the recommended way to disable a function is to set the AzureWebJobs.<FUNCTION_NAME>.Disabled app setting. But I haven't found an API for doing that in C#. I'm hoping there is something that I can call from my C# code that is equivalent to the Azure CLI's az functionapp config appsettings set command.
I saw similar questions on SO like:
azure set environment variable programmatically to disable an azure function
and How to Enable/Disable Azure Function programmatically
But those have answers from back in 2017 that use kudu APIs to change the disabled property in the function.json file, and I'm hoping that there is a better way to do that now. Especially because the Docs at How to disable functions in Azure Functions say:
The generated function.json file for a class library function is not
meant to be edited directly. If you edit that file, whatever you do to
the disabled property will have no effect.
Unfortunately I was not able to find any documentation as such. The closest I got was
https://learn.microsoft.com/en-us/rest/api/appservice/webapps/createfunction
For instance to create the function :
https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/functions/{functionName}?api-version=2019-08-01
However this documentation also did not take me near to your requirement of updating the Config File. Or I may have overlooked few modules. Request you check further before implementing the below steps
So here's is what I did, I was kind of trying to reverse engineer, I ran the commands in Azure CLI and captured the traces - my thought process - the Azure CLI internally run on python and issues the API request to the Azure.
Ran the below command and captured Fiddler :
az functionapp config appsettings set --name <myFunctionApp> \
--resource-group <myResourceGroup> \
--settings AzureWebJobs.QueueTrigger.Disabled=true
And Yes ! The python process was issuing request to https://management.azure.com to update appsetting :
The set property is sent in the Request Body :
We can hardcode the properties or get it dynamically.
So I ran the below Azure CLI command
az functionapp config appsettings list --name <> --resource-group <>
I was able to see the above properties that was passed along the PUT request
Took the fiddler for the above command
Saw there is a POST Request to the below endpoint :
https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Web/sites//config/appsettings/list?api-version=2019-08-01
These are the same set of property bags which are sent as the request bodies in the PUT in order to set the property.
So in your case you will have to request the above end point to get the list of properties. It is json output. Update the value of AzureWebJobs.QueueTrigger.Disabled to True.
Issue the Updated properties using the PUT method along with the headers such as Bearer Token & Content-Type: application/json; charset=utf-8
Request URI :
https://management.azure.com/subscriptions//resourceGroups//providers/Microsoft.Web/sites//config/appsettings?api-version=2019-08-01
Headers :
Authorization: Bearer <> Content-Type: application/json;
charset=utf-8`
Request Body:
{"kind": "<class 'str'>", "properties": }
I hope you will be able to achieve your requirement.
I hope this helps you :)
I don't recommend this for your prod. Pls try and monitor in your Dev env.

Azure Notification Hubs Register Device Error 404

This is the first time I'm using Azure Notification Hubs and I'm having some trouble getting it working properly with my application.
The part I'm stuck on (at the moment) is registering my device with the notification hub. I'm using the backend method to do the registration ... that is, I'm creating an Installation object and using the CreateOrUpdateInstallationAsync method to register the device via my Web API. I'm only testing it at this stage so I'm hitting my API endpoint with dummy data via Postman.
When I step through my code, I'm getting the following error when I execute CreateOrUpdateInstallationAsync ...
The remote server returned an error: (404) Not Found. Entity does not
exist.TrackingId:203cba37-007d-4dcb-ae25-ced33fa012aa_G1,TimeStamp:2/4/2018
10:24:02 PM
I've tested that I am connecting to the Notification Hub correctly by calling GetAllRegistrationsAsync. This returns an empty list (expected) and no error ... so I have my endpoints set up correctly. I'm wondering if there is a problem with my dummy data? For the installation Id, I've just created a random GUID (Guid.NewGuid). The Device ID and Push Notification Handle are random numbers and letters. And I'm testing this for the Android platform (NotificationPlatform.Gcm).
Has anyone seen this error before and know what it means? Am I able to just use random data for testing purposes (I'm only interested in registering devices at this stage) or do I need legitimate data (real device id's, etc)?
Thanks in advance.
The CreateOrUpdateInstallationAsync method would essentially invoke the REST API Create or Overwrite an Installation. When you register with a notification hub from your custom backend using the Installation, the core code would look like as follows:
NotificationHubClient hubclient = NotificationHubClient.CreateClientFromConnectionString(listenConnString, hubName);
await hubclient.CreateOrUpdateInstallationAsync(installation);
Note: You could install the Microsoft.Azure.NotificationHubs package for back end operations.
For a simpler way, I just created a console application and test this operation as follows:
Note: I just created a new Azure Notification Hub and did not set any notification settings. And I set a GUID as the InstallationId and a random string as the PushChannel, the rest operation could work as expected.
And I could retrieve the previous added registration as follows:
Has anyone seen this error before and know what it means? Am I able to just use random data for testing purposes (I'm only interested in registering devices at this stage) or do I need legitimate data (real device id's, etc)?
The operation could work on my side, I would recommend you debug your application and leverage fiddler to capture the network traces to narrow this issue. Moreover, you could follow Registration management for more details about registering devices with azure notification hubs.
Ok, it turns out that I had the wrong value for Hub Name when instantiating the NotificationHub object using NotificationHubClient.CreateClientFromConnectionString. I was using the namespace, instead of the hub name (visible on the Overview tab in the Azure Portal).

How to inform users that api maintenance is in progress

I am using azure app service and DB for my C# ODATA API and DB as the backend of of my phone app.
I only have one app service that hosts 10s of endpoints. There are times when I need to publish new versions and I don't want any incoming requests during that time of deployment.
I don't mind that users are not able to finish their requests during the maintenance.
Is there anything in Azure or API that can let me:
1. turn off the api/app service manually?
2. Be able to inform the user that a maintenance is in progress?
This is my trial:
the only thing I can come up with is this. While users always use the "odata" in their url requests: https://myserverl/odata/Users
which is setup in the webapi.config like this:
config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
I put the routePrefix (2nd odata) in a web.config.
When I need to turn off access, I change my web.config (which I can access manually even after the publish of code into Azure) to be like this:
<add key="odata" value="noaccess" />
and in my webapi.config:
string odata = ConfigurationManager.AppSettings["odata"].ToString();
config.MapODataServiceRoute("odata", odata, builder.GetEdmModel());
and then save the web.config which will reset the server and all incoming requests that has "odata" will result into error. I can always set it back later.
This method will stop the users from sending requests during maintenance but will not let them know what is going on.
I figured it out.
when I call the server from my client, I verify that the response is between 200 & 299 before parsing results or any other further processing.
So now, I check also for the possible response from the server that it could be either 403 (access is denied) or 503 (server is unavailable). That's where I can add code to notify the user.
In Azure, simply stopping the app service, will generate one of those 2 error codes.
Note: You must check for both: 403 & 503.

Categories