Wso2 Fault Sequence Error Handling Header - wso2

I am currently developing an API that will send a request to the Endpoint and will response back to the client.
On my fault sequence, I will log the error code and error message by using the makefault mediator. Everything is working fine about the error code and message logging. It just that, the HTTP header return as 500 (Internal Server Error) for every error.
This is my Fault Sequence look like.
<faultSequence>
<makefault description="" version="soap11">
<code value="soap11Env:VersionMismatch" xmlns:soap11Env="http://schemas.xmlsoap.org/soap/envelope/"/>
<reason expression="get-property('ERROR_CODE')"/>
<role/>
<detail/>
</makefault>
<log level="custom">
<property expression="get-property('HTTP_SC')" name="header"/>
</log>
<header name="To" action="remove"/>
<property name="RESPONSE" value="true"/>
I try to catch the HTTP code inside the message context. The value is null
LogMediator header = null
But when the response is being send back to the client, it return the HTTP as 500(Interal Server Error)
Any advice would help here. Kindly assist. Thank you StackOverFlow.

HTTP_SC property belongs to the axis2 scope. So you can log the status code using either
<log level="custom">
<property expression="get-property('axis2','HTTP_SC')" name="header"/>
</log>
or
<log level="custom">
<property expression="$axis2:HTTP_SC" name="header"/>
</log>

Related

WSO2 : Request header field x-requested-with is not allowed by Access-Controll-Allow-Headers in preflight response when using multipart/form-data

I'm creating a POST API service to upload files in WSO2EI. Request using multipart/form-data.
I got error
Access to XMLHttpRequest at 'x' from origin y has been blocked by CORS policy: Request header field x-requested-with is not allowed by Access-Controll-Allow-Headers in preflight response
I only got the error when hit the service from frontend using vue js.
I already added option method
<resource methods="OPTIONS" uri-template="/*">
<inSequence>
<property name="Access-Control-Request-Headers" scope="transport" type="STRING" value="authorization,content-type"/>
<sequence key="gov:commons/AccessControlAllow.xml"/>
<property name="RESPONSE" scope="default" type="STRING" value="true"/>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
sequence AccessControlAllow.xml
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="AccessControlAllow" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<property name="Access-Control-Request-Headers" value="Authorization,Content-Type, Access-Control-Allow-Origin" scope="transport" type="STRING"/>
<property name="Access-Control-Allow-Methods" scope="transport" type="STRING" value="GET,POST,PUT,DELETE,OPTIONS"/>
<property name="Access-Control-Allow-Headers" scope="transport" type="STRING" value="Origin, X-Requested-With, Content-Type, Accept"/>
<property name="Access-Control-Allow-Origin" scope="transport" type="STRING" value="*"/>
</sequence>
I also added this sequence (AccessControlAllow.xml) before sending response. I got the error only when the request using mulltipart/form-data and hit from vue.js. Anyone can help me to solve this problem?
This might be because, You have defined a OPTION resource in your API. If you have defined OPTIONS as a resource method, then EI sends the request to the backend service to collect the information.
Therefore, Check the API definition and remove OPTION call if exist.

WSO2 Integrator: REST API GET Request missing response body

