WSO2: Avoid hard-coding URI ports in Address Endpoint - wso2

I have configured an offset of '10' to my ESB server on the carbon.xml file. Now all deployed API's are pointing to the port 8290.
In my API I am calling another API via an Http Endpoint. I am setting the URI template manually to: http://localhost:8290/paramAPI, as follows:
<send>
<endpoint>
<http method="get" uri-template="http://localhost:8290/paramAPI"/>
</endpoint>
</send>
However I also want to deploy to other server instances. For example, I would like to deploy to a server with an offset of '20', and therefore the '/paramAPI' would no longer be reachable at port '8290', instead on '8300'.
In this case, the Http endpoint inside the send mediator must become:
<send>
<endpoint>
<http method="get" uri-template="http://localhost:8300/paramAPI"/>
</endpoint>
</send>
I am searching for a method to parameterize the port value.
I have tried to use local entries by defining a string variable on the server by the name APIPort. When referencing it, I modified the HTTP endpoint as follows:
<send>
<endpoint>
<http method="get" uri-template="http://localhost:{APIPort}/paramAPI"/>
</endpoint>
</send>
but I got: java.net.MalformedURLException: For input string: "{APIPort}"
What is the best approach to parameterize URI's? if local entries are used then what is the proper way to use them as parameters and reference them in the URI?
Much appreciated and kind regards,

if I recall correctly you should use uri.var for your uri-template properties. Try to name your property uri.var.APIPort instead.
To be sure I created a simple API , see the following example:
<api xmlns="http://ws.apache.org/ns/synapse" name="testapi" context="/test" version="1" version-type="context">
<resource methods="POST GET">
<inSequence>
<property name="uri.var.version" value="v2"/>
<send>
<endpoint>
<http uri-template="http://mocky.io/{uri.var.version}/5d1dec2a3000006a00d7239d"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</resource>
</api>

Related

WSO2 ESB REST with dynamic parameters

I build up a API which should take dynamic parameters like below,
<api xmlns="http://ws.apache.org/ns/synapse" name="MrlDatabaseAPI" context="/rest">
<resource methods="OPTIONS GET" uri-template="/reportNotes?country={country}&pesticide={pesticide}&crop={crop}">
<inSequence>
<send>
<endpoint>
<http method="GET" uri-template="http://172.17.100.113/MRLService/rest/v1/reportNotes?country={uri.var.country}&pesticide={uri.var.pesticide}&crop={uri.var.crop}"/>
</endpoint>
</send>
</inSequence>
Now the resource only work if passing all three parameters, http://localhost/rest/reportNotes?country=AUS&pesticide=ABA3000&crop=22020100.
How can I tweak the API and make it accept any two parameters, like:
http://localhost/rest/reportNotes?country=AUS&pesticide=ABA3000 or http://localhost/rest/reportNotes?country=AUS&crop=22020100
The Restful web service itself can accept any number of parameters.
Thanks,
Sean
According to your configuration, it can't be solve with any number of parameters.
You may solve the issue with "filter" mediator
Ex:
<filter source="boolean(get-property('uri.var.pesticide'))" regex="false">
<then>
<send>
<endpoint>
<http method="GET" uri-template="http://172.17.100.113/MRLService/rest/v1/reportNotes?country={uri.var.country}&crop={uri.var.crop}"/>
</endpoint>
</send>
</then>
<else>
<drop/>
</else>
</filter>
You may implement your scenario with this mediator.

WSO2ESB HTTP Endpoint throws exception when using uri.var parameters in the uri-template

I tried to invoke a REST endpoint by using the following configuration:
...
<property name="uri.var.host" value="localhost:8080"/>
<property name="uri.var.context" value="my-service"/>
<call>
<endpoint>
<http method="POST" uri-template="http://{uri.var.host}/{uri.var.context}" />
</endpoint>
</call>
...
But then I get an XMLStreamException that says "DOCTYPE is not allowed":
[2016-06-01 17:16:15,702] ERROR - RelayUtils Error while building Passthrough stream
org.apache.axiom.om.OMException: javax.xml.stream.XMLStreamException: DOCTYPE is not allowed
...
On the other hand, it works without any issues if I don't use uri.var parameters, i.e. this configuration works:
...
<call>
<endpoint>
<http method="POST" uri-template="http://localhost:8080/my-service"/>
</endpoint>
</call>
...
Unfortunately, I need to use uri.var parameters since the target endpoint needs to be specified dynamically. So the question is how can I make uri.var parameters to work? Thanks!
If you enable the wirelog you can find what is the actual endpoint you are referring.see below sample request.
<property name="uri.var.username" expression="$func:username"/>
<call>
<endpoint>
<http method="get" uri-template="{+uri.var.apiUrl}/users/{+uri.var.username}/orgs"/>
</endpoint>
</call>

How to add query params to URL in API in WSO2 ESB

