I have created an API in esb like this snippet:
<api xmlns="http://ws.apache.org/ns/synapse" name="contact_v1"
<resource methods="GET" uri-template="/contact-by-email?email={query.param.email}" inSequence="crm_contact-by-email_v1" outSequence="crm_contact-by-email_v1" faultSequence="crm_contact-by-email-error_v1"/>
</api>
In my sequence I retrieve the request param, email, like that
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="crm_contact-by-email_v1" xmlns="http://ws.apache.org/ns/synapse">
<in>
<script language="js"><![CDATA[try {
var randomnumber1=Math.floor((Math.random() * 10000) + 1);
mc.setProperty("sessionnumber", randomnumber1.toString());
} catch(e) {
}]]></script>
<property expression="$axis2:REST_URL_POSTFIX" name="myURL"
scope="default" type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
<script language="js"><![CDATA[try {
var log = mc.getServiceLog();
var email = mc.getProperty('query.param.email');
log.info("emailxxxxxx "+email);
} catch(e) {}]]></script>
</in>
<out>
<send/>
<drop/>
</out>
</sequence>
When I make a request with an encoding email like that
test%40test.com
it works witout problem.
But when I make a request with
test#test.com
it display this error
<tp:fault xmlns:tp="https://xxxxxxx.com/"><tp:code>404</tp:code><tp:type>Status report</tp:type><tp:message>Not Found</tp:message><tp:description>The requested resource (//contact-by-email?email=test#test.com) is not available.</tp:description></tp:fault>
Would you have any idea
Best regards
Characters as # are reserved characters for delimiters in the RFC specification for URI-Templates (I can explain more if you are interested). Therefore, in order to allow # as the value for email parameter, define the uri-template with {+query.param.email} as below.
<api xmlns="http://ws.apache.org/ns/synapse" name="contact_v1"
<resource methods="GET" uri-template="/contact-by-email?email={+query.param.email}" inSequence="crm_contact-by-email_v1" outSequence="crm_contact-by-email_v1" faultSequence="crm_contact-by-email-error_v1"/>
</api>
Related
Product Version: WSO2-EI-6.3
I have created a data service to retrieve data as a JSON like below format.
{
"Employees":{
"Employee":[
{
"EmployeeNumber":"1"
},
{
"EmployeeNumber":"2"
}
]
}
}
Find below the sequence used to create the data service in EI.
<data name="RDBMSDataService" transports="http https local">
<config enableOData="false" id="DataSource">
<property name="driverClassName">com.mysql.jdbc.Driver</property>
<property name="url">jdbc:mysql://localhost:3306/Employees</property>
<property name="username">root</property>
<property name="password">1234</property>
</config>
<query id="SelectAllEmployees" useConfig="DataSource">
<sql>select EmployeeNumber from Employees</sql>
<result outputType="json">{
"Employees":{
"Employee":[
{
"EmployeeNumber":"$EmployeeNumber"
}
]
}
}</result>
</query>
<operation name="AllEmployees">
<call-query href="SelectAllEmployees"/>
</operation>
</data>
But Still, it gives the XML mapped output as below.
<Employees xmlns="http://ws.wso2.org/dataservice/SelectAllEmployees">
<Employee>
<EmployeeNumber>1</EmployeeNumber>
</Employee>
<Employee>
<EmployeeNumber>2</EmployeeNumber>
</Employee>
</Employees>
Have I been working on it days ago?
What I suggest you to do is. In your client side pass the following header:
'Accept':'application/json'
enter image description here
Then:
enter image description here
I try to create an automatic JIRA problem reporting (in some FAULT sequences.
I make a JSON payload for JIRA APIs what works just fine for text.
I would like to however report to JIRA a SOAP request and response whereby I could investigate on the issue.
my question is how can I create a JSON payload with text containing XML in it?
I get this exception in WSO2 ESB
[2016-09-18 21:46:31,774] ERROR - NativeWorkerPool Uncaught exception
java.lang.Error: Error: could not match input
at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonScanner.zzScanError(JsonScanner.java:530)
at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonScanner.yylex(JsonScanner.java:941)
payload which I want to generate
<payloadFactory description="" media-type="json">
<format>
{
"fields": {
"project":
{
"key": "$1"
},
"summary": "$2",
"description": "$3",
"issuetype": { "name": "$4" }
}
}
</format>
<args>
<arg evaluator="xml" expression="$func:projectKey"/>
<arg evaluator="xml" expression="$func:summary"/>
<arg evaluator="xml" expression="$func:description"/>
<arg evaluator="xml" expression="$func:issueType"/>
</args>
</payloadFactory>
and I want to send some text containing XML into the parameter $func:description. When I sent only poor XML into the $func:description, the payload Factory transferred into into JSON what is not needed in this case, the the XML is supposed to be a text - the message
for the completeness to get the XML message I used
<property expression="$body" name="request"
scope="default" type="STRING"/>
call the end-point
<property expression="$body" name="response"
scope="default" type="STRING"/>
and I need to know bind "request" + "response" into $func:description
If the XML is well-formed you can simply set messageType property to application/json and do the conversion automatically. Refer this for more details.
Or else you can use the payload Factory mediator or Enrich mediator to custom build your Json.
create the payload with the XML structure you like.
use JS script mediator to modify one node as CDATA.
change the content type.
My proxy config, please do the change you need for your requirement:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="XMLinsideJSON"
transports="http https"
startOnLoad="true">
<target>
<inSequence>
<property name="BOK" expression="//*[1]" type="OM" scope="default"/>
<enrich>
<source type="inline" clone="true">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<fields xmlns="">
<summary xmlns=""/>
<project xmlns=""/>
<description xmlns=""/>
<issuetype xmlns="">
<name xmlns=""/>
</issuetype>
</fields>
</soapenv:Body>
</soapenv:Envelope>
</source>
<target type="envelope"/>
</enrich>
<script language="js">
importPackage(Packages.org.apache.axiom.om);
var elem= mc.getEnvelope().getBody().getFirstElement().getFirstElement();
var myText = elem.getOMFactory().createOMText(elem, mc.getProperty("BOK"), OMNode.CDATA_SECTION_NODE);
elem.addChild(myText)
</script>
<property name="messageType" scope="axis2" value="application/json"/>
<respond/>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
</proxy>
My request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<payload>
<response>
<data>AAA</data>
</response>
</payload>
</soapenv:Body>
</soapenv:Envelope>
My response:
{"fields":{"summary":"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Body>\n <payload>\n <response>\n <data>AAA</data>\n </response>\n </payload>\n </soapenv:Body></soapenv:Envelope>","project":null,"description":null,"issuetype":{"name":null}}}
Since WSO2 5.0 supports WebSockets, I have written a simple app following by tutorials:
WebSocket Transport
Sending a Message from a WebSocket Client to an HTTP Endpoint
Here's my source view output from WSO2:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
<registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">
<parameter name="cachableDuration">15000</parameter>
</registry>
<taskManager provider="org.wso2.carbon.mediation.ntask.NTaskTaskManager"/>
<sequence name="fault">
<!-- Log the message at the full log level with the ERROR_MESSAGE and the ERROR_CODE-->
<log level="full">
<property name="MESSAGE" value="Executing default 'fault' sequence"/>
<property expression="get-property('ERROR_CODE')" name="ERROR_CODE"/>
<property expression="get-property('ERROR_MESSAGE')" name="ERROR_MESSAGE"/>
</log>
<!-- Drops the messages by default if there is a fault -->
<drop/>
</sequence>
<sequence name="main">
<in>
<!-- Log all messages passing through -->
<log level="full"/>
<!-- ensure that the default configuration only sends if it is one of samples -->
<!-- Otherwise Synapse would be an open proxy by default (BAD!) -->
<filter regex="http://localhost:9000.*" source="get-property('To')">
<!-- Send the messages where they have been sent (i.e. implicit "To" EPR) -->
<send/>
</filter>
</in>
<out>
<send/>
</out>
<description>The main sequence for the message mediation</description>
</sequence>
<sequence name="outDispatchSeq">
<log level="full">
<property name="MESSAGE" value="Executing outDispatchSeq -------------- "/>
</log>
<respond/>
</sequence>
<sequence name="dispatchSeq">
<payloadFactory media-type="json">
<format>$1</format>
<args>
<arg evaluator="xml" expression="get-property('body')"/>
</args>
</payloadFactory>
<property expression="json-eval($.testPropertyName)"
name="testPropertyName" scope="default" type="STRING"/>
<log level="full">
<property name="MESSAGE" value="Executing dispatchSeq -------------- "/>
</log>
</sequence>
<!-- You can add any flat sequences, endpoints, etc.. to this synapse.xml file if you do
*not* want to keep the artifacts in several files -->
<inboundEndpoint name="test" onError="fault" protocol="ws"
sequence="dispatchSeq" suspend="false">
<parameters>
<parameter name="inbound.ws.port">9091</parameter>
<parameter name="ws.outflow.dispatch.sequence">outDispatchSeq</parameter>
<parameter name="ws.client.side.broadcast.level">0</parameter>
<parameter name="ws.outflow.dispatch.fault.sequence">fault</parameter>
<parameter name="content.type">application/json</parameter>
</parameters>
</inboundEndpoint>
</definitions>
Then I create simple JavaScript code to connect with WebSocket and send simple JSON data:
function connect() {
webSocket = new WebSocket('ws://localhost:9091/');
webSocket.onopen = function(e) {
console.log('connected: ' + webSocket);
};
// some logic here...
webSocket.send("{ \"testPropertyName\": \"testValue\"}");
}
But by all the time, WSO2 cannot parse my JSON object. I am getting errors like:
DEBUG - PayloadFactoryMediator #mediate. Transformed payload format>>>
ERROR - SynapseJsonPath #stringValueOf. Error evaluating JSON Path <$.testPropertyName>. Returning empty result. Error>>> invalid path
INFO - LogMediator To: , MessageID: urn:uuid:93c8c0bc-2a77-4895-a852-1267e21f2044, Direction: request, MESSAGE = Executing dispatchSeq -------------- , Payload: {}
DEBUG - PayloadFactoryMediator #mediate. Transformed payload format>>>
ERROR - SynapseJsonPath #stringValueOf. Error evaluating JSON Path <$.testPropertyName>. Returning empty result. Error>>> invalid path
INFO - LogMediator To: , MessageID: urn:uuid:828216c3-a3ba-476a-886d-302a62e117be, Direction: request, MESSAGE = Executing dispatchSeq -------------- , Payload: {}
UPDATE:
After changing loggin to:
log4j.logger.org.apache.synapse.transport.http.wire=DEBUG
and adding loggig just after payloadFactory:
<sequence name="dispatchSeq">
<payloadFactory media-type="json">
<format>$1</format>
<args>
<arg evaluator="xml" expression="get-property('body')" />
</args>
</payloadFactory>
<log level="full" />
<property expression="json-eval($.testPropertyName)" name="testPropertyName" scope="default" type="STRING" />
<log level="full">
<property name="MESSAGE" value="Executing dispatchSeq -------------- " />
</log>
</sequence>
WSO2 is logging following output:
DEBUG - PayloadFactoryMediator #mediate. Transformed payload format>>>
INFO - LogMediator To: , MessageID: urn:uuid:7a04df37-b3c0-47a0-9ea1-78df460aec0a, Direction: request, Payload: {}
ERROR - SynapseJsonPath #stringValueOf. Error evaluating JSON Path <$.testPropertyName>. Returning empty result. Error>>> invalid path
INFO - LogMediator To: , MessageID: urn:uuid:7a04df37-b3c0-47a0-9ea1-78df460aec0a, Direction: request, MESSAGE = Executing dispatchSeq -------------- , Payload: {}
DEBUG - PayloadFactoryMediator #mediate. Transformed payload format>>>
INFO - LogMediator To: , MessageID: urn:uuid:9ef7732c-b196-435e-a800-5d98d670b11a, Direction: request, Payload: {}
ERROR - SynapseJsonPath #stringValueOf. Error evaluating JSON Path <$.testPropertyName>. Returning empty result. Error>>> invalid path
INFO - LogMediator To: , MessageID: urn:uuid:9ef7732c-b196-435e-a800-5d98d670b11a, Direction: request, MESSAGE = Executing dispatchSeq -------------- , Payload: {}
UPDATE
I removed payloadFactory like:
<sequence name="dispatchSeq">
<log level="full" />
<property expression="json-eval($.testPropertyName)" name="testPropertyName" scope="default" type="STRING" />
<log level="full">
<property name="MESSAGE" value="Executing dispatchSeq -------------- " />
</log>
</sequence>
WSO2 logs show me:
INFO - LogMediator To: , MessageID: urn:uuid:db00d7aa-69c8-4de6-8140-91169183c3d6, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>
WARN - SynapseJsonPath Json Payload is empty.
INFO - LogMediator To: , MessageID: urn:uuid:db00d7aa-69c8-4de6-8140-91169183c3d6, Direction: request, MESSAGE = Executing dispatchSeq -------------- , Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>
INFO - LogMediator To: , MessageID: urn:uuid:19816ec6-c255-4edf-adae-cca83dbd2008, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>
WARN - SynapseJsonPath Json Payload is empty.
INFO - LogMediator To: , MessageID: urn:uuid:19816ec6-c255-4edf-adae-cca83dbd2008, Direction: request, MESSAGE = Executing dispatchSeq -------------- , Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>
UPDATE
Modified dispatchSeq:
<sequence name="dispatchSeq">
<log level="full" />
<property expression="json-eval($.testPropertyName)" name="testPropertyName" scope="default" type="STRING" />
<log level="full">
<property name="MESSAGE" value="Executing dispatchSeq -------------- " />
<property expression="get-property('websocket.source.handshake.present')" name="websocket.source.handshake.present.value" scope="default" type="STRING"/>
</log>
</sequence>
WSO2 output is:
INFO - LogMediator To: , MessageID: urn:uuid:5cc82e8d-6638-4cca-97f7-ac4f96877f85, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>
WARN - SynapseJsonPath Json Payload is empty.
INFO - LogMediator To: , MessageID: urn:uuid:5cc82e8d-6638-4cca-97f7-ac4f96877f85, Direction: request, MESSAGE = Executing dispatchSeq -------------- , websocket.source.handshake.present.value = true, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>
INFO - LogMediator To: , MessageID: urn:uuid:81b0e2bd-4e79-48bd-b177-f49fd5664c0a, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>
WARN - SynapseJsonPath Json Payload is empty.
INFO - LogMediator To: , MessageID: urn:uuid:81b0e2bd-4e79-48bd-b177-f49fd5664c0a, Direction: request, MESSAGE = Executing dispatchSeq -------------- , websocket.source.handshake.present.value = null, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>
Do you know what else I am missing?
I will appreciate any code examples.
Thank you very much!
PayloadFactory mediator I’m using JSON format string. The Problem is, when I enable the following lines in /repository/conf/axis2/axis2.xml, POST request works fine, but GET request produce error message.
<!--messageFormatter contentType="application/json"
class="org.apache.axis2.json.JSONStreamFormatter"/-->
<!--messageBuilder contentType="application/json"
class="org.apache.axis2.json.JSONStreamBuilder"/-->
Here is the ESB template for paypal List all Payment Resources:
<template name="listPaymentResources" xmlns="http://ws.apache.org/ns/synapse">
<sequence class="sequence">
<payloadFactory media-type="json">
<format>
{}
</format>
</payloadFactory>
<property name="messageType" scope="axis2" value="application/json" />
<call>
<endpoint>
<http method="get" uri-template="{uri.var.paypalUrl}/v1/payments/payment"/>
</endpoint>
</call>
</sequence>
</template>
Proxy service:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="listPaymentResources"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property xmlns:ns="uri.var.payment"
name="ppurl"
expression="//ns:paypalurl/text()"/>
<PayPal.config>
<appUri>{$ctx:ppurl}</appUri>
</PayPal.config>
<PayPal.listPaymentResources/>
<respond/>
</inSequence>
<outSequence>
<log/>
<send/>
</outSequence>
</target>
<description/>
</proxy>
The Error log:
[2013-12-11 17:25:10,971] ERROR - TargetHandler Unexpected error: Cannot get a J
SON writer
java.lang.UnsupportedOperationException: Cannot get a JSON writer
at org.apache.axis2.json.JSONStreamFormatter.getJSONWriter(JSONStreamFor
matter.java:63)
at org.apache.axis2.json.AbstractJSONMessageFormatter.getTargetAddress(A
bstractJSONMessageFormatter.java:228)
at org.apache.synapse.transport.passthru.TargetRequest.start(TargetReque
st.java:152)
at org.apache.synapse.transport.passthru.TargetHandler.requestReady(Targ
etHandler.java:136)
at org.apache.http.impl.nio.DefaultNHttpClientConnection.produceOutput(D
efaultNHttpClientConnection.java:244)
at org.apache.synapse.transport.http.conn.LoggingNHttpClientConnection.p
roduceOutput(LoggingNHttpClientConnection.java:112)
at org.apache.synapse.transport.passthru.ClientIODispatch.onOutputReady(
ClientIODispatch.java:88)
at org.apache.synapse.transport.passthru.ClientIODispatch.onOutputReady(
ClientIODispatch.java:41)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.outputReady(Abstr
actIODispatch.java:148)
I have done some testing on the subject on latest release of the WSO2 ESB and i could not able to reproduce this given issue.
I have this WSO2 ESB proxy:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="sid008" transports="http" startOnLoad="true" trace="disable">
<target>
<inSequence>
<switch source="get-property('inquiryId')">
<log level="full"/>
<case regex="">
<send/>
</case>
<default>
</default>
</switch>
</inSequence>
<outSequence>
<....some processing..>
<send/>
</outSequence>
</target>
<publishWSDL key="CommonService.wsdl">
<resource location="request.xsd" key="request.xsd"/>
<resource location="response.xsd" key="response.xsd"/>
<resource location="SMEV.xsd" key="SMEV.xsd"/>
<resource location="statusAndError.xsd" key="statusAndError.xsd"/>
</publishWSDL>
</proxy>
In this proxy in default case doesn't run outSequence without send mediator. How can I do it without send mediator
Try this config for :
<default>
<... some processing ...>
<header action="remove" name="To"/>
<property action="set" name="RESPONSE" scope="default" type="STRING" value="true"/>
<send/>
</default>
With this config, you'll send response to client directly from inSequence part (you won't get into outSequence).
The rational behind In and Out sequence is:
In seq : When a message comes to a proxy service from a client, it always goes to the In sequence.
Out Seq: When a proxy service sends a message out from ESB to a backend service, the response will always come to Out seq (Unless specify the sequence using receiving seq.)
Hope this helps.