WSO2 Amazonsns connector issues publishing json message - json

I am trying to publish a json message using the Amazonsns connector in WSO2 ESB 4.9. I am able to successfully publish a simple string message however when I set the messagestructure to json in order to send different messages to different platforms and attempting to send json as the value of message it will not work. I am using a simple transaction that looks almost exactly like the documentation sample. My Transaction:
content-type: application/json;charset=UTF-8
{
"region":"us-west-2",
"accessKeyId":"MyAccessKey",
"secretAccessKey":"MySecretAccessKey",
"version":"",
"messageStructure":"json",
"subject":"Test",
"message": {"default":"mess","email":"message"},
"targetArn":"arn:aws:sns:us-west-2:977102061874:endpoint/APNS_SANDBOX/mobile_iOS_Sandbox/34ed4324e6-1119-67sd-b7dd-f413c88e4e25",
"topicArn":""
}
My result is an unexpected error sending message out.
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,73]Message: Illegal character: <d>
My service is also like the example:
<amazonsns.init>
<region>{$ctx:region}</region>
<accessKeyId>{$ctx:accessKeyId}</accessKeyId>
<secretAccessKey>{$ctx:secretAccessKey}</secretAccessKey>
<version>{$ctx:version}</version>
</amazonsns.init>
<amazonsns.publish>
<message>{$ctx:message}</message>
<subject>{$ctx:subject}</subject>
<messageStructure>{$ctx:messageStructure}</messageStructure>
<topicArn>{$ctx:topicArn}</topicArn>
<targetArn>{$ctx:targetArn}</targetArn>
</amazonsns.publish>
I did not expect much success but just started trying different things....I attempted xml encoding the json message and get the same message on '&'. Using wire logs I found the content type of the successful messages going to Amazon were application/x-www-form-urlencoded so I also tried url encoding and get same message on the '%'.
I'm running out of ideas. I double checked the connector documentation to make sure I did not miss anything. It does say you can use a JSON transaction for Publish and gives a sample transaction however it does not discuss anything special/different that you would need to set up in order to make this work. Is there something I am missing?
UPDATE: Can see it is using the Builder for application/x-www-form-urlencoded which is stumbling on the json. Have tried setting messageType and ContentType properties to application/json. JSON Builder is enabled. It just seems the connector wants to send it out as application/x-www-form-urlencoded, is there something I am not setting properly to tell the connector this is JSON?
UPDATE: The publish template that comes with the connector is setting the messagetype to applicaiton/x-www-form-urlencoded which is overriding any of the settings I am making in my proxy service. Going to look at changing the template in the connector to use a different messagetype and/or allow me to set it in the proxy dynamically then will be trying again.
Joe

We have created a public JIRA for this issue. Please follow that.

You need to enable message builders for the content types you are sending. make sure following is done.
Enable relevent Message builder for each content-type.
< messageBuilder contentType="application/json"
class="org.apache.synapse.commons.json.JsonStreamBuilder"/>
Make sure Content-Type header property is parsing with the message.
Make sure your Json is wellformed.

Related

How set default output type to JSON ins DSS

We have a mobile app using Restkit which would use as WSO2 DSS service as the backend of the app. The service has a database data source. However the developer is complaining that he gets an error that the service is only returning text/plain format. The service has a JSON output type and mapped on a json format. He said that in reskit it does not send the sevice the header content type but it is expecting a json output format. Is there anyway I can set DSS default output type as json output. I've already tried all the solutions in the net but still getting same error.
Normally JSON return handled by httpContentNegotiation parameter on 'axis2.xml' and in 'axis2_client.xml'.
<parameter name="httpContentNegotiation">true</parameter>
So simply you can set content request header with
Accept:application/json
ex:
curl -v -H "Accept:application/json" 'your_path'
If you are using restkit make sure to add a custom header to http request. You need to set the Accept header as mentioned above. Please find this link.

Django cannot parse POST parameters of WSGIRequest on Internal Server Errors