I need to append query params to endpoint URI according to query params in request.
I have an resource API in ESB published like this:
<resource methods="GET" url-mapping="/searchEngine/sortAndFilterVolunteers*">
<inSequence>
<send>
<endpoint>
<address
uri="http://localhost:8080/project-web-services/services/project-rs"></address>
</endpoint>
</send>
</inSequence>
I have to append query params dinamically.
How could I do that?
Following sample API definition may help you.
<api xmlns="http://ws.apache.org/ns/synapse" name="sample" context="/api/sample">
<resource methods="OPTIONS GET" uri-template="/{val1}/groups/{val2}.json?q1={v1}&q2={v2}">
<inSequence>
<property name="uri.var.q1" expression="$url:q1"></property>
<property name="uri.var.q2" expression="$url:q2"></property>
<property name="uri.var.val1" expression="get-property('uri.var.val1')"></property>
<property name="uri.var.val2" expression="get-property('uri.var.val2')"></property>
<send>
<endpoint>
<http method="GET" uri-template=""></http>
</endpoint>
</send>
</inSequence>
<outSequence>
<send></send>
</outSequence>
</resource>
</api>
Add the query parameter to uri-template in resource as below :
<resource methods="GET" uri-template="/getStudents/{id}">
When sending to the endpoint,
<send>
<endpoint>
<http method="get" uri-template="http://studentsapi/student/{uri.var.id}"/>
</endpoint>
</send>
Add the query parameter to url-mapping in resource as below : url-mapping="/*"
*
you can send a request may be server:port/service?q1={q1} and other request may be server:port/service?q2={q2}&q3={q3}.

WSO2 ESB Proxy Basic Service Chaining

this is what I thought would be a fairly straight-forward service chaining scenario.
All I want to do it forward some data to a proxy service, that proxy service will then iterate over the data and use an ID ("entity_id") from that data (which it can successfully retrieve) to look up a resource sitting in WSO2 Data Services Server. Once it has the result of that request, I want to forward it to another application (RequestBin, in this case).
Please take a look at my proxy configuration below:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="pollService"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<log level="full"/>
<iterate id="iter1"
expression="//*[local-name()='Change']"
sequential="true">
<target sequence="anon">
<sequence>
<log level="full"/>
<property name="uri.var.entityid" expression="//*[local-name()='entity_id']"/>
<call>
<endpoint>
<http method="get"
uri-template="http://54.66.155.36:9764/services/civicrm/activity/{uri.var.entityid}"/>
</endpoint>
</call>
<log level="full"/>
<call>
<endpoint>
<http method="post" uri-template="http://requestb.in/1c79v711"/>
</endpoint>
</call>
<log level="full"/>
</sequence>
</target>
</iterate>
</inSequence>
</target>
<description/>
</proxy>
I currently do not get any indication that those two calls have fired at all.
Any assistance would be greatly appreciated.
Thank you.
you can enable the wirelog and verify whether calls have fired or not.
please refer the following blog post to learn about wirelog.
1 http://mytecheye.blogspot.in/2013/09/wso2-esb-all-about-wire-logs.html
Could you also give a sample message (what is going into the proxy) , and to see a finer-grain detail of what is going on in your proxy , go into [esb-home]/repository/conf/ and open the log4j.properties file , and set
log4j.category.org.apache.synapse=DEBUG , also do as #robin suggested. Try putting
<log level="full" category="DEBUG" separator="-----:-----"/>
in your proxy where you want to see the state of the message at that point.

How to extract http headers using a mediator

How do I extract http headers like
Authorization: ​"admin 0PN5J17HBGZHT7JJ3X82"
where admin is the username and 0PN5J17HBGZHT7JJ3X82 is the password and assign it to a property/variable which would be then passed to a dss service for user login verification. From what I know our API can be do this using custom sequences and mediators (https://docs.wso2.com/display/AM170/Adding+Mediation+Extensions) but its not clear tome on how to extract this header and assign it to different property names like login and password.
Does a mediator header can take care of this? Or this there another way of doing by using a proxy service?
Header Mediator
<in>
<header name="Authorization" value="admin 0PN5J17HBGZHT7JJ3X82" scope="transport"/>
<send>
<endpoint name="people">
<address uri="http://localhost:9443/testapi/" format="get"/>
</endpoint>
</send>
</in>
<out>
<send/>
</out>
Proxy Service
<proxy name="adminServiceProxy" transports="https http"
startOnLoad="true" trace="disable">
<description/>
<target>
<endpoint>
<address uri="https://localhost:9443/testapi"/>
</endpoint>
<inSequence>
<property name="Authorization"
expression="fn:concat('Basic ','admin:0PN5J17HBGZHT7JJ3X82')"
scope="transport"/>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
</proxy>
Thank you
You can extract like this;
<property name="AuthHeader" expression="$trp:Authorization"/>
Then log it and see what you are retrieving..
<log>
<property name =" Authheder value" expression=get-property('AuthHeader')/>
</log>
Then construct Basic auth header as you pointed in your proxy configuration.
Here is a blog post which explains how you can retrive various information from a sequence