I am using WSO2 Integrator 6.6.0 to make a blocking HTTP GET to a REST API that returns a JSON response (HTTP 200 OK).
But I never see the response body inside my sequences. I am not sure what I am doing wrong, having exhausted all available documentation and other threads.
Sequence doing the call (simplified to anonymize), which logs the response afterwards:
<!-- Remove XML body as not needed for GET request -->
<payloadFactory media-type="json">
<format></format>
<args></args>
</payloadFactory>
<header name="Accept" value="application/json" scope="transport"/>
<property name="NO_ENTITY_BODY" value="true" scope="axis2" type="BOOLEAN" />
<call blocking="true">
<endpoint>
<http method="GET" uri-template="http://my-api/order-status">
</endpoint>
</call>
<property name="RESPONSE" scope="default" type="STRING" value="true"/>
<log level="full">
<property name="response-log" value="Received response"/>
<property expression="$body" name="response-body"/>
<property expression="json-eval($)" name="json-eval-body"/>
</log>
This results simply into a log line - with no response body at all!
INFO {org.apache.synapse.mediators.builtin.LogMediator} - To:
http://my-api/order-status, WSAction: urn:mediate, SOAPAction:
urn:mediate, MessageID:
ID:414d51204343494153303131202020209ca4175f28ac422e, Direction:
response, response-log = Received response, response-body =
<soapenv:Body
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"></soapenv:Body>,
json-eval-body = {}, Payload: {}
I can see the request in my API application and I can also see what it correctly returns a response body in its logs. Also, using Postman to do the same request I receive the following JSON response with 200 OK and Content-Type appication/json:
{
"order_status": "NOT_FOUND"
}
Inside WSO2 I do not see anything! I want to be able to convert the response into XML format.
What could be wrong?
Before making a REST call, it is necessary to remove the headers from the main call.
Put this snippet before the call mediator:
<property name = "FORCE_HTTP_CONTENT_LENGTH" scope = "axis2" type = "STRING" value = "true" />
<property action = "remove" name = "REST_URL_POSTFIX" scope = "axis2" />
<property action = "remove" name = "TRANSPORT_HEADERS" scope = "axis2" />
As I understand it should solve.
Can you modify the NO_ENTITY_BODY property as follows and try this mediation again.
<property name="NO_ENTITY_BODY" action="remove" scope="axis2"/>
Having simplified this configuration for this question, I had missed that having the following property set in my proxy service:
<property name="OUT_ONLY" scope="default" type="STRING" value="true"/>
Means that WSO2 is ignoring the response from the API. Removing this property resolved the issue for the following config:
<header name="Accept" value="application/json" scope="transport" />
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<call blocking="true">
<endpoint key="conf:/endpoints/FX_TRADING_API_ORDERSTATUS.xml"/>
</call>

Error in log with Fire and Forget API resource in WSO2 ESB

According to One-Way Messaging in a Fire-and-Forget Mode through ESB in WSO2 ESB Documentation I have the following resource:
<resource methods="GET" uri-template="/{serviceId}/*">
<inSequence>
<property name="CHANNEL_COD" value="999"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="OUT_ONLY" value="true"/>
<log>
<property name="**** INSIDE" value="[API] /emma/{serviceId}"/>
</log>
<property name="serviceId" expression="get-property('uri.var.serviceId')"/>
<log>
<property name="**** SERVICE_VALUE" expression="get-property('serviceId')"/>
</log>
<switch source="get-property('serviceId')">
<case regex="Servicio">
<log>
<property name="**** Servicio CASE" expression="get-property('serviceId')"/>
</log>
</case>
<default>
<log>
<property name="**** Default CASE" expression="get-property('serviceId')"/>
</log>
</default>
</switch>
<send/>
</inSequence>
But, when I look in SystemLog (from WSO2 Console) I can see two following error messages:
The system cannot infer the transport information from the /context/servicio URL.
Unexpected error during sending message out
The behavior is correct, but I don't know if I do wrong anything.
PD: It's a mock resource to trying Fire&Forget resource.
There is a send at the end of your inSequence. But without an endpoint definition and without initializing heater To, this send means "send back the response message to the caller".
However, there is no request and so no response and moreover, you define FORCE_SC_ACCEPTED that send back an ack (http status code 202)
Remove this send that make no sense (in the sample that you mention, there is an endpoint definition inside the send)

WSO2ESB Parallel SOAP calls

