In wso2 ESB when multipart/formdata request comes for ESB API I want to first store the request and then afterwards I want to use that property.
Below is the API code.
<api context="/multi" name="multi" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<property name="ContentType" scope="axis2" type="STRING" value="application/json"/>
<property name="messageType" scope="axis2" type="STRING" value="multipart/form-data"/>
<property name="ContentType" scope="axis2" type="STRING" value="multipart/form-data"/>
<respond/>
</inSequence>
<outSequence>
<send/>
</outSequence>
<faultSequence/>
</resource>
</api>
Request:
key : file value:image
key : json value:{"a":"b"}
Response i'm getting is correct:
--MIMEBoundary_9e01467992befaaccfd1aa25f3e48a26d18d37e547e64c30
Content-Disposition: form-data; name="file"; filename="file.png"
Content-Type: image/png; charset=ISO-8859-1
Content-Transfer-Encoding: binary
--MIMEBoundary_9e01467992befaaccfd1aa25f3e48a26d18d37e547e64c30
Content-Disposition: form-data; name="json"
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
sdkjahkshdkkhk..............(Image)
{ "a":"b"}
--MIMEBoundary_9e01467992befaaccfd1aa25f3e48a26d18d37e547e64c30--
But as I wanted to process the property mediator having json payload of multipart request to use afterwards and convert to multipart format, so if I use below API code I' getting wrong response.
<api context="/multi" name="multi" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<property name="ContentType" scope="axis2" type="STRING" value="application/json"/>
<property expression="json-eval($.)" name="inputPayLoad" scope="default" type="STRING"/>
<script language="js"><![CDATA[var rp = mc.getProperty("inputPayLoad");
mc.setPayloadJSON(rp);]]></script>
<property name="messageType" scope="axis2" type="STRING" value="multipart/form-data"/>
<property name="ContentType" scope="axis2" type="STRING" value="multipart/form-data"/>
<respond/>
</inSequence>
<outSequence>
<send/>
</outSequence>
<faultSequence/>
</resource>
</api>
But response I'm getting is
--MIMEBoundary_9e01467992befaacae1a7a25f3e48a26818d37e547e64c30
Content-Disposition: form-data; name="mediate"
Content-Type: application/xml; charset=US-ASCII
Content-Transfer-Encoding: 8bit
<mediate><file>iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAIAAAAiOj........./file><json>{ "a":"b"}</json></mediate>
--MIMEBoundary_9e01467992befaacae1a7a25f3e48a26818d37e547e64c30--
There is a difference between two response, but both the request before converting to multipart/formdata format(property mediator) are same like
{
"mediate":{
"file":"dksad..",
"json":"{"a":"b"}"
}
}
But I am not understanding why ESB is giving different response for same request(json) before converting to multipart.
The Response which you are getting is base64 Encoded, can you decode it by using base64 decoder and see the response
Related
I'm using wso2 integration studio (version 7.2). I'm trying to post a JSON payload factory to an endpoint. This JSON message has a JSON array with a square bracket but wso2 keeps removing that before sending it out. The receiver API doesn't accept it in this format.
See my code below:
<api context="/test" name="testAPi" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<property name="setCharacterEncoding" value="false" scope="axis2"/>
<payloadFactory media-type="json">
<format>{"field1": 5,"field2": 2022,"field3": "22","contacts": [{"id":1014,"surname": "N"}],"applicants": [{"nameId": 111111}]}
</format>
<args/>
</payloadFactory>
<header name="Content-Type" scope="transport" value="application/json"/>
<property name="contentType" scope="axis2" type="STRING" value="application/json"/>
<log level="full"/>
<header name="Accept" scope="transport" value="*/*"/>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<header name="Connection" scope="transport" value="keep-alive"/>
<header name="Accept-Encoding" scope="transport" value="gzip, deflate, br"/>
<property name="DISABLE_CHUNKING" scope="axis2" type="STRING" value="true"/>
<log level="full"/>
<call blocking="true">
<endpoint key="tcpmon"/>
</call>
<log level="full"/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
I used the tcpmon to see what is sending out. and I can see wso2 just remove the [] from the message and send it out.
Do you know how can I fix this?
I create custom proxy service in WSO2 ESB 490:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="write_2_greg"
transports="https,http"
statistics="disable"
trace="enable"
startOnLoad="true">
<target>
<inSequence>
<payloadFactory media-type="json">
<format>
{"name":"2rest_test","context":"/ressttest2","type":"restservice","version":"1.0.0"}
</format>
<args/>
</payloadFactory>
<property name="DISABLE_CHUNKING"
value="true"
scope="axis2"
type="STRING"/>
<property name="Accept"
expression="$trp:Accept"
scope="default"
type="STRING"/>
<property name="messageType"
value="application/json"
scope="axis2"
type="STRING"/>
<property name="Authorization"
expression="fn:concat('Basic ',base64Encode('admin:admin'))"
scope="transport"
type="STRING"/>
<call>
<endpoint>
<http trace="enable"
method="POST"
uri-template="https://localhost:9443/governance/restservices"/>
</endpoint>
</call>
<property xmlns:ns="http://org.apache.synapse/xsd"
name="__Status"
expression="$axis2:HTTP_SC"
scope="default"
type="STRING"/>
<enrich>
<source type="body" clone="true"/>
<target type="property" property="res_body"/>
</enrich>
<log level="custom">
<property name="__Status" expression="$ctx:__Status"/>
<property name="res_body--" expression="get-property('res_body')"/>
</log>
</inSequence>
<outSequence/>
<faultSequence/>
</target>
<description/>
</proxy>
This simple proxy just create new restservice to GREG, it uses the GREG REST API. But when I run this proxy service, the GREG response 500 status code, and check GREG log, it seems Jackson error:
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not construct instance of org.wso2.carbon.governance.api.generic.dataobjects.GenericArtifact, problem: abstract types can only be instantiated with additional type information
at [Source: org.apache.cxf.transport.http.AbstractHTTPDestination$1#4d4489c7; line: 1, column: 1]
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
at org.codehaus.jackson.map.deser.StdDeserializationContext.instantiationException(StdDeserializationContext.java:212)
at org.codehaus.jackson.map.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:97)
at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2376)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1166)
at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:410)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1262)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBody(JAXRSUtils.java:1209)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:757)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:716)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:253)
... 40 more
But I can create new restservice used by "Advanced Rest Client Application"(Chrome plugin)
BTW, I test this by ESB 490 , GREG 510 and GREG 520 .
How can I achive this used by ESB?
After research the carbon-governace source code, I found that the method "isReadable" in class "org.wso2.carbon.governance.rest.api.internal.GenericArtifactMessageBodyReader"
#Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
if (GenericArtifact.class.getName().equals(type.getName()) || GovernanceArtifact.class.getName().
equals(type.getName())) {
if (MediaType.APPLICATION_JSON_TYPE.equals(mediaType) || MediaType.APPLICATION_XML_TYPE.equals(mediaType)) {
return true;
}
}
return false;
}
When post the json to request, this method is called to determine the MediaType. The MediaType accept
application/json
But the proxy I wrote it sent the content-type
application/json; charset=UTF-8
They aren't the same, so the method return false, and not process the json post.
I try to reset the ESB proxy content type like this:
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
<property name="ContentType" scope="default" type="STRING" value="application/json"/>
But the content-type still "application/json;charset=UTF-8"
I think this is the reson, but how can we fix it ?
I am developing a proxy service with a soap webservice that performs soap to rest conversion, the message is sent to a servlet that response with a string in flat format (not xml), just a secuence of characters like
OIUW|ECHNOWE|RFHQWIUE|FBPQW|EFHAO|IEFH
I am invoking with SOAP UI and I get this response fine, now I would like to receive it in "SOAP format", wrapping the message into a soap:body, I've tried with a XSLT and with a PayloadFactory Mediator, but as soon as I use any of them (even doing nothing) I get a
[2014-07-31 09:30:41,847] ERROR - RelayUtils Error while building Passthrough stream
org.apache.axiom.om.OMException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
What do I do wrong ? How can I achieve a message transformation without this exception?
Thank you!
UPDATE: My proxy as requested by Ratha
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="SCL3"
transports="http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<log level="custom">
<property name="MyTrace" value="--- REQUEST ---"/>
</log>
<log level="full"/>
<property name="REST_URL_POSTFIX"
value="x4?msg=x4|0003|0000000021|0|0|0400002081020224849"
scope="axis2"
type="STRING"/>
<property name="HTTP_METHOD" value="GET" scope="axis2" type="STRING"/>
<property name="SOAPAction" scope="default" action="remove"/>
<header name="Action" scope="default" action="remove"/>
<send>
<endpoint>
<address uri="http://localhost:8087/X4" format="pox"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<log level="custom">
<property name="MyTrace" value="--- RESPONSE ---"/>
</log>
<property name="ContentType"
value="application/soap+xml"
scope="transport"
type="STRING"/>
<property name="messageType"
value="application/soap+xml"
scope="transport"
type="STRING"/>
<payloadFactory media-type="xml">
<format>
<a xmlns="">$1</a>
</format>
<args>
<arg value="my value"/>
</args>
</payloadFactory>
<send/>
</outSequence>
</target>
<publishWSDL uri="file:/C:/wso2/wso2esb-4.8.1/repository/workspaces/myproject/SCL3.wsdl"/>
</proxy>
I've seen that my servlet was setting content type to "text/xml" instead of "text/plain", I've changed it to "text/plain" and everything is working fine now.
Therefore I deduce that the error message
"Content is not allowed in prolog"
actually means
"Unexpected content type"
When you have following outsequence configuration what your log prints?
<outSequence>
<log level="full">
<property name="MyTrace" value="--- RESPONSE ---"/>
</log>
<send/>
</outSequence>
My aim is i have to receive the url's like www.google.com from client in proxy service and send response back to client.
How can i solve this.Here i am sending my proxy service.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="Geturl"
transports="https http"
startOnLoad="true"
trace="enable"
statistics="enable">
<description/>
<target>
<inSequence onError="fault">
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="REQUEST_HOST_HEADER" value="www.google.com" scope="axis2"/>
<property name="querystrings"
expression="get-property('axis2', 'REST_URL_POSTFIX')"/>
<property name="REST_URL_POSTFIX"
expression="get-property('REQUEST_HOST_HEADER')"
scope="axis2"
type="STRING"/>
<property name="HTTP_METHOD" value="GET" scope="axis2" type="STRING"/>
<header name="To"
expression="get-property('www.google.com')"/>
<property name="message" value="Response message"/>
<property name="Sender Address" expression="get-property('www.google.com')"/>
<log level="full"/>
<log level="full">
<property name="REQUEST_HOST_HEADER" value="www.wso2.org"/>
</log>
<send/>
</inSequence>
<outSequence onError="fault">
<log level="full"/>
<log level="full">
<property name="REQUEST_HOST_HEADER" value="www.google.com"/>
</log>
<log level="full">
<property name="success" value="success"/>
</log>
<send/>
</outSequence>
</target>
</proxy>
Thanks
In the outSequence of a proxy service, when you call <send/> , the response will be sent back to the client. Try sample proxy service [1], and invoke using Try-It or SOAP UI. You will see that the response comming to the client.
[1]http://docs.wso2.org/wiki/display/ESB460/Sample+150%3A+Introduction+to+Proxy+Services
I am working on the WSO2 ESB Proxy service, which involves exposing the internal RESTful service via SOAP endpoint on the ESB.
My RESTful service requires Content-type = "application/rdf+xml". I tried setting it using all 3 properties mentioned in the documentation: messageType, ContentType and CONTENT_TYPE. However, the request Content-type still remains "application/xml".
Here is an excerpt from my sequence that calls REST service:
<property xmlns:ns="http://org.apache.synapse/xsd" name="REST_URL_POSTFIX" value="/record/12345" scope="axis2" type="STRING"/>
<property name="HTTP_METHOD" value="PUT" scope="axis2" type="STRING"/>
<property name="messageType" value="application/rdf+xml" scope="axis2" type="STRING"/>
<property name="ContentType" value="application/rdf+xml" scope="axis2" type="STRING"/>
<property name="CONTENT_TYPE" value="application/rdf+xml" scope="axis2" type="STRING"/>
<send>
<endpoint name="CQ">
<address uri="http://my_url" format="pox">
</address>
<property xmlns:ns="http://org.apache.synapse/xsd" name="Authorization" expression="fn:concat('Basic ', base64Encode('username:password'))" scope="transport"/>
<property name="OSLC-Core-Version" value="2.0" scope="transport"/>
<property name="Accept" value="application/rdf+xml" scope="transport"/>
</endpoint>
</send>
I tested it with TCPMon and no matter what Content-type property I use, request still contains "application/xml".
Please advice.
Can you try WSO2 ESB 4.7.0 with following configuration? Note that, I have changed the address format from "pox" to "rest"
<property xmlns:ns="http://org.apache.synapse/xsd" name="REST_URL_POSTFIX" value="/record/12345" scope="axis2" type="STRING"/>
<property name="HTTP_METHOD" value="PUT" scope="axis2" type="STRING"/>
<property name="messageType" value="application/rdf+xml" scope="axis2" type="STRING"/>
<property name="ContentType" value="application/rdf+xml" scope="axis2" type="STRING"/>
<property name="CONTENT_TYPE" value="application/rdf+xml" scope="axis2" type="STRING"/>
<send>
<endpoint name="CQ">
<address uri="http://my_url" format="rest">
</address>
<property xmlns:ns="http://org.apache.synapse/xsd" name="Authorization" expression="fn:concat('Basic ', base64Encode('username:password'))" scope="transport"/>
<property name="OSLC-Core-Version" value="2.0" scope="transport"/>
<property name="Accept" value="application/rdf+xml" scope="transport"/>
</endpoint>
</send>
These are the http headers sent now (captured from tcpmon)
PUT /record/12345 HTTP/1.1
Cookie: region1_configure_menu=none; region3_registry_menu=none; region4_monitor_menu=none; region5_tools_menu=none; JSESSIONID=54D2911FCD5559C6B2F723E7C6FA9B44; requestedURI="../../carbon/service-mgt/index.jsp?region=region1&item=services_list_menu"; current-breadcrumb=manage_menu%2Cservices_menu%2Cservices_list_menu%23
Authorization: null
OSLC-Core-Version: 2.0
Content-Type: application/rdf+xml
Accept: application/rdf+xml
Transfer-Encoding: chunked
Host: www.foo.com:8080
Connection: Keep-Alive
User-Agent: Synapse-PT-HttpComponents-NIO
In the configuration you have attached, you have specified the format of the address uri as "pox" .
<address uri="http://my_url" format="pox">
This will be the reason that you are getting content-type as application/xml always. Please remove this attribute and try. It should be
<address uri="http://my_url">
If you still see the issue, then try to switch to the NHTTP transport as suggested by RaviU. For that, you can first backup the axis2.xml (ESB_HOME/repository/conf/axis2/axis2.xml) as axis2_back.xml and then rename the axis2_nhttp.xml file (same location) as axis2.xml.
Can you set the content type property like this;
<property name="Content-Type” value="application/rdf+xml" scope="transport"/>
Please remove other content-type properties..
If you define like this;
[1]<property name="messageType" value="application/rdf+xml" scope="axis2" type="STRING"/>
[2]<property name="ContentType" value="application/rdf+xml" scope="axis2" type="STRING"/>
[1] for, to select messageformatter
[2]for, to select message builders
Edit;
try like this
<inSequence>
<log level="custom">
<property name="in seq --------------of proxy" expression="$trp:Content-Type"/>
</log>
<property name="messageType"
value="application/json"
scope="axis2"
type="STRING"/>
<property name="Content-Type"
value="application/json"
scope="transport"
type="STRING"/>
<log level="custom">
<property name="in seq --------------of proxy" expression="$trp:Content-Type"/>
</log>
<send>
<endpoint>
<address uri="http://localhost:5555/com"/>
</endpoint>
</send>
Sometimes, you have to enable those message formatters in axis2.xml before using them.
Check this article out. It may help if you haven't done so yet.
http://wso2.com/library/articles/axis2-configuration-part2-learning-axis2-xml#mf