wso2 api manager path pattern issue - wso2

I'm having issue with what I feel is a simple url pattern match, but seeing unexpected behavior for an API I created.
I set up the API, and when I place the "URL Pattern", I do something simple like "/player/{playerId}"
When I go to the next screen to input the endpoint information, I reference my path variable as it appears in the documentation, like http://mycoolendpoint.com/playerInfo/{uri.var.playerId}
What I end up seeing is that the entire URL pattern is being appended to my endpoint. So, in the above, instead of seeing the expected http://mycoolendpoint.com/playerInfo/111, I see coming across the wire http://mycoolendpoint.com/playerInfo/111/player/111
Am I setting up something wrong when I do this syntax that it's appending the entire URL pattern to the Sandbox and Production endpoints instead of just the value of the path variable?

API's resource is normally appended to its endpoint URL by API Manager by default So to avoid this you can follow below instructions,
Create a custom sequence with the following content and save it as a .xml file.
<sequence xmlns="http://ws.apache.org/ns/synapse" name="TestSequence">
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
</sequence>
Now edit your API in publisher. In design view go to "Message Mediation Policies" section and Enable Message mediation. Now add a In Flow and upload the previously saved sequence.

There are 2 ways you can do this by defining your API like below.
1) Define resource like this.
playerInfo/{playerId}
and define endpoint like this.
http://mycoolendpoint.com/
Or
2) Define resource like this.
/{playerId}
and define endpoint like this.
http://mycoolendpoint.com/playerInfo/
Or you can also do this as #ycr has mentioned. If you want to do that change for all APIs without creating a custom sequence file, you can add below line inside InSequence section of <APIM_HOME>/repository/resources/api_templates/velocity_template.xml file.
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
This template is used when APIM creates synapse files of new APIs.

Related

WSO2 EI, getting HTTP request's message contents inside Sequence

I have been reading this documentation more than two weeks and it is still hard to understand some concepts.
Lets consider simple case. User makes request to our API then EI must call specific endpoint depending on requests body and show response.
Now there is the main problem on getting data of HTTP request.
I know that it could be accessed via Property Mediator, but this documentation does not help to understand anything.
if user makes GET request like this:
https://my-ei-domain.com:8280/myapi/mymethod?query1=1&query2=2
How it is possible to get values of query1 and query2
If user makes POST request with urlencoded form data how to get them?
If user makes POST request with JSON body like this:
{
"var1": "one",
"var2": 2,
"var3": {
"var3_var1": "two"
}
}
How to get values of these variables?
User makes POST request with XML body:
<body>
<var1>1</var1>
<var2>2</var2>
<var3>
<var1>3</var1>
</var3>
<body>
How to get these values?
Next problem. Sometimes users will send some variables inside Headers of requests. How to get them?
These cases are not described well in documentation. Even if they are, they just scattered across multiple pages.
if user makes GET request like this... . Using as described in
documentation URL Template or URI mapping
https://docs.wso2.com/display/EI611/Working+with+APIs
If user makes POST request with urlencoded form data how to get them... There is no another way to get data as described above. Actually Content-Type is used to identify how data transfered and I think (since ESB server use apache http core lib, widely used) will able to handle param values. Anyway that is easy to reproduce. Create rest service, send urlencode request and see how it works.
If user makes POST request with JSON body like this... Rules are described in documentation how to work with json in synapse engine https://docs.wso2.com/display/ESB480/JSON+Support (paragraph Accessing content from JSON payloads)
User makes POST request with XML body: to rest service ? to webservice? Anyway, xpath is commonly used to access certain parts of xml documents. But, synapse engine has to identify that xml document is received and parse it. Engine relies on Content-Type, details in here https://docs.wso2.com/display/ESB480/Working+with+Message+Builders+and+Formatters
Next problem. Sometimes users will send some variables inside Headers of requests. How to get them? In here how to read http headers in esb
Most of answers in documentation or easy to find by in web.
Your question is quite long and I can see you are requesting tutorials on how to achieve these. I hope the following Wso2 related tutorials will help you:
Enterprise Service Integration
Service Orchestration
Restful Integration
As an example let me explain the answers to a few of your questions:
To get information from a query like the following:
http://127.0.0.1:8280/pizzashop/api/menu/pizza?val=thin&type=crust
you may use property mediators like this:
<property name="Type" expression="$ctx:query.param.type"></property>
<property name="Val" expression="$ctx:query.param.val"></property>
WSO2 uses mediators to achieve most of the tasks. For example the payloadFactory mediator can be used to process the json and xml body and transform them. To process the following json
{ "payment":
{
"amount_lkr": "175.00",
"card_no": "1234-5678-9876-5432"
}
}
we can use payloadFactory mediator as follows:
<payloadFactory media-type="json">
<format>{"purchaseInformation": {"amount": "$1","cc": "$2"}}</format>
<args>
<arg evaluator="json" expression="$.payment.amount_lkr"></arg>
<arg evaluator="json" expression="$.payment.card_no"></arg>
</args>
</payloadFactory>
Similarly this mediator and others can be used to process xml as well in a POST request.
Please learn from the tutorials. The details are too broad to be explained in a single answer

