In Integration Studio, I am working on generating a new API by taking the query parameter from outside and sending it to an API that runs the query parameter as follows. The query structure of the endpoint I call works as follows.
Integration Studio Call http endpoint:
http://localhost:8080/Energy?q=year>2019;month==1
WSO2 Integration Studio Generated API
http://localhost:8290/Energy/Test?q=year>2019;month==1
This is how I will send the query parameter (year>2019;month==1) that I will get from outside. But it does not accept == character.
I can get the part up to the == statement in the Query parameter, but not the == and beyond.
Below is my sample xml work.
Example Xml:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/Energy" name="Energy" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" url-mapping="/Test">
<inSequence>
<property expression="$url:q" name="uri.var.ep.q" scope="default"
type="STRING"/>
<log>
<property expression="$url:q" name="QueryParameter"/>
</log>
<call>
<endpoint>
<http method="get" uri-template="http://localhost:8080/Energy?q==
{uri.var.ep.q}">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<script language="js"><![CDATA[var data = mc.getPayloadJSON();
mc.setPayloadJSON(JSON.stringify(data));]]></script>
<property name="messageType" scope="axis2" type="STRING"
value="application/json"/>
<jsontransform description="convert to json">
<property name="synapse.commons.json.output.autoPrimitive" value="true"/>
<property name="synapse.commons.enableXmlNullForEmptyElement"
value="false"/>
</jsontransform>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Some characters are reserved when it comes to URI construction. For example according to RFC2396 and RFC3986 following characters are reserved and you are not able to use them as values in query parameters, path parameters, or in the URI itself.
reserved = ";" | "/" | "?" | ":" | "#" | "&" | "=" | "+" |
"$" | ","
If you want to use these special characters you need to use URL encoding to encode the special characters, there are online tools for encoding as well.
In your case, you can use the following URL when calling the API which will allow you to extract the query parameters properly.
http://localhost:8080/Energy?q=year%3E2019%3Bmonth%3D%3D1
Related
I'm using the iterate mediator for calculate the sum of a note variable i tried with the script mediator
but when i send the api in postman for test we takes a long time without answer and i have this error :
ERROR {PassThroughNHttpGetProcessor} - Unable to find axis service for service name : studenttest/getsomme
here is my code:
<resource methods="GET" uri-template="/gettotal">
<inSequence>
<property expression="$url:nom" name="uri.var.nom" scope="default" type="STRING"/>
<call>
<endpoint>
<http method="get" uri-template="http://ITMTNF3RRJSJ:8290/services/studenttest/getsomme?nom={uri.var.nom}">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<property name="it_count" scope="operation" type="STRING" value="0"/>
<iterate expression="//symbols/symbol" sequential="TRUE">
<target>
<sequence>
<property expression="json-eval($.note)" name="note" scope="default" type="STRING"/>
<script language="js"><![CDATA[var note = mc.getProperty('note');
var totalnote =it_count+note;
mc.setProperty('it_count', totalnote);]]></script>
</sequence>
</target>
</iterate>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
This error "Unable to find axis service for service name" is a known issue[1] when a data service is invoked as a Rest service with query parameters in MI-1.2.0 and this is already fixed in MI-1.2.0 with the latest updates. If you have a valid wso2 subscription you can get the latest updates using the Update 2.0 tool[2].
However, you can invoke the data service in soap manner or rest manner without query parameters and check the mediation.
[1] https://github.com/wso2/micro-integrator/issues/2351
[2] https://updates.docs.wso2.com/en/latest/
I am re-factorizing a wso2 project and I wondered how/whether I could do the following. This project is designed to send data to a SOAP Api. In every environment, this API exposes a .wsdl file and the URL and credentials are the only things changing from one environment to another. The most natural thing to do is thus to
create those in the Registry and
load it in the beginning of the job like so
<propertyGroup>
<property expression="get-property('registry', 'gov:/endpoints/sap_constructionSiteUser')" name="sap_constructionSiteUser" scope="default" type="STRING"/>
<property expression="get-property('registry', 'gov:/endpoints/sap_constructionSitePassword')" name="sap_constructionSitePassword" scope="default" type="STRING"/>
<property expression="get-property('registry', 'gov:/endpoints/sap_constructionSiteUrl')" name="uri.var.sap_constructionSiteUrl" scope="default" type="STRING"/>
</propertyGroup>
But I could not find a straightforward way to use this uri.var.sap_constructionSiteUrl in the endpoint definition. The following does not work
<call>
<endpoint>
<wsdl optimize="mtom" uri="{uri.var.sap_constructionSiteUrl}" port="OUVERTURE_CHANTIER" service="OUVERTURE_CHANTIER" statistics="enable">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</wsdl>
</endpoint>
</call>
Looks like uri= only accept plain value. Is there a way I could made this dynamic without writing the entire endpoint in the Registry (the point is to keep things simple for the clients)
[Environment]
wso2ei 6.5.0
====================EDIT========================
I just created a template:
<template name="crm4sap-constructionSiteTemplate" xmlns="http://ws.apache.org/ns/synapse">
<axis2ns488:parameter name="port" xmlns:axis2ns488="http://ws.apache.org/ns/synapse"/>
<axis2ns489:parameter name="service" xmlns:axis2ns489="http://ws.apache.org/ns/synapse"/>
<axis2ns490:parameter name="uri" xmlns:axis2ns490="http://ws.apache.org/ns/synapse"/>
<endpoint name="$name">
<wsdl port="$port" service="$service" uri="$uri">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1.0</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</wsdl>
</endpoint>
</template>
And I call it with
<call>
<endpoint name="constructionSiteEndpoint" template="crm4sap-constructionSiteTemplate">
<axis2ns468:parameter name="port" value="OUVERTURE_CHANTIER" xmlns:axis2ns468="http://ws.apache.org/ns/synapse"/>
<axis2ns469:parameter name="service" value="OUVERTURE_CHANTIER" xmlns:axis2ns469="http://ws.apache.org/ns/synapse"/>
<axis2ns469:parameter name="uri" value="{$ctx:sap_constructionSiteUrl}" xmlns:axis2ns469="http://ws.apache.org/ns/synapse"/>
</endpoint>
</call>
Variable substitution does not seem to occur:
[2020-04-15 12:30:54,032] [] WARN - TemplateEndpointFactory Could not read the WSDL endpoint {$ctx:sap_constructionSiteUrl}
java.net.MalformedURLException: no protocol: {$ctx:sap_constructionSiteUrl}
at java.net.URL.<init>(URL.java:600)
at java.net.URL.<init>(URL.java:497)
at java.net.URL.<init>(URL.java:446)
Looks like a common problem
You can try to template this endpoint and then call the template with the parameters. You can pass dynamic values to the template in the runtime.
https://docs.wso2.com/display/EI650/Endpoint+Template
I was able to do it using the following code in the sequence:
<call-template target="template-for-calling-soap">
<with-param name="url" value="{get-property('soap-uri')}"/>
</call-template>
Where soap-uri is a local entry or a simple property, and the sequence template named template-for-calling-soap takes as parameter the url value and has the following code:
<template name="template-for-calling-soap"
xmlns="http://ws.apache.org/ns/synapse">
<parameter name="url"/>
<sequence>
<property expression="$func:url" name="uri.var" scope="default"
type="STRING"/>
<send>
<endpoint>
<address format="soap11" uri="${uri.var}"/>
</endpoint>
</send>
</sequence>
</template>
What I'm trying to achieve:
Using an Enterprise Integrator API, I want to combine the data from two data service endpoints (call it ORDERS and METADATAS) into a custom object like so:
[
{
Order: {},
Metadata: {}
}, ...
]
The API takes in a single parameter at the moment, USER_ID.
When I run the <call> mediator in blocking mode, I get the following problem:
Current Params: {USER_ID={1,1}, ID=test}
or
Current Params: {USER_ID={test,1}}
When in non-blocking mode, the first call works successfully and the second call can't proceed. It seems it can't access the USER_ID parameter from the URL, nor from the stored property. I thought properties were supposed to persist values?
It should be noted that the values in the logs are 100% accurate (USER_ID property is showing correct value).
INFO {org.apache.synapse.mediators.builtin.LogMediator} - _TEST = 1, _TEST2 = 1, _TEST3 = 1
Here's what I've got thus far for the inSequence:
<resource methods="GET" uri-template="/test?USER_ID={USER_ID}">
<inSequence>
<property expression="get-property('query.param.USER_ID')" name="USER_ID" scope="default" type="STRING"/>
<property expression="$url:USER_ID" name="uri.var.USER_ID" scope="default" type="STRING"/>
<call blocking="true">
<endpoint>
<http method="get" statistics="enable" trace="enable" uri-template="https://localhost:8243/services/ORDERS_DataService/user/{query.param.USER_ID}"/>
</endpoint>
</call>
<log level="custom">
<property expression="get-property('USER_ID')" name="_TEST"/>
<property expression="get-property('query.param.USER_ID')" name="_TEST2"/>
<property expression="get-property('uri.var.USER_ID')" name="_TEST3"/>
</log>
<enrich>
<source clone="false" type="body"/>
<target property="_ORDERS" type="property"/>
</enrich>
<filter regex="200" source="get-property('axis2', 'HTTP_SC')">
<then>
<log level="custom">
<property name="switchlog" value="Case: first call successful"/>
</log>
<call blocking="true">
<endpoint>
<http method="get" statistics="enable" trace="enable" uri-template="https://localhost:8243/services/ORDERS_DataService/metadata/user/{query.param.USER_ID}"/>
</endpoint>
</call>
<enrich>
<source clone="false" type="body"/>
<target property="_METADATAS" type="property"/>
</enrich>
<log level="custom">
<property expression="get-property('_METADATAS')" name="_METADATAS"/>
</log>
</then>
<else/>
</filter>
</inSequence>
</resource>
What have I tried?
Using {USER_ID}, {uri.var.USER_ID}, {$url:USER_ID}, and {query.param.USER_ID} in both of the uri-templates for the <call>s.
Tried non-blocking and blocking mode, getting different results.
My problem is just (for now) with the calling of both sequences and assigning to properties.
I planned to bring them all together with an iterate, and something like the below to map the properties to each of the items in the array I'm looking for:
<!-- Assuming iterate provides _ORDER and _METADATA whilst looping -->
<format>
{
"Order":"$1",
"Metadata":"$2"
}
</format>
<args>
<arg expression="get-property('_ORDER')"/>
<arg expression="get-property('_METADATA')"/>
</args>
And if that doesn't work I was going to evaluate an XSLT transform on the two items, but I haven't thought that far ahead yet, stuck on the two calls not working properly.
I've figured out the answer to the issue. Found this curious line buried in the documentation [1]:
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
Adding it just after grabbing the query parameter works! It does exactly what it says, apparently a Postfix is applied by default. Now to look for a global way to turn that off automatically!
References:
[1] https://docs.wso2.com/display/EI650/Configuring+Specific+Use+Cases
I have a rest end point in WSO2ESB (4.8),I need to read query parameter to set as dynamic payload as the my business ,But i failed to read it due to newer with wso2 ESB.Any help ?
The bellow code 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>
Define a REST API inside ESB and access to query params with get-property('query.param.xxx') or get-property('uri.var.yyy'), sample :
<resource methods="GET" uri-template="/testwso2/{symbol}?arg1={value1}">
get-property('query.param.arg1')
get-property('uri.var.symbol')
I am new to the WSO2 esb. I want to create a api in which i want to add a dynamic parameter from api Url to endpoint url.
My end point url is like http://example.com/api/sync/{session_id}.json
I tried to create api like
<api name="rest" context="/sync">
<resource methods="GET" uri-template="/{id}">
<inSequence>
<log level="full">
<property xmlns:ns="http://org.apache.synapse/xsd"
name="uri.var.session"
expression="get-property('uri.var.id')"
scope="axis2"/>
</log>
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
<send>
<endpoint name="Mecars">
<http trace="enable"
method="get"
uri-template="http://example.com/sync/{+uri.var.session}.json"/>
</endpoint>
</send>
</inSequence>
</resource>
</api>
In log i get the value of uri.var.session But on the endpoint Uri-template it is not appending.
Please guid me how append the {id} value in the api uri-template to end point uri-template?
Check this sample
I recommend you to do string concatenation at property mediator adn use that directly at uri-template, rather adding "variable +.json" at uri-template.
That is;
<property xmlns:ns="http://org.apache.synapse/xsd"
name="uri.var.session"
expression="get-property('uri.var.id')"
scope="axis2"/>
In the above for expression do string concatenation to construct full variable with ".json" ending.
Please remove the '+' symbol from your http end point.Its working fine to me
sample API
<api xmlns="http://ws.apache.org/ns/synapse" name="Elastic Search Using NPI" context="/api/npi/professional/npi.json">
<resource methods="OPTIONS GET" uri-template="/{npi}">
<inSequence>
<log level="full">
<property name="uri.var.npi" expression="get-property('uri.var.npi')"></property>
</log>
<send>
<endpoint>
<http method="get" uri-template="example.com/{uri.var.npi}"></http>
</endpoint>
</send>
</inSequence>
</resource>
</api>
Change the http endpoint uri template like follows.
<http trace="enable" method="get" uri-template="http://example.com/sync/{uri.var.id}.json"></http>
Following is the modified api configuration.
<api xmlns="http://ws.apache.org/ns/synapse" name="rest" context="/sync">
<resource methods="GET" uri-template="/{id}">
<inSequence>
<log level="full">
<property xmlns:ns="http://org.apache.synapse/xsd" name="uri.var.session" expression="get-property('uri.var.id')"></property>
</log>
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"></property>
<send>
<endpoint name="Mecars">
<http trace="enable" method="get" uri-template="http://example.com/sync/{uri.var.id}.json"></http>
</endpoint>
</send>
</inSequence>
</resource>
</api>
You can do the string concatenation at the property mediator as follows.
<property xmlns:ns="http://org.apache.synapse/xsd"
name="uri.var.session"
expression="fn:concat(get-property('uri.var.id'),'.json')"
scope="axis2"/>