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.
Related
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
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>
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.
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.
I have the following proxy:
<proxy name="expedientes" transports="https http" startOnLoad="true" trace="enable" statistics="enable">
<target inSequence="main" outSequence="main" faultSequence="main">
<endpoint>
<address uri="https://someweb/somepath/"/>
<property name="Authorization" expression="fn:concat('Basic ', base64Encode('user:password'))" scope="transport"/>
</endpoint>
</target>
</proxy>
with the this default main sequence:
<sequence name="main">
<in>
<log level="full"/>
<filter source="get-property('To')" regex="http://localhost:9000.*">
<send/>
</filter>
</in>
<out>
<send/>
</out>
</sequence>
When I remove the filter and leave it as:
<sequence name="main">
<in>
<log level="full"/>
<send/>
</in>
<out>
<send/>
</out>
</sequence>
I get the following error "Unexpected error during sending message out: org.apache.axis2.AxisFault: The system cannot infer the transport information from the /services/expedientes/indice.xml":
TID: [] [WSO2 ESB] [2013-02-15 12:42:05,531] ERROR
{org.apache.synapse.core.axis2.Axis2Sender} - Unexpected error during sending message out
{org.apache.synapse.core.axis2.Axis2Sender}org.apache.axis2.AxisFault: The system cannot infer the transport information from the /services/expedientes/indice.xml URL. at
...
The out message should (obviously) use the same transport to answer the request (HTTP GET). But what has this to do with "filter"?
Basically in the segment of configuration above (the one with filter mediator) it checks the "TO" header property of your message weather it is equals to "http://localhost:9000.*" or not.
If that condition fired, it simply send your message to the destination. Else the message send inside the "out" mediator.
When you remove the expression what happened is, it trying to send the all messages which are coming inside "in" mediator without knowing weather there is a "To" property or not.
In your case the incoming messages aren't containing a valid "To" property.
The default mediator inside main sequence to send message out is the "out" mediator. The "in" mediator doesn't know the message is expected to send as a response otherwise you did not say it is a resonance message explicitly.You can do it by using configuration like this
<header action="remove" name="To"/>
<property action="set" name="RESPONSE" scope="default" type="STRING" value="true"/>
But It strongly depend on your usecase though
I suggest you to go through some references regarding message mediation with WSO2 ESB.
Following are good references which I found hope you can find more
Configuring the ESB to Perform Message Mediation
Message Mediation
Thanks,