Dynamically replace the PATH value of an Endpoint (WSO2 - API Manager) - wso2

I have created an API in the WSO2 API Manager (1.10.0) with the next info:
POST:
/regularPath/*
API URL:
http://<ip-address-1>/t/tenant.com/api/1.0.0/
HTTP-Endpoint:
http://<ip-address-2>:8181/{uri.var.newRestVar}
The issue is that the HTTP Endpoint has more than one path, e.g.:
http://<ip-address-2>:8181/mainService/cityInfo
http://<ip-address-2>:8181/country/cityInfo
http://<ip-address-2>:8181/country/dataKey/amountOfUsers
http://<ip-address-2>:8181/main/city/data/users
And I want that the resulting API URLs look like this:
http://<ip-address-1>/t/tenant.com/api/1.0.0/regularPath/mainService/cityInfo
http://<ip-address-1>/t/tenant.com/api/1.0.0/regularPath/country/cityInfo
http://<ip-address-1>/t/tenant.com/api/1.0.0/regularPath/country/dataKey/amountOfUsers
http://<ip-address-1>/t/tenant.com/api/1.0.0/regularPath/main/city/data/users
My initial approach was to use the REST_URL_PREFIX variable in order to capture the path after the 1.0.0 part of the API URL (e.g.: regularPath/country/dataKey/amountOfUsers) and then, assign that value to the uri.var.newRestVar variable.
Next, is the modified Service Bus Configuration of the API Manager (Carbon) I've created in the API Manager:
...
<inSequence>
<filter regex="PRODUCTION" source="$ctx:AM_KEY_TYPE">
<then>
<property expression="get-property('SYSTEM_TIME')" name="api.ut.backendRequestTime"/>
<log>
<property expression="$trp:To" name="ToURL"/>
</log>
<property expression="$axis2:REST_URL_POSTFIX" name="restURL" scope="default" type="STRING"/>
<log>
<property
expression="get-property('restURL')" name="logRestURL"/>
</log>
<script description="JS" language="js">
<![CDATA[
var unmodifiedRestPostfix = new String(mc.getProperty("restURL"));
print("value = " + unmodifiedRestPostfix);
unmodifiedRestPostfix = unmodifiedRestPostfix.replace("/regularPath/", "");
mc.setProperty("uri.var.newRestVar", unmodifiedRestPostfix);
]]>
</script>
<log>
<property expression="get-property('uri.var.newRestVar')" name="URI_VAR_NEWRESTVAR"/>
</log>
<send>
<endpoint name="admin-AT-tenant.com--API-Main_APIproductionEndpoint_0">
<http uri-template="http://<ip-address-2>:8181/{uri.var.newRestVar}"/>
</endpoint>
</send>
...
But it does not work. I checked the logs but everything seems to be OK:
TID: [35] [] [2016-04-11 16:47:01,955] #bank.com [35] [AM] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: local://axis2services/api/1.0.0/regularPath/mainService/cityInfo, MessageID: urn:uuid:091613ce-9fd3-4094-8638-5b112
a4214ad, Direction: request, logRestURL = /regularPath/mainService/cityInfo {org.apache.synapse.mediators.builtin.LogMediator}
a4214ad, Direction: request, URI_VAR_NEWRESTVAR = /regularPath/mainService/cityInfo {org.apache.synapse.mediators.builtin.LogMediator}
What configuration should I change in order to successfully access the HTTP-Endpoint using the paths of the API I've mentioned?

You can do the same thing without modifying the synapse configuration. Following are the steps. Hope it would be a solution for you
Create the api as following
API context : api/{version}/regularPath
Note: you can define the version in the context as a template in AM 1.10. once you define the version, above context will get the version
resources:
POST mainService/cityInfo
POST country/cityInfo
POST country/dataKey/amountOfUsers
POST main/city/data/users
HTTP Endpoint
http://<ip-address-2>:8181
After that you would be able to call a backend . No need to add custom modifications to synapse config
http://<ip-address-2>:8181/country/dataKey/amountOfUsers
with
http://<ip-address-1>/t/tenant.com/api/1.0.0/regularPath/country/dataKey/amountOfUsers
Additional information
If something went wrong, you can enable the wire logs and check what kind of request coming and going out in the gateway. see http://mytecheye.blogspot.com/2013/09/wso2-esb-all-about-wire-logs.html on how to enable wirelogs and debug using it.

Related

Remove activityid Parameter from response Header in WSO2- API Manager

As you know, by default, WSO2 add a "activityid" Parameter to each response header which would be passed from API-Manager.
Reference:
https://docs.wso2.com/display/EMM210/Getting+Operation+Details+by+the+Activity+ID
For some reason, I need to remove this parameter from the response for client. As I searched, I find out the following link
https://apim.docs.wso2.com/en/4.0.0/deploy-and-publish/deploy-on-gateway/api-gateway/message-mediation/removing-specific-request-headers-from-response/
So I added following code into Main.XML and Fault.XML, However it doesn't work
<property name="activityid" scope="transport" action="remove"/>
I also add the following property to the data flow of a specific API through Integrator Studio. However it doesnt work
<resource methods="POST" uri-template="/attachment">
<inSequence>
<call>
<endpoint key="attachment"/>
</call>
<send/>
</inSequence>
<outSequence>
<property action="remove" name="TRANSPORT_HEADERS" scope="default"/>
<property action="remove" name="activityid" scope="default"/>
</outSequence>
<faultSequence/>
</resource>
Anybody can Give me some advice about this matter??
You can use the message mediation for API Manager. Add the above property mediator to the response path 1 of the API.
Under runtime configurations of the API, there is a message mediation section for both request and response paths. Here you can upload a mediation sequence which will be executed in the request flow as well as response flow. You can save the mediation you need to an xml file and upload the file for the response flow.
1 - https://apim.docs.wso2.com/en/4.0.0/deploy-and-publish/deploy-on-gateway/api-gateway/message-mediation/changing-the-default-mediation-flow-of-api-requests/

Error with WSO2 ESB when trying to connect to Jira and ElasticSearch

I have and scenario where I want to extract dynamically Issues from Jira in order to save them on ElasticSearch. I use a custom Proxy Service that connect with Jira (via Jira connector), get a project (first I want to save the project's information) and pass this information to Elastic. Following is the in Sequence of the proxy service:
<?xml version="1.0" encoding="UTF-8"?>
<inSequence xmlns="http://ws.apache.org/ns/synapse">
<property expression="json-eval($.username)" name="username"/>
<property expression="json-eval($.password)" name="password"/>
<property expression="json-eval($.uri)" name="uri"/>
<property expression="json-eval($.id)" name="id"/>
<property expression="json-eval($.uriEl)" name="uriEl"/>
<property expression="json-eval($.indexName)" name="indexName"/>
<property expression="json-eval($.type)" name="type"/>
<property expression="json-eval($.message)" name="message"/>
<jira.init>
<username>{$ctx:username}</username>
<password>{$ctx:password}</password>
<uri>{$ctx:uri}</uri>
</jira.init>
<jira.getProject>
<projectIdOrKey>{$ctx:id}</projectIdOrKey>
</jira.getProject>
<property expression="json-eval($.project)" name="project"
scope="default" type="STRING"/>
<elasticsearch.init>
<apiUrl>{$ctx:uriEl}</apiUrl>
</elasticsearch.init>
<elasticsearch.createDocumentWithIndex>
<indexName>{$ctx:indexName}</indexName>
<type>{$ctx:type}</type>
<message>{$ctx:message}</message>
<body>{$ctx:project}</body>
</elasticsearch.createDocumentWithIndex>
<respond/>
</inSequence>
And here is the sample request:
{
"username":"MyName",
"password":"AnStrongPassword",
"uri":"JiraURL",
"id":"MyProject",
"uriEl":"http://localhost:9200",
"indexName":"jira",
"type":"project",
"message":"Testing"
}
The other parameters (Endpoint, out Sequence and Fault Sequence) are by default.
The problem is that when I try to send this request via 'Try the Test service' option on WSO2 ESB, i get the following error:
Error connecting to the Tryit ajax proxy
I have tested the same code but only using the Jira connection (without get a project or connect to Elastic), and the same error occurs.
Looking to this error, I suppose that the problem is before to read the JSON request, but I don't know if it is related to the endpoint (I think that it is not necessary an endpoint for this scenario).
Thanks in advance.
This problem is totally independent of the jira connector etc. Problem is with the "try it" tool. This tool is not that much recommended for testing purposes. Instead of that, try invoking the proxy service via soap ui.
If you share a screenshot when the try it error occurs, I'll be able to comment on that as well.
After a few days I have found another solution to my problem without using proxy services. To connect ESB with Jira, I created this API on ESB:
<api xmlns="http://ws.apache.org/ns/synapse" name="transport_service" context="/transport_service">
<resource methods="GET">
<inSequence>
<jira.init>
<uri>MyURL</uri>
<username>MyUser</username>
<password>3MyPass</password>
</jira.init>
<jira.searchJira>
<query>project=MyProject</query>
<maxResults>50000</maxResults>
<fields>MyField1,MyField2,etc</fields>
</jira.searchJira>
<respond/>
</inSequence>
<outSequence>
<log level="full"/>
<property name="messageType" value="application/xml" scope="axis2"/>
<send/>
</outSequence>
</resource>
</api>
The command to call this API is simple:
curl -v -X GET http://localhost:8280/transport_service > jira-db.json
Finally, if you want to insert this json on elastic, you can follow the typical PUT via curl:
curl -XPUT 'http://localhost:9200/jira/jira/1' -d #jira-db.json
Additionally, you can write both commands on a daily bash script (using your scheduled task list), getting the same result that scheduling your proxy service on WSO2ESB:
#!/bin/bash
curl -v -X GET http://localhost:8280/transport_service > jira-db.json
curl -XPUT 'http://localhost:9200/jira-dev/jira/1' -d #jira-db.json
echo "Daily load completed"

WSO2 ESB: Can we use Call Mediator for Rest Service to post (POST HTTP Method) the xml request?

When I create proxy with send mediator with Rest service Post HTTP Method in HTTP endpoint url. Selected the endpoint as HTTP endpoint on proxy and post the request xml without soap envelop, this perfectly works and get the response in the response window.
But when I use the call mediator with the same HTTP end point url configuration, this does not works. I would like to know can we use call mediator for Post HTTP method? When I use Call mediator for the GET HTTP method which require only query parameters and does not require any request xml this works absolutely fine.
Here is the further information:
However issue is resloved by using the address endpoint in callmediator. When I Invoke the proxy from external Restt client ot Soap UI, it does works. If I use the Try this Service option in wso2 ESB will fail with the results 1. When Soap12 endpoint is selected and 2 when HTTP end point is selected as shown below.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="postIDMPCall"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<property name="ContentType" value="text/xml" scope="axis2" type="STRING"/>
<property name="HTTP_METHOD" value="POST" scope="axis2" type="STRING"/>
<payloadFactory media-type="xml">
<format>
<organizationList xmlns="">
<xml content>
</organizationList>
</format>
<args/>
</payloadFactory>
<header name="_user" scope="transport" value="username"/>
<header name="_password" scope="transport" value="Password"/>
<call blocking="true">
<endpoint>
<address uri="http://<ip-address>:<port>/<resource-path>/UpdateOrganization"
format="rest"/>
</endpoint>
</call>
</inSequence>
</target>
</proxy>
Output: When soap12 endpoint is selected
Though posted the correct xml service does not recorgonize the correct xml format for soap12 endpoint.
FAILURE
Record is not processed successfully. Please Provide valid Request XML
When Http end point is selected
[2016-04-21 12:07:50,179] INFO - HTTPSender Unable to sendViaPost to url[http://://UpdateOrganization/mediate]
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
I think we can't use call mediator for this purpose because call mediator is context unaware mediator.
Your call should already perform a post out the box.
Did you try to set format="pox" if you expect simple xml as a response

How to pick service name in WSO2 using Log Mediator

I am using WSO2 ESB 4.8.1. When i use log mediator, i want it to also log the proxy service name in which log mediator is being used. Is there any property defined in wso2 that i can use?
Problem:
In the following log mediator I am using "Server_IP" and "Server_HOST" property to pick up the Server IP and Server Host name. So is there any property from which i can pick up the service name.
Log Mediaator:
<log level="full" separator="LogMediator" description="LoggerTemplate">
<property name="ServerIP" expression="get-property('SERVER_IP')"/>
<property name="ServerHost" expression="get-property('SERVER_HOST')"/>
</log>
Yes. Use the $ctx:proxy.name expression for your property mediator:
<log level="custom">
<property name="proxyName" expression="$ctx:proxy.name"/>
</log>
Output:
[2015-02-06 06:24:07,161] INFO - LogMediator proxyName = vfsTest

How can I configure WSO2 ESB 4.0.3 to use corporate proxy to access external web services (over HTTP)

I am trying to access external web services (outside of intranet) using WSO2 ESB 4.0.3 but I do not know how to configure the proxy to let the request go outside. I can send SOAP messages over HTTP from my basic Java client app without issues; I could specify teh proxy details using Apache HttpComponents. So, connection details are OK.
I tried:
Editing <transportSender name="http" ... > and specifying parameters like "http.proxyHost" and "http.proxyPort".
Setting up a global parameter <parameter name="Proxy"> ...
Configuring the HTTP Transport Sender and specifying the appropriate parameters.
The best I got was:
ERROR_CODE = 101503, ERROR_MESSAGE = Connection refused or failed for : ...
So, what did I wrong and what should I do instead? Thanks.
Does your proxy server has any authentication? If yes and it uses Basic Auth you need to specify followoing properties before sending out the request..
<property name="Proxy-Authorization" expression="fn:concat('Basic', base64Encode('userName:password'))" scope="transport"/>
<property name="POST_TO_URI" value="true" scope="axis2"/>
The first property sets the Proxy-Authorization HTTP transport header with the base64 encoded user name and password as expected by the HTTP basic authentication.
The second property makes the out-going URL a complete URL understandable by the Proxy Server.
Following is an example proxy config...
<proxy name="StockQuoteProxy" startOnLoad="true">
<target>
<inSequence>
<property name="Proxy-Authorization" expression="fn:concat('Basic ', base64Encode('udayanga:test123'))" scope="transport"/>
<property name="POST_TO_URI" value="true" scope="axis2"/>
<send>
<endpoint>
<address uri="http://www.wso2.com:9000/services/SimpleStockQuoteService"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
</proxy>