I have the following problem:
Develop a WSDL Based Proxy that calls several different SOAP Web services in parallel and returns the responses:
<inSequence>
<log level="full"/>
<iterate xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:agg="http://www.test.ro/aggregate"
preservePayload="true"
attachPath="//soapenv:Body"
expression="//agg:AggregateRequest/agg:messageRequest">
<target>
<sequence>
<property name="messageId"
expression="//soapenv:Body/agg:messageRequest/agg:messageId[node()]"/>
<property name="endpoint"
expression="//soapenv:Body/agg:messageRequest/agg:endpoint[node()]"/>
<xslt key="CleanPayload" source="/"/>
<send>
<endpoint key="MirrorEndpoint"/>
</send>
</sequence>
</target>
</iterate>
</inSequence>
<outSequence>
<property name="resp" scope="default">
<agg:AggregateResponse xmlns:agg="http://www.test.ro/aggregate"/>
</property>
<aggregate>
<completeCondition timeout="10">
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
expression="$body/*"
enclosingElementProperty="resp">
<log level="full"/>
<send/>
</onComplete>
</aggregate>
</outSequence>
My challenges are:
how do I pass the messageId from inSequence to outSequence so I can match the response to the request (similar to local environment from Message Broker)
how do I set the endpoint key with the text from agg:endpoint
I know this may be a newbie question but I'm having a hard time finding good tutorials on this topic.
Thank you
When you set a property (scope default) inside the In Sequence, you can find back it's value inside the Out Sequence.
Set this property inside your In Sequence :
<property name="IN_MESSAGE_ID" expression="get-property('MessageID')"/>
you can use get-property('IN_MESSAGE_ID') in your Out Sequence
If you want to send a message to a dynamic address, you can set "To" header and use send mediator :
<header name="To" expression="get-property('MY_DESTINATION')"/>
<send/>
Try setting the messageId as a HTTP header property,
<header name="MessageId" value="0001" scope="transport"/>
And retrieve this header in the outSequence
<property name="MessageId" expression="get-property('MessageId')"/>
I havnt tested this out, so give a feedback on whether it works

WSO2 ESB - transform a HTTP 202 accepted response

The Endpoint_BPS_CreateCaseService/UpdateCaseService endpoints below both point to one-way BPEL services running on WSO2 BPS. WSO2 BPS returns a HTTP 202 accepted message instantly when they are invoked.
The client application that I am using will throw a fault if it does not get a valid SOAP envelope as a response so I'm going to use a proxy service in ESB to wrap around the BPEL process.
How do I use a WSO2 ESB proxy service to forward a SOAP envelope to Endpoint_BPS_* below and then return a SOAP envelope response to my client app?
I also want to execute the faultSequence "ProcessFault" if either endpoint is unavailable or times out. I previously used the OUT_ONLY to get around the response issue above but it means I can't detect endpoint problems. Unless it is possible to do both somehow?
Another thing I've tried is cloning the message but this was a bit messy.
Any help greatly appreciated
<proxy xmlns="http://ws.apache.org/ns/synapse" name="BPSProxyService" transports="https,http" statistics="disable" trace="enable" startOnLoad="true">
<target faultSequence="ProcessFault">
<inSequence>
<log level="full">
<property name="MESSAGE" value="BEGIN BPSProxyService" />
</log>
<switch source="//*[local-name()='Operation']">
<case regex="create">
<send>
<endpoint key="Endpoint_BPS_CreateCaseService" />
</send>
</case>
<case regex="update">
<send>
<endpoint key="Endpoint_BPS_UpdateCaseService" />
</send>
</case>
</switch>
</inSequence>
<outSequence>
<property name="HTTP_SC" value="200" scope="axis2" />
<class name="esb.mediators.InjectSOAPEnvelope" />
<log level="full">
<property name="MESSAGE" value="END BPSProxyService" />
</log>
<send />
<drop />
</outSequence>
</target>
<publishWSDL key="common/bpsproxyservice/bpsproxyservice.wsdl">
<resource location="schema.xsd" key="common/schema_v2.xsd" />
</publishWSDL>
</proxy>
When you receive a 'HTTP/1.1 202 Accepted' response from your backend like BPS in the outSequence of your Proxy Service, then you need the <property name="SC_ACCEPTED" value="false" scope="axis2"/> statement to modify the '202'-response into something else.
Example:
<property name="SC_ACCEPTED" value="false" scope="axis2"/>
<property name="HTTP_SC" value="200" scope="axis2"/>
<payloadFactory media-type="xml">
<format>
<response>
<result>OK</result>
</response>
</format>
<args/>
</payloadFactory>
<send/>
The response is transformed into 'HTTP/1.1 200 OK' with a response message.
Add the "FORCE_SC_ACCEPTED" parameter with the "OUT_ONLY" in the inSequence of the proxy service as follows.
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2" type="STRING"/>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
For more information use the following article:
http://mohanadarshan.wordpress.com/2013/05/05/out_only-scenario-in-proxy-service-wso2-esb/