WSO2, convert an empty SOAP response to an empty JSON - wso2

I have a EI 6.6.0 service that could return empty response, but they have to be JSONs, and in case there is an empty response
TID: [-1234] [] [2021-08-26 09:03:16,819] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:5be867bf-2210-4ccd-8ecd-97a6078500f8, Direction: response, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>`
the converted response should be {}
I'm using the property
<property name="messageType" value="application/json" scope="axis2"/>
to manage the conversion, but I get an error
TID: [-1234] [] [2021-08-26 09:06:17,135] ERROR {org.apache.synapse.commons.json.JsonUtil} - #writeAsJson. Payload could not be written as JSON. MessageID: urn:uuid:28a3eea3-a226-483a-8d5d-68d359d0fc08
TID: [-1234] [] [2021-08-26 09:06:17,136] ERROR {org.wso2.carbon.integrator.core.json.JsonStreamFormatter} - Error occurred while writing to application/json java.lang.reflect.InvocationTargetException
And if I use
<property name="NO_ENTITY_BODY" value="true" scope="axis2" type="BOOLEAN" />
then the conversion doesn't fail, but it returns nothing.
The following is my output flow:
<log level="full" xmlns="http://ws.apache.org/ns/synapse"/>
<switch source="//soapenv:Body/*[1]" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<case regex="">
<property name="NO_ENTITY_BODY" value="true" scope="axis2" type="BOOLEAN" />
</case>
<default/>
</switch>
<property name="messageType" value="application/json" scope="axis2"/>
<respond/>

You can try the PayloadFactory Mediator
<payloadFactory media-type="json">
<format>{}</format>
<args/>
</payloadFactory>

Related

Can you redirect to a web page based on whether a field exists in a microsoft sql database on wso2?

I have created a REST API that searches a microsoft sql db using a db lookup mediator, I wish to redirect to a web page based on whether or not a UserCode field exists in my database. I do not receive an error when attempting to test my API but it does not redirect either. Please see my API code below that I have created on EI.
<api xmlns="http://ws.apache.org/ns/synapse" name="DBLookupAPI" context="/dblookup">
<resource methods="GET" uri-template="/{UserCode}">
<inSequence>
<log level="custom">
<property name="Value" expression="get-property('uri.var.UserCode')"/>
</log>
<dblookup>
<connection>
<pool>
<driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver>
<url>jdbc:sqlserver://10.1.1.111\test;databaseName=UserDB</url>
<user>admin</user>
<password>admin</password>
</pool>
</connection>
<statement>
<sql>select UserCode from UserDB.dbo.Users where UserCode =?;</sql>
<parameter expression="get-property('uri.var.UserCode ')" type="CHAR"/>
<result name="foundnr" column="UserCode "/>
</statement>
</dblookup>
<log level="custom">
<property name="Value" expression="get-property('foundnr')"/>
</log>
<filter source="boolean(get-property('foundnr'))" regex="true">
<then>
<log>
<property name="Message" value="Name Exists Lets redirect"/>
</log>
<property name="HTTP_SC" value="302"/>
<property name="Location" value="https://wso2.com/"/>
</then>
<else>
<log>
<property name="Message" value="Name Does Not Exist Lets redirect"/>
</log>
<property name="HTTP_SC" value="302"/>
<property name="Location" value="https://www.youtube.com/"/>
</else>
</filter>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
My wso2-ei-api log says
TID: [-1234] [2022-11-10 15:57:12,665] INFO {API_LOGGER.DBLookupAPI} - Value = Sash18
TID: [-1234] [2022-11-10 15:57:12,727] INFO {API_LOGGER.DBLookupAPI} - Value = Sash18
TID: [-1234] [2022-11-10 15:57:12,728] INFO {API_LOGGER.DBLookupAPI} - To: /dblookup/Sash18, MessageID: urn:uuid:e37541a7-eabd-4d70-8bde-6f9dfc2ebfee, Direction: request, Message = Name Exists Lets redirect
TID: [-1234] [2022-11-10 15:57:19,067] INFO {API_LOGGER.DBLookupAPI} - Value = No
TID: [-1234] [2022-11-10 15:57:19,120] INFO {API_LOGGER.DBLookupAPI} - Value = null
TID: [-1234] [2022-11-10 15:57:19,121] INFO {API_LOGGER.DBLookupAPI} - To: /dblookup/No, MessageID: urn:uuid:6fd1a264-5f1b-45d8-bcc4-b52a079abbd3, Direction: request, HTTP_SC = 302, Location = https://www.youtube.com/
First I enter Sash18, which is a UserCode in my db and then I enter no which is not a UserCode in my db.
I have even attempted to create an API calling a data service instead of using a db lookup mediator and this approach did not redirect either. (I have this posted as another question)
The results of the DBLookupMediator will be set to a property called foundnr. So in your FileterMediator you need to check the availability of this property.
<filter source="boolean(get-property('foundnr'))" regex="true">
<then>
<log>
<property name="Message" value="Name Exists Lets redirect"/>
</log>
<property name="HTTP_SC" value="302" scope="axis2" type="STRING"/>
<property name="Location" value="https://wso2.com/" scope="transport" type="STRING"/>
</then>
<else>
<log>
<property name="HTTP_SC" value="302"/>
<property name="Location" value="https://www.youtube.com/"/>
</log>
</else>
</filter>

How can I get the Property from OnComplete AggregateMediator in RESTful API WSO2EI 6.2.0?

I've tried several ways to get The Property from OnComplete AggregateMediator and used it in Expression prop of ForEach Mediator, but none of these is suceed.
I've searched in google too, but no luck at all.
Here is my RESTful API (in short mode):
This is inSequence section
<api xmlns="http://ws.apache.org/ns/synapse" context="/path/to/context" name="NamedAPI">
<resource methods="POST" protocol="http">
<inSequence>
<property expression="count(//parameter/objects)" name="count" scope="default" type="STRING"/>
<iterate expression="//parameter/objects" id="iterate1" sequential="true">
<target>
<sequence>
<property expression="//objects/text()" name="element1" scope="default" type="STRING"/>
<sequence key="getIdOfElement1"/>
<property expression="json-eval($.result.id)" name="el1id" scope="default" type="STRING"/>
<payloadFactory media-type="xml">
<format>
<ids xmlns="">
<id>$1</id>
</ids>
</format>
<args>
<arg evaluator="xml" expression="get-property('el1id')"/>
</args>
</payloadFactory>
</sequence>
</target>
</iterate>
<aggregate id="iterate1">
<completeCondition timeout="10">
<messageCount max="-1" min="{get-property('count')}"/>
</completeCondition>
<onComplete expression="//ids">
<property expression="$body" name="message" scope="operation" type="OM"/>
</onComplete>
</aggregate>
<payloadFactory media-type="xml">
<format>
<result xmlns="">$1</result>
</format>
<args>
<arg evaluator="xml" expression="get-property('operation','message')"/>
</args>
</payloadFactory>
<send>
<endpoint key="NamedEP"/>
</send>
</inSequence>
This is OutSequence section:
<outSequence>
<property expression="get-property('operation', 'message')" name="IDs"/>
<log level="custom">
<property expression="//ids" name="========== LIST IDs =========="/>
</log>
<foreach expression="//ids" id="foreach1">
<sequence>
<log level="custom">
<property expression="//id" name="========== ID =========="/>
</log>
<log level="full"/>
<dbreport>
<connection>
<pool>
<dsName>A_DS</dsName>
</pool>
</connection>
<statement>
<sql>INSERT INTO "table" ("field1", "id") VALUES (?,?)</sql>
<parameter expression="get-property('field1')" type="VARCHAR"/>
<parameter expression="//id" type="INTEGER"/>
</statement>
</dbreport>
</sequence>
</foreach>
<payloadFactory media-type="json">
<format>
[{ "field1" : "$1" }]
</format>
<args>
<arg evaluator="xml" expression="get-property('field1')"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<property expression="json-eval($.)" name="response" scope="default" type="STRING"/>
<send/>
</outSequence>
This is FaultSequence Section
<faultSequence>
<payloadFactory media-type="json">
<format>
[{ "fault" : { "responsecode" : "999", "responsedesc" : "General error", "errordetails" : "$1" } }]
</format>
<args>
<arg evaluator="xml" expression="$ctx:ERROR_MESSAGE"/>
</args>
</payloadFactory>
<respond/>
<send/>
</faultSequence>
</resource>
</api>
I've Tried this:
<foreach expression="//ids" id="foreach1">
it does not work. The DBReport not executed in ForEach Mediator, so does the Log Mediator
I've Tried this:
<foreach expression="get-property('operation', 'message')" id="foreach1">
The WSO2EI showed me an error
I've tried to move all of the Mediator (ForEach and DBReport) in OutSequence Section to the InSequence Section but it's not worked too.
Please, help me.
Any help will be appreciated.
Thanks in advance.
Here is the log as per #Arunan's Comment
TID: [-1234] [] [2019-08-21 10:00:06,176] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== START COUNTER ========== = 1 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,176] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== START ITERATE NO : = 2.0 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,177] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== NIP FROM ITERATE : = 198910202001020001 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,180] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== START ITERATE NO : = 2.0 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,181] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== NIP FROM ITERATE : = 199509142005010001 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,230] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== RPID FROM SEQUENCE IN ITERATE ========== = 3 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,230] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== RPID FROM SEQUENCE IN ITERATE ========== = 1 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,262] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== EXIST RICE DOCUMENT ========== = 0 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,348] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== LIST RPIDs ========== = {org.apache.synapse.mediators.builtin.LogMediator}
Alhamdulillah, I've tried my best, and It's worked Perfectly.
How to share the messaging between InSequence and OutSequence (in my case: from Aggregate Mediator inside inSequence section to Expression ForEach Mediator inside OutSequence section).
You must declare new property, and get the value from message property, like:
<property expression="get-property('operation', 'message')" name="rpidList" scope="default" type="OM"/>
And, in the ForEach Expression, you give a code below
<foreach expression="$ctx:rpidList//rpids" id="foreach1">
Thanks for all.
And Thank you StackOverflow.com

After call to a WebService set response value in property to reuse it

Following a service call through the mediator call, I try to retrieve a value in the response to reuse it in subsequent calls.
The body is well valued, but against the xpath me never return value.
Extract of the XML file
<log description="LogApresAppelALAuthentication" level="full"/>
<property description="Get body response Auth" expression="$body" name="bodyRespAuth" scope="default" type="OM" />
<log>
<property expression="$ctx:bodyRespAuth" name="bodyRespAuth"/>
</log>
<property description="Get Token CS" expression="$ctx:bodyRespAuth//AuthenticateUserResult/text()" name="tokenCS" scope="default" type="STRING" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Core.service.livelink.opentext.com" xmlns:ns="http://org.apache.synapse/xsd"/>
<log>
<property expression="$ctx:tokenCS" name="tokenCS"/>
</log>
Log :
MessageID: urn:uuid:97a99ef0-cfb3-4d14-9013-20ee8bb89e6d, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><AuthenticateUserResponse xmlns="urn:Core.service.livelink.opentext.com"><AuthenticateUserResult>kzE3hcjoG6lYIn6yglLGwYXNivGpCGMDoJWcetPTEj9EiU%2BSGaTqyxZ9azmTc%2BMdGbKcJzCsSAz0epdXkZkP%2BeIazTcvQtu8</AuthenticateUserResult></AuthenticateUserResponse></soapenv:Body></soapenv:Envelope>
MessageID: urn:uuid:97a99ef0-cfb3-4d14-9013-20ee8bb89e6d, Direction: request, bodyRespAuth = <soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><AuthenticateUserResponse xmlns="urn:Core.service.livelink.opentext.com"><AuthenticateUserResult>kzE3hcjoG6lYIn6yglLGwYXNivGpCGMDoJWcetPTEj9EiU%2BSGaTqyxZ9azmTc%2BMdGbKcJzCsSAz0epdXkZkP%2BeIazTcvQtu8</AuthenticateUserResult></AuthenticateUserResponse></soapenv:Body>
MessageID: urn:uuid:97a99ef0-cfb3-4d14-9013-20ee8bb89e6d, Direction: request, tokenCS =
I used several possible combinations for the xpath but each time I have no value in tokencs.
Do you have an idea ?
I find solution
<property description="Get Token CS" expression="$body//*/urn:AuthenticateUserResult/text()" name="tokenCS" scope="default" type="STRING" xmlns:urn="urn:Core.service.livelink.opentext.com" />
I have my value

Why in WSO2 ESB I can't create a new property that is the concatenation of another property and a fixed string? I obtain null as result

I am pretty new in WSO2 ESB and I have the following problem. I have a simple POST API that receives a JSON payload. I correctly extract the JSON content into properties.
Then I have to create a new property containing the content of one of the previous properties (retrieved from the JSON document) and I have to concatenatet a fixed string to its content.
So my API is:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/meteo" name="meteo_data_population_insert" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" protocol="http" uri-template="/forecast">
<inSequence>
<log level="full"/>
<log description="Log" level="custom">
<property name="message" value="meteo_data_population_insert START !!!"/>
</log>
<property expression="json-eval($.forecast_date)" name="forecast_date" scope="default" type="STRING"/>
<property expression="json-eval($.morning.weather.min_temp)" name="morning_min_temp" scope="default" type="STRING"/>
<log level="custom">
<property expression="$ctx:forecast_date" name="forecast_date"/>
</log>
<log level="custom">
<property expression="$ctx:morning_min_temp" name="morning_min_temp"/>
</log>
<property name="forecast_date_CONCAT" expression="fn:concat($ctx:forecast_date, '_morning')" scope="operation" type="STRING"/>
<log level="custom">
<property expression="$ctx:forecast_date_CONCAT" name="forecast_date_CONCAT"/>
</log>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
As you can see I am retrieving from the JSON payload the value of the forecast_date field:
<property expression="json-eval($.forecast_date)" name="forecast_date" scope="default" type="STRING"/>
It works fine (I can see it into the log), then I want to create a new property that start with the content of this forecast_date and concatenate to it the _morning string.
So I tried to do in this way:
<property name="forecast_date_CONCAT" expression="fn:concat($ctx:forecast_date, '_morning')" scope="operation" type="STRING"/>
<log level="custom">
<property expression="$ctx:forecast_date_CONCAT" name="forecast_date_CONCAT"/>
</log>
The problem is that in the log I obtain this result:
TID: [-1234] [] [2018-03-08 16:03:46,882] INFO {org.apache.synapse.mediators.builtin.LogMediator} - message = meteo_data_population_insert START !!! {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2018-03-08 16:03:46,883] INFO {org.apache.synapse.mediators.builtin.LogMediator} - forecast_date = 2018-03-14 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2018-03-08 16:03:46,883] INFO {org.apache.synapse.mediators.builtin.LogMediator} - morning_min_temp = 24 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2018-03-08 16:03:46,884] INFO {org.apache.synapse.mediators.builtin.LogMediator} - forecast_date_CONCAT = null {org.apache.synapse.mediators.builtin.LogMediator}
So as you can see I am correctly retrieving the forecast_date value but when I try to create the new forecast_date_CONCAT property concatenating this value with the _morning string it doesn't work and I obtain null as value of this new propery.
Why? What is wrong in my code? What am I missing? How can I fix this issue?
Solve by myself in this way:
<property expression="fn:concat(get-property('forecast_date'), '_morning')" name="forecast_date_CONCAT" scope="default" type="STRING"/>
<log level="custom">
<property expression="$ctx:forecast_date_CONCAT" name="forecast_date_CONCAT"/>
</log>

Why am I obtaining this error when I try to perform a DSS query from my ESB API flow? The endpoint reference (EPR) for the Operation not found

I am pretty new in WSO2 EI and I am finding some problem trying to call a DSS service from an API defined in my ESB flow.
I have done in this way:
1) Into the agrimarketprice-dss.dbs file related to my DSS service I have this operation:
<operation name="GetCommodityDetails">
<call-query href="SelectCommodityDetails">
<with-param name="commodity_details_id" query-param="commodity_details_id"/>
</call-query>
</operation>
that calls a query having id=commodity_details_id. It works fine, I tested it with the Try It tool and I obtain the expected result set.
2) Then I have defined this API defined by this ESB flow:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/commodity_details" name="commodity_details" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" protocol="http" uri-template="/{commodityId}">
<inSequence>
<property expression="get-property('uri.var.commodityId')" name="commodityId" scope="default" type="STRING"/>
<log level="custom"/>
<log description="commodity_details" level="custom" separator="-">
<property name="commodity_details" value="'commodity_details START'"/>
</log>
<log level="custom">
<property expression="$ctx:commodityId" name="COMMODITY ID"/>
</log>
<property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
<payloadFactory media-type="xml">
<format>
<ds:GetCommodityDetails xmlns:ds="http://ws.wso2.org/dataservice">
<ds:commodity_details_id>$1</ds:commodity_details_id>
</ds:GetCommodityDetails>
</format>
<args>
<arg evaluator="xml" expression="$ctx:commodityId" xmlns:ds="http://ws.wso2.org/dataservice" xmlns:ns="http://org.apache.synapse/xsd"/>
</args>
</payloadFactory>
<header name="Action" scope="default" value="urn:GetCommodityDetails"/>
<call>
<endpoint key="agrimarketprice_Endpoint"/>
</call>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
As you can see in the previous ESB flow I am trying to call the previous previous operation defined into my DSS service in this way:
<property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
<payloadFactory media-type="xml">
<format>
<ds:GetCommodityDetails xmlns:ds="http://ws.wso2.org/dataservice">
<ds:commodity_details_id>$1</ds:commodity_details_id>
</ds:GetCommodityDetails>
</format>
<args>
<arg evaluator="xml" expression="$ctx:commodityId" xmlns:ds="http://ws.wso2.org/dataservice" xmlns:ns="http://org.apache.synapse/xsd"/>
</args>
</payloadFactory>
<header name="Action" scope="default" value="urn:GetCommodityDetails"/>
<call>
<endpoint key="agrimarketprice_Endpoint"/>
</call>
So I am creating a payload containing the retrieved ID represented by the $ctx:commodityId (it contains the correct value because I logged it). Then I set the header with the name of the operation that have to be executed ("urn:GetCommodityDetails"). Finnaly I perform the call toward the agrimarketprice_Endpoint that contains the details of the previous DSS service, this is the content:
<?xml version="1.0" encoding="UTF-8"?>
<endpoint name="agrimarketprice_Endpoint" xmlns="http://ws.apache.org/ns/synapse">
<address uri="http://localhost:8280/services/agrimarketprice-dss"/>
</endpoint>
This endpoint is correct because I used it for another query in another API (but it have a different logic because in this other query I am extracting the parameters from a JSON document).
The provlem is that when I call my API I am obtaining the following error message into the Carbon log (I think when it try to perform the call that execute my query):
TID: [-1234] [] [2017-10-03 11:55:16,574] INFO {org.apache.synapse.mediators.builtin.LogMediator} - {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2017-10-03 11:55:16,574] INFO {org.apache.synapse.mediators.builtin.LogMediator} - commodity_details = 'commodity_details START' {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2017-10-03 11:55:16,575] INFO {org.apache.synapse.mediators.builtin.LogMediator} - COMMODITY ID = 1 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2017-10-03 11:55:16,597] INFO {org.apache.synapse.core.axis2.TimeoutHandler} - This engine will expire all callbacks after GLOBAL_TIMEOUT: 120 seconds, irrespective of the timeout action, after the specified or optional timeout {org.apache.synapse.core.axis2.TimeoutHandler}
TID: [-1234] [] [2017-10-03 11:55:16,637] ERROR {org.apache.axis2.engine.AxisEngine} - The endpoint reference (EPR) for the Operation not found is /services/agrimarketprice-dss/1 and the WSA Action = null. If this EPR was previously reachable, please contact the server administrator. {org.apache.axis2.engine.AxisEngine}
org.apache.axis2.AxisFault: The endpoint reference (EPR) for the Operation not found is /services/agrimarketprice-dss/1 and the WSA Action = null. If this EPR was previously reachable, please contact the server administrator.
at org.apache.axis2.engine.DispatchPhase.checkPostConditions(DispatchPhase.java:102)
at org.apache.axis2.engine.Phase.invoke(Phase.java:329)
at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:261)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:167)
at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:326)
at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:158)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
TID: [-1234] [] [2017-10-03 11:55:16,642] ERROR {org.apache.synapse.transport.passthru.ServerWorker} - Error processing GET request for : /services/agrimarketprice-dss/1 {org.apache.synapse.transport.passthru.ServerWorker}
org.apache.axis2.AxisFault: The endpoint reference (EPR) for the Operation not found is /services/agrimarketprice-dss/1 and the WSA Action = null. If this EPR was previously reachable, please contact the server administrator.
at org.apache.axis2.engine.DispatchPhase.checkPostConditions(DispatchPhase.java:102)
at org.apache.axis2.engine.Phase.invoke(Phase.java:329)
at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:261)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:167)
at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:326)
at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:158)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
TID: [-1] [] [2017-10-03 11:58:16,778] INFO {org.apache.synapse.transport.passthru.SourceHandler} - Writer null when calling informWriterError {org.apache.synapse.transport.passthru.SourceHandler}
TID: [-1] [] [2017-10-03 11:58:16,780] WARN {org.apache.synapse.transport.passthru.SourceHandler} - Connection time out after request is read: http-incoming-6 Socket Timeout : 180000 Remote Address : /168.202.253.227:62418 {org.apache.synapse.transport.passthru.SourceHandler}
It seems to me that this error should be related to this log information:
The endpoint reference (EPR) for the Operation not found is /services/agrimarketprice-dss/1 and the WSA Action = null
It seems that it is tryng to append the passed id (1) to the agrimarketprice-dss (that is the service name) ignorning the operation (that is GetCommodityDetails and that I specified in the header).
So what is wrong? What am I missing? How can I try to fix this error?
EDIT-1: I tried another way: the API doesn't retrieve the commodity_id from the URL path but from a JSON document like this in the request:
{
"commodity_id": 1
}
So, changing the API in this way it works fine, the query is correctly performed (but I need to retrieve the commodity_id from the URL and use it as query parameter (so it could be only a workaround):
<?xml version="1.0" encoding="UTF-8"?>
<api context="/commodity_details" name="commodity_details" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" protocol="http" uri-template="/">
<inSequence>
<log level="full"/>
<log level="custom">
<property expression="json-eval($.commodity_id)" name="Commodity ID"/>
</log>
<property expression="json-eval($.commodity_id)" name="CommodityId" scope="default" type="STRING"/>
<property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
<payloadFactory media-type="xml">
<format>
<ds:GetCommodityDetails xmlns:ds="http://ws.wso2.org/dataservice">
<ds:commodity_details_id>$1</ds:commodity_details_id>
</ds:GetCommodityDetails>
</format>
<args>
<arg evaluator="json" expression="$.commodity_id"/>
</args>
</payloadFactory>
<header name="Action" scope="default" value="urn:GetCommodityDetails"/>
<call>
<endpoint key="agrimarketprice_Endpoint"/>
</call>
<send/>
</inSequence>
<outSequence>
<send/>
</outSequence>
<faultSequence/>
</resource>
</api>
So in this way the DSS service is correctly called, the query performed and the API send back to the client the expected output.
But why retrieving the ID from the JSON document in the POST request it works fine but it doesn't work retrieving it from the URL?
Set the soapAction header as below before the call mediator. You can verify whether the SOAPAction header has been set in the request to dataservice by enabling wirelogs
<property name="SOAPAction" scope="transport" value="urn:GetCommodityDetails"/>