Generate/Create New Query Parameter in WSO2-AM Sequence

I have a use case where create new set of query parameters(Say 4 new query parms) based on a query parameter come from request and send all query parameters(both newly created and old) into target server. How to achieve ? I have created a logic to split that query param come from request using Script Mediator and set into query param function like mc.setProperty("query.param.IndA", IndA);
<script function="restGET"
key="conf:repository/resources/scripts/rest.js" language="js"/>
<header name="To" scope="default" value="http://localhost:8443/res/c/r/cust/0.0.1/e"/>
But this doesn't set in request and reached to end server. Is that anyway better way than this approach ?
You can use REST_URL_POSTFIX property to append values to the target endpoint. Please refer the example which uses that property.
Answer given by #pubci is correct. Here I am adding some additional info on reading query parameter from request- To read the query parameter from the request no need to have script mediator , you can just use synapse xpath variable $url [1]. You can find a sample here[2]
[1] https://docs.wso2.com/display/ESB481/Synapse+XPath+Variables#SynapseXPathVariables-$trp
[2] https://jenananthan.wordpress.com/2015/09/22/how-to-read-dynamic-query-parameter-in-esbapim-synapse/

Cannot use property expression in class mediator in WSO2 ESB 4.9.0

I created a class mediator and need to use expression for password property because it has been encrypted in vault,
However, the property inside of class mediator () seems not support expression. There is an exception in console,
We ran into same issue. We were unable use expression on a property for the class Mediator.
I am by no means an expert so if there is a better way hopefully someone else will speak up but this is how I got it working.
Change the property on your inSequence to this, really only adding scope="default"
<property name="passwordvault"
expression="wso2:vault-lookup('proxy.sunb.password')"
scope="default"/>
Then once you set that you can retrieve it inside nz.govt.mpi.NtlmAuthorisation2 retrieve the value like this
password = (String) synMgtx.getProperty("passwordvault");

WSO2 api manager not showing destination adress in API Usage by Destination

I'm using WSO2 AM 2.0.
I'm using dynamic endpoint throught custom sequence.
The problem is that my endpoint destination adress is not showing now
I have verifyed that it is insert empty in my analytics DB.
Is there any way to add this information?
In your custom sequence, please set another property named "ENDPOINT_ADDRESS" with the same value as the one you assign to "To" header. It will solve your problem.
For consequent invokes, the destination address will be set correctly.
ex:
<header name="To" value="https://localhost:9448/am/sample/pizzashack/v1/api/menu"/>
<property name="ENDPOINT_ADDRESS" value="https://localhost:9448/am/sample/pizzashack/v1/api/menu"/>

API MANAGER 1.9 query parameters are not accepted in swagger client console

After deploying a prototype, when trying to invoke the service without query parameters it works , but when i give the query parameter a value it will say resource not found
<am:fault xmlns:am="http://wso2.org/apimanager">
<am:code>403</am:code>
<am:type>Status report</am:type>
<am:message>Runtime Error</am:message>
<am:description>No matching resource found in the API for the given request</am:description>
</am:fault>
how can we support that any query parameter to be accepted after the URL
<resource methods="GET"
uri-template="accounts/{account_id}/asd"
faultSequence="fault">
Have you enabled JWT cahing? If you have enabled, there is a known issue in API Manager 1.9.0, which will be fixed in upcoming releases.
Thanks!
When you giving the URI pattern in the API Manger you have to give the "?*" character at the end if your URL contain query parameters. Even though swagger able to create the URL with that parameter,the runtime cannot identify it as a query parameter(runtime is based on Apache Synapse). By adding that character you are forcing the Synapse to append the query parameters to the URL.
so your template should be.
<resource methods="GET"
uri-template="accounts/{account_id}/asd?*"
faultSequence="fault">
Thanks