In Azure API Management, I need to check whether or not a query parameter is set. To achieve this, I'm trying to use context.Request.Url.Query.GetValueOrDefault(queryParameterName: string, defaultValue: string).
According to the documentation, this expression works as follows -
Returns comma separated query parameter values or defaultValue if the parameter is not found.
With that in mind, I used the example from the MS blog Policy Expressions in Azure API Management, to create the following <inbound> policy -
<set-variable name="uniqueId" value="#(context.Request.Url.Query.GetValueOrDefault("uniqueId", ""))" />
However, whenever I include this policy, execution fails with 404 Resource Not Found. Upon inspection of the trace, I can see that the execution was aborted without error before a single policy was evaluated (no matter where within <inbound> the above policy is placed.
This behavour results in the following <backend> trace, which explains the 404
"backend": [
{
"source": "configuration",
"timestamp": "2017-09-07T12:42:13.8974772Z",
"elapsed": "00:00:00.0003536",
"data": {
"message": "Unable to identify Api or Operation for this request. Responding to the caller with 404 Resource Not Found."
}
}
],
Given that the MS documentation seems to be inaccurate, how can I check whether or not a query parameter is set?
So the answer here is that there is (another) MS bug.
When the API operation was originally created, the uniqueId query parameter was set as required. I changed this so that it was not required before adding the policy described in my question, however a bug within the new Azure Portal means that when you uncheck the Required box adjacent to the query parameter and then save your changes, they are ignored.
I was able to work around this behaviour be editng the YAML template in the OpenAPPI specification view, removing the declaration required: true for the query parameter in question. The expresion within my policy now works as expected.
Please note: that this workaround sheds light on yet another bug, where saving the template results in your policies being deleted, so make sure you take a copy first.
Related
I'm running into this error - ActionFailed. An action failed. No dependent actions succeeded - when trying to run this logic app to add an IP to be blocked.
Error
I'm not sure where to start. The input looks ok. Help? Thanks in advance!
p.s. - sorry, it won't allow me to post the pics due to not having enough points.
Tried changing some parts of the body. Not sure what to change really.
According to Microsoft's documentation on Submit or Update Indicator API the request body should be as follows:
{
"indicatorValue": "220e7d15b011d7fac48f2bd61114db1022197f7f",
"indicatorType": "FileSha1",
"title": "test",
"application": "demo-test",
"expirationTime": "2020-12-12T00:00:00Z",
"action": "AlertAndBlock",
"severity": "Informational",
"description": "test",
"recommendedActions": "nothing",
"rbacGroupNames": ["group1", "group2"]
}
Since the error you get is too generic, it isn't clear enough to know exactly.
You are not passing in recommendedActions and rbacGroupNames, they may not be required but may want to pass the column even if no value is included.
I would also validate calling this API using manual values (even the exact value from their documentation) and if that does work, use process of elimination to figure out which property is giving you the trouble.
i.e. application might not accept a space value or combining the two values for description should be done outside of the HTTP call using compose and then passed as a single value of the output.
I am using QuickBooks. Somehow I am getting some weird error on creating one invoice.
{
"Fault": {
"Error": [
{
"Message": "Duplicate Document Number Error",
"Detail": "Duplicate Document Number Error : You must specify a different number. This number has already been used. DocNumber=O0010714 is assigned to TxnType=Invoice with TxnId=45823",
"code": "6140",
"element": ""
}
],
"type": "ValidationFault"
},
"time": "2020-12-15T04:54:25.476-08:00"
}
Why it is happening as there is no doc in the QuickBooks which says that doc number is a unique entity.
Short version: DocNumber should be unique in most cases. In some cases you can add include=allowduplicatedocnum arg in URL to allow that. Be aware that DocNumber can be automatically generated.
Long version: taken from DocNumber field documentation for Invoice
Reference number for the transaction. If not explicitly provided at
create time, this field is populated based on the setting of
Preferences:CustomTxnNumber as follows:
If Preferences:CustomTxnNumber is true a custom value can be provided.
If no value is supplied, the resulting DocNumber is null.
If Preferences:CustomTxnNumber is false, resulting DocNumber is system
generated by incrementing the last number by 1.
If Preferences:CustomTxnNumber is false then do not send a value as it
can lead to unwanted duplicates. If a DocNumber value is sent for an
Update operation, then it just updates that particular invoice and
does not alter the internal system DocNumber.
Note: DocNumber is an
optional field for all locales except France. For France locale if
Preferences:CustomTxnNumber is enabled it will not be automatically
generated and is a required field. If a duplicate DocNumber needs to
be supplied, add the query parameter name/value pair,
include=allowduplicatedocnum to the URI.
P.S. Late response, but may be useful for somebody in future.
UPD:
Looks like library from npm node quickbooks doesn't support that natively. Because method createBill doesn't allow to provide any params to URI. Even method module.create have just hardcoded url variable without ability to provide nothing extra.
In this case, if you still want to use include=allowduplicatedocnum, you have the following options:
monkey-patch this library;
make fork and do updates;
ask authors of that library to implement that instead of you;
find a library that will support that;
send raw requests to QBO from your code.
[First of all, it is very sad that BizSpark susbcription do not have any technical support, even to inform a error like this :-((( ]
Ok, well , the error, that occurs twice creating a VirtualMachine, so replicated:
{
"error": {
"code": "InvalidParameter",
"target": "resourceGroupName",
"message": "The entity name 'resourceGroupName' is invalid according to its validation rule: ^[^_\\W][\\w-._]{0,79}(?<![-.])$."
}
}
The reason, it is because my resource group is called _ReGr_MyName,
but IT ALREADY EXIST !!!
(indeed the rest of resources, like Public-Ip, Storage Accounts, etc, are already under that resource group)
so seems like validation rules are inconsistent across different resources
I can provide the Operation-Id or the TRacking-ID if necesary
But please, solve this short of issues, Azure should be an stable system
In general, avoid having any special characters (- or _) as the first or last character in any name. These characters will cause most validation rules to fail.
For detailed information, please check this article.
Since we can't edit the name of created resource group, you may need to create a new resource group and move the resources into it.
Here is a good answer from Zain Rizvi.
Here is what RFC 5789 says:
The PATCH method requests that a set of changes described in the request entity be applied to the resource identified by the Request-URI. The set of changes is represented in a format called a "patch document" identified by a media type. If the Request-URI does not point to an existing resource, the server MAY create a new resource, depending on the patch document type (whether it can logically modify a null resource) and permissions, etc.
The difference between the PUT and PATCH requests is reflected in the way the server processes the enclosed entity to modify the resource identified by the Request-URI. In a PUT request, the enclosed entity is considered to be a modified version of the resource stored on the origin server, and the client is requesting that the stored version be replaced. With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version.
Let's say I have { "login": "x", "enabled": true }, and I want to disable it.
According to post "Please. Don't Patch Like An Idiot.", the proper PATCH request would be
[{ "op": "replace", "path": "/enabled", "value": false }]
However, let's take this request:
{ "enabled": false }
It also 'contains a set of instructions describing how a resource currently residing on the origin server should be modified', the only difference is that JSON property is used instead of JSON object.
It seems less powerful, but array changes can have some other special syntax if required (e.g. {"a":{"add":[], "remove":[]}}), and server logic might not be able to handle anything more powerful anyway.
Is it an improper PATCH request as per RFC? And if so, why?
And, on the other hand, would a { "op": "disable" } be a correct PATCH request?
the only difference is that JSON property is used instead of JSON object.
It's actually a bit deeper than that. The reference to RFC 6902 is important. The first request has a Content-Type of application/json-patch+json, but the second is application/json
The important thing is that you use a 'diff media type,' one that's useful for this purpose. You don't have to use JSON-PATCH, (I'm a big fan of json-merge-patch), but you can't just use anything you want. What you're asking about in the second part is basically 'can I make my own media type' and the answer is 'yes,' just please document it and register it with the IANA.
Query string parameter
I have seen plenty of examples of reading query string parameters.
For example take the following URI:
/api/Profile?id={accountId}
The accountId can be read in the policy xml using the following syntax:
context.Request.Url.Query["accountId"]
Route parameter
But what if my URI is structured as:
/api/profiles/{accountId}
How do I read accountId in the policy xml when the parameter is not in the query string?
Using the example above I can read the accountId by the following syntax:
context.Request.MatchedParameters["accountId"]
For example I could assign it to a variable for usage elsewhere in the APIM policy file:
<set-variable name="account-id" value="#(context.Request.MatchedParameters["accountId"])" />
There isn't a massive amount of documentation about it, but thankfully there is at least some mention of the Context variable on learn.microsoft.com.
There is a GitHub repository with quite some snippets including your use case: https://github.com/Azure/api-management-policy-snippets/blob/master/policy-expressions/README.md
For your concrete example, you can use this:
context.Request.MatchedParameters.GetValueOrDefault("accountId", "optional-default-value")
The benefit compared to the other solution is that the policy evaluation does not fail if the URI parameter does not exist. It will use the default value as a fallback instead. Otherwise a 500 Internal Server Error would be returned.