Square brackets in application/x-www-form-urlencoded message format (wso2 ESB 5.0) - wso2-esb

I am trying to send a request through wso2 ESB 5.0.0 to external HTTP API which require application/x-www-form-urlencoded format. I found this post:
Sending Content-Type application/x-www-form-urlencoded WSO2 ESB
and it's almost works, but this vendor also require parameters in array format like this:
to[email#email.com][message_id]=message_id
Unfortunately xml nor json doesn't allow me to build parameters with square brackets in xml node names or in json key names. Escaping through %5B %5D also won`t help.
I also tried ExpandingMessageFormatter but with no success - I can`t build well-formed property and replace message of a body with it's content. For example:
<property name="messageBody" scope="default" type="STRING" value="to%5Bemail%40email.com%5D%5Bmessage_id%5D=id&to%5Bemail%40email.com%5D%5Breciver_name%5D=Name%20Surname&smtp_account=2.xxx.smtp&subject=Test%20temat&html=%3Chtml%3E%3Cb%3ETEST%3C%2Fb%3E%3C%2Fhtml%3E&from=email%40email.com&from_name=xxx"/>
<payloadFactory media-type="json">
<format>"$ctx:messageBody"</format>
<args/>
</payloadFactory>
or with EnrichMediator:
<enrich>
<source clone="true" property="messageBody" type="property"/>
<target type="body"/>
</enrich>
Please, any advise will be helpful.

Related

WSO2 Sequence: capture headers of incoming request

I am writing a mediation sequence for APIM v 2.6. The point is to extract Authorization headers for further processing. Based on this documentation, I thought of the following:
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="ExtractAuthorization2EndPoint" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<property expression="get-property('axis2', 'TRANSPORT_HEADERS')" name="basic_auth" scope="axis2"/>
<log level="full">
<property expression="get-property('basic_auth')" name="captured_headers"/>
</log>
</sequence>
Problem
Reading the logs, I get captured_headers = null
TID: [-1234] [] [2020-01-09 13:46:44,178] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: /somewhere, MessageID: urn:uuid:e9fc50db-5a7b-41d1-9613-80b215633bcd, Direction: request, captured_headers = null, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body/></soapenv:Envelope> {org.apache.synapse.mediators.builtin.LogMediator}
How can I capture the headers (more specifically, the Authorization) of the incoming request?
Various other attempts
get-property('transport','Authorization')
$trp:Authorization
Authorization Header is used in API Manager for internal authorization purposes only, and that header is normally removed from the outgoing request(from APIM gw to backend) before it is sent to backend. This happens at APIAuthenticationHandler level. And the custom in sequence you attached to API will be executed after the APIAuthenticationHandler. You may refer the message flow diagram in [1] for a better understanding.
Now let's see how this APIAuthenticationHandler is applied by default on the API's synapse file. (You may find this at /repository/deployments/server/synapse-configs/api folder)
<handler class="org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler">
<property name="RemoveOAuthHeadersFromOutMessage" value="true"/>
<property name="APILevelPolicy" value=""/>
<property name="APISecurity" value="oauth2"/>
</handler>
You can modify the above handler as below and enforce to keep the Oauth header in the outgoing message.
<property name="RemoveOAuthHeadersFromOutMessage" value="false"/>
After modifying the API's synapse you may see a log like below in the console.
INFO - APIDeployer API: admin--PizzaShackAPI:v1.0.0 has been updated from the file: /wso2am-2.6.0/repository/deployment/server/synapse-configs/default/api/admin--PizzaShackAPI_v1.0.0.xml
Now, try invoking the API. You should be able to log the Authorization header.
[1]. https://docs.wso2.com/display/AM210/Message+Flow+in+the+API+Manager+Gateway

WSO2 API Manager 1.10 issue

We are running into an issue where a call to a WSO2 API REST endpoint fails with a "412 Precondition Failed" when the Content-Length exceeds 1068. Just adding a space to the request (increasing size to 1069) causes this failure. This issue can also happen when content length is less than 1069, if the API is called fast enough (using SOAPUI for testing). We have a theory that the header and body are split between packets and confuses the request. We tried turning off chunking and that didn't affect things. When the back end REST service is called directly it works fine.
You can turn off the chunking as below by using the property mediator if you are calling the SOAP endpoint. But you have to make sure that the SOAP endpoint is also expecting a non-chunked request.
<property name=”DISABLE_CHUNKING” value=”true” scope=”axis2″/>
But if you are using REST endpoint above property may not work sometimes. In that kind of situation, we need to make sure the Content-Length header is appended to the request. We can use below two properties to append the Content-Length header.
<property name="FORCE_HTTP_CONTENT_LENGTH" value="true" scope="axis2"></property>
<property name="COPY_CONTENT_LENGTH_FROM_INCOMING" value="true" scope="axis2"></property>
Sample proxy inSequence
<inSequence>
<log level="custom">
<property name="msg" value="Executing IN sequence"></property>
</log>
<property name="FORCE_HTTP_CONTENT_LENGTH" value="true" scope="axis2"></property>
<property name="COPY_CONTENT_LENGTH_FROM_INCOMING" value="true" scope="axis2"></property>
<send>
<endpoint>
<address uri="https://www.google.com" format="rest"></address>
</endpoint>
</send>
</inSequence>

Internal server error in WSO2 ESB API resource

I'm trying to call a web service in tomcat through api resource in WSO2 ESB.
The resource is:
<resource methods="DELETE" url-mapping="/weight/delete">
<inSequence>
<log level="custom">
<property name="Access token value" expression="$trp:Authorization"/>
</log>
<oauthService remoteServiceUrl="https://host:port/services/" username="username" password="password"></oauthService>
<header name="Authorization" scope="transport" action="remove"></header>
<send>
<endpoint>
<address uri="http://host:8080/web-services/services/proyect1"></address>
</endpoint>
</send>
</inSequence>
It hasn't query params and path params.
But I have an 500 internal server error, and tomcat throw this exception:
Caused by: com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
The request is:
Method: Delete
http://host:8282/web-services/services/proyect1/weight/delete
Head: Authorization: Bearer 89712389712hd97861h
Payload: [{"id":"307"}]
All is correct sending request directly to tomcat.
According to REST, delete method in HTTP must not content payload. Then, http://host:8282/web-services/services/proyect1/weight/delete it's not correct.
But, to resolve this problem I can use a PayLoadFactory mediator in WSO2 to send JSON to endpoint.

WSO2 PayloadFactory is sending json wrapped with jsonObject

I am using WSO2 API Manager 1.7.0 and am doing a simple payloadfactory attempting to convert a call from a GET to a POST passing in a json payload.
However when I look at the log files it appears that WSO2 is sending the json wrapped with {"jsonObject": [myjson] }
I am new to WSO2 and am not sure what cofiguration setting I need to use to stop this. I assume it is a config setting since in no examples or documentation that I have found does anyone else mention this.
My api looks like this:
"POST http://localhost:81/Service/ProcessRequest HTTP/1.1[\r][\n]"
"Authorization: Basic asdfadfadfadfadfadfadfa=[\r][\n]"
"Accept-Encoding: gzip,deflate[\r][\n]"
"Content-Type: application/json[\r][\n]"
"activityID: 2342342342342342342342342[\r][\n]"
"Transfer-Encoding: chunked[\r][\n]"
"Host: localhost:81[\r][\n]"
"Connection: Keep-Alive[\r][\n]"
"User-Agent: Synapse-PT-HttpComponents-NIO[\r][\n]"
"[\r][\n]"
I/O session http-outgoing-2-3 11.11.11.11:12345<->192.168.1.1:8080[ACTIVE][rw:w]: 0 bytes written
http-outgoing-2: Produce output
I/O session http-outgoing-2-3 11.11.11.11:12345<->192.168.1.1:8080[ACTIVE][rw:w]: 230 bytes written
"db[\r][\n]"
"{"jsonObject":{"UserType":"User"}}[\r][\n]"
"0[\r][\n]"
"[\r][\n]"
The log file part that seems to apply to the service call looks like this:
<api name="admin--JJJJJ" context="/jjjjj" version="v1.0" version-type="url">
<resource methods="GET" url-mapping="/documents">
<inSequence>
<payloadFactory media-type="json">
<format>{"UserType":"User"}</format>
<args/>
</payloadFactory>
<property name="Authorization" expression="fn:concat('Basic ', base64Encode('user:password'))" scope="transport"/>
<property name="HTTP_METHOD" value="POST" scope="axis2" type="STRING"/>
<property name="messageType" value="application/json" scope="axis2"/>
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
<log>
<property name="JSON-Payload" expression="json-eval($.)"/>
</log>
<send>
<endpoint name="admin--JJJJJ_APIproductionEndpoint_0">
<http trace="enable" method="post" uri-template="http://localhost:81/Service/ProcessRequest"></http>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</resource>
<handlers>
...
</handlers>
</api>
I'm not sure where the db and 0 come from in the transmission but the error I get back from my service appears to be caused by the wrapping jsonObject.
Does anyone have any hints or ideas on how I can either prevent this wrapping or modify the payload just prior to sending it to remove it. Or I guess a better or even different way of transforming a GET request to a POST with a json payload.
Thank you for any hints on what I'm doing wrong.
change the messageformater in axi2.xml (/repository/conf/axis2/axis2.xml)file as
<messageFormatter contentType="application/json" class="org.apache.synapse.commons.json.JsonStreamFormatter"/>
and comment the default message formatter for json
<!--messageFormatter contentType="application/json" class="org.apache.axis2.json.JSONMessageFormatter"/-->
learn more on json support here[1]
https://docs.wso2.com/display/ESB480/JSON+Support
You can add an enrich mediator to api before send mediator to remove jsonObject wrapper from body like below.
<enrich>
<source clone="true" xpath="$body//jsonObject//UserType"/>
<target type="body"/>
</enrich>
You can add a log mediator after enrich mediator and check the changed body.
Hope this will help you.

WSO2 ESB REST Post request empty response

I'm trying to call test Rest Api via Post request but ESB returns always empty response. For GET request response is sent correctly by ESB.
I have tried almost everything but still cannot make this work. My ultimate goal is to store message sent by client via Post request (large requests) and sent XML structured response to user that message is queued. Here's simple example what I have tried but for Post request empty response is sent by ESB.
<inSequence xmlns="http://ws.apache.org/ns/synapse">
<log>
<property name="text" value="IN Sequence"></property>
</log>
<header name="To" scope="default" action="remove"></header>
<property name="RESPONSE" value="true" scope="default" type="STRING"></property>
<payloadFactory media-type="xml">
<format>
<response xmlns="">Hello world</response>
</format>
</payloadFactory>
<send></send>
</inSequence>
Is this BUG In WSO2 ESB 4.0.8 or am I missing something ?
Thanks,
Kari
This is now resolved. Actually problem was that in Rest client I didn't specify Content-type. After adding Content-Type application/xml -header. The XML response worked fine for POST request. For GET Request this was working all the time.