I'm using Django REST Framework and all the API calls come from Android and iOS apps. The system works perfectly most of the time, however, when an internal server error happens and I get an email from Django, the POST of the WSGIRequest contains <could not parse> instead of the actual posted JSON data (even though 'CONTENT_TYPE': 'application/json' is also in the header, and the data is sent as JSON).
This is really annoying, as it would be great to see the request body that actually causes the error, not just the stacktrace.
The <could not parse> part is very similar to this question (in the ModPythonRequest part): django request.POST contains <could not parse>, except the actual problem is slightly different. Also the reference link in that question (https://stackoverflow.com/questions/12471661/mod-python-could-not-parse-the-django-post-request-for-blackberry-and-some-andro) seems to have gone down, even though the name looked very promising.
I'm on Django 1.6.2 and DRF 2.3.13.
The POST dictionary of the WSGIRequest is always going to be invalid, because it is intended to hold the parsed form data when the Content-Type is application/x-www-form-urlencoded or multipart/form-data.
The data you want is in the body attribute of the WSGIRequest object, which isn't output when that object is converted to a string to be written to the log.
When using Django REST framework, you will typically want to access request.DATA (which will handle whatever formats you have parsers configured for - defaulting to form content and JSON) instead of Django's standard request.POST, which will only handle form encoded data.

Debugging Web Service that fails as JSON but not as XML

I have a webservice method that if I call directly via url GET returns XML without issue.
However, POST to that same url with Content-Type Json, it fails.
I think I can figure out the issue (I'm guessing it's an encoding or bad character somewhere in there) but I don't know how to debug the problem.
If I set a breakpoint in the webservice, it runs to completion. The failure appears to be happening AFTER the method returns, but BEFORE the json is returned to the caller.
How can I get in between to trace the error?
Please let me know if I can provide more context to help, but I really just need to know how to get in there.
EDIT:
The web service is configured to receive POST and return JSON and in fact DOES correctly return JSON in some cases. However, there are certain calls that are failing, so I need a way to trace this or debug it somehow and figure out why some calls are not working.
The web service is likely not configured to receive POST requests, especially if you are receiving a 405 Method Not Allowed response status.
Although I didn't find a way to debug or intercept the request to find the exact answer, it turns out the problem was the size of the content being returned by the webservice. Following this answer: ASP.NET WebMethod with jQuery json, is there a size limit?
and increasing the json limit fixed the issue!
Is there a way I could have trapped this to find the error without just guessing it was a size limit?

WSO2 API Manager Auth error content type

I have WSO2 API Manager configured and everything seems to work fine.
The only issues bothering me is that in case of an Auth exception, the API manager always returns the response with XML content type, e.g.,
<ams:fault xmlns:ams="http://wso2.org/apimanager/security"><ams:code>900904</ams:code><ams:message>Access Token Inactive</ams:message><ams:description>Access failure for API: /exchange, version: 1.0 with key: 1139a466ebfd825aca953ad7259b9f45</ams:description></ams:fault>
In case of client communicates with my web service with JSON format, the XML response will look a little bit strange.
Is there any ideas how to make API Manager provide error response in JSON format?
This has been addressed in recent versions of API Manager. Auth errors can be set to json format by adding or updating the error_message_type property in WSO2HOME/repository/deployment/server/synapse-configs/default/sequences/_auth_failure_handler_.xml:
<property name="error_message_type" value="application/json"/>
I've found this also requires JSONBuilder and JSONMessageFormatter to be selected for the json content type in axis2.xml (which is the default setting).
For older versions, this article explains how to manually do the same.

Message relay for JSON data in wso2ESB

I am trying to build a simple POC using wso2ESB. I've created a simple pass through proxy service with an Alfresco service http://www.alfresco.com/
The problem is I am not getting the full JSON data. I've read it has something to do with the axis2-JSON and that it causes problems when one has JSONArray in the root. So I've decided to use message relay.
WSO2 ESB Unable to convert complete JSON data to XML
I've edited the axis2.xml as described in the documentation thus adding the following lines
<messageFormatter contentType="application/json"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
and
<messageBuilder contentType="application/xml"
class="org.apache.axis2.builder.ApplicationXMLBuilder"/>
But after I've restarted the server when I try to use the proxy server through the firefox REST plugin the ESB throws the following exception
[2012-07-12 10:02:29,125] WARN - ClientWorker Unexpected response received. HTTP response co
de : 405 HTTP status : Method Not Allowed exception : SOAP message MUST NOT contain a Documen
t Type Declaration(DTD)
[2012-07-12 10:02:29,125] ERROR - NativeWorkerPool Uncaught exception
java.lang.ClassCastException: org.apache.axiom.om.impl.llom.OMTextImpl cannot be cast to org.
apache.axiom.om.OMElement
at org.apache.synapse.util.MessageHelper.cloneSOAPFault(MessageHelper.java:441)
at org.apache.synapse.util.MessageHelper.cloneSOAPEnvelope(MessageHelper.java:254)
at org.apache.synapse.core.axis2.SOAPUtils.convertSOAP11toSOAP12(SOAPUtils.java:95)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbac
kReceiver.java:323)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackRecei
ver.java:160)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:181)
at org.apache.synapse.transport.nhttp.ClientWorker.run(ClientWorker.java:275)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.ja
va:173)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886
)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
What causes this? Is the problem that ESB still tries to convert the JSON object instead of trying to relay it?
Is there another workaround in parsing these JSON objects (i.e. adding artificial root to the JSON object?)
at the builders you need to set the application/json to use org.wso2.carbon.relay.BinaryRelayBuilder as well.