I'm working with wso2 ESB 4.8.1
My complete functionality is:
Step one:
I make a call to a service that respond me with a processId (Asynchcronous)
The service make the work asociated to that processId
Step two:
I have to iterate calling the service with the processId Until a response that indicate me that process has finished and return me the result
I'm having problems with step two implementation.
You can store the response with the process id into a Message Store.
You define a Message Processor (a scheduled message forwarding processor) that consume messages from this store and send them into a proxy service (defined inside the same ESB)
In this proxy service :
you call your service with the process id
you analyse it's response in this proxy outSequence and decide to return it if it's OK (so, the message processor will execute the reply.sequence and delete the message from the store) or return an error if not (the message processor will execute the fault.sequence and let the message in the store so, it will retry it the next time)
Thanks you very much I'll try your solution.
I have make some advances with a secuence that check if the processId has finished and if not the secuence call it own (recursion), I'm testing this alternative, I put the code (some thinks are hardcode but the important is the idea)
<resource methods="GET" uri-template="/test2">
<inSequence>
<log>
<property name="***** IN" value="Estoy en el GET /recursivetest1/test2"></property>
</log>
<call>
<endpoint name="uploadServlet">
<!-- this is the request that return the processId -->
<http method="get" uri-template="http://localhost:1234/ProyectoWebMultipartForm/UploadServlet?fase=escaneo"></http>
</endpoint>
</call>
<log>
<property name="data_id" expression="json-eval($.data_id)"></property>
</log>
<property name="escaneo" expression="json-eval($.data_id)"></property>
<sequence key="iterate_calls2"></sequence>
<send></send>
</inSequence>
<outSequence>
</outSequence>
</resource>
</api>
/////////////////
<sequence xmlns="http://ws.apache.org/ns/synapse" name="iterate_calls2" trace="disable">
<call>
<!-- this is the request that check if the processId has finished-->
<endpoint name="uploadServlet">
<http method="get" uri-template="http://localhost:1234/ProyectoWebMultipartForm/UploadServlet?fase=chequeo"></http>
</endpoint>
</call>
<property xmlns:ns="http://org.apache.synapse/xsd" name="resultado" expression="json-eval($.scan_results.scan_all_result_a)"></property>
<filter xmlns:ns="http://org.apache.synapse/xsd" source="get-property('resultado')" regex="Clean">
<then>
<log level="full">
<property name="MESSAGE" value="No hay virus"></property>
</log>
</then>
<else>
<property name="mensaje" expression="json-eval($.mensaje)"></property>
<filter source="get-property('mensaje')" regex="Escaneo sin finalizar">
<then>
<!-- the processId has not finished, I call again to the sequence, recursion-->
<log level="full">
<property name="MESSAGE" value="El escaneo no ha finalizado antes del sleep"></property>
</log>
<script language="js">
<![CDATA[java.lang.Thread.sleep(200);]]></script>
<log level="full">
<property name="MESSAGE" value="El escaneo no ha finalizado despues del sleep"></property>
</log>
<sequence key="iterate_calls2"></sequence>
</then>
<else>
<!-- the processId has finished, I have end-->
<log level="full">
<property name="MESSAGE" value="No hay virus"></property>
</log>
</else>
</filter>
</else>
</filter>
</sequence>
Related
I have created a API in API manager. I can invoke it with
http://localhost:6547/generatereports/1.0/Reports/dcuid/vcid
I am passing two parameters with "dcuid and vcid" at a time but not passing.
reportsapi:
<?xml version="1.0" encoding="UTF-8"?>
<api context="generatereports/1.0/Reports" name="reportsdataapi" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" protocol="http" uri-template="/{dcuid}/{vcid}">
<inSequence>
<property description="http" name="HTTP_SC" scope="axis2" type="STRING" value="404"/>
<log level="full"/>
<send>
<endpoint key="reportsendpoint"/>
</send>
</inSequence>
<outSequence>
<switch source="get-property('axis2','HTTP_SC')">
<case regex="200">
<log description="200log" level="custom">
<property expression="$ctx:ERROR_CODE" name="200reserrorcode"/>
</log>
<send/>
</case>
<default>
<log description="reslog" level="custom">
<property expression="$ctx:ERROR_CODE" name="reserrorcode"/>
<property expression="$ctx:ERROR_MESSAGE" name="reserrormessage"/>
<property expression="get-property('axis2','HTTP_SC')" name="reshttpsc"/>
</log>
</default>
</switch>
<send/>
</outSequence>
<faultSequence>
<switch source="get-property('axis2','HTTP_SC')">
<case regex="200">
<log description="200log" level="custom">
<property expression="$ctx:ERROR_CODE" name="200reserrorcode"/>
</log>
</case>
<default>
<log description="reslog" level="custom">
<property expression="$ctx:ERROR_CODE" name="reserrorcode"/>
<property expression="$ctx:ERROR_MESSAGE" name="reserrormessage"/>
<property expression="get-property('axis2','HTTP_SC')" name="reshttpsc"/>
</log>
</default>
</switch>
<send/>
</faultSequence>
</resource>
</api>
wso2 configuration process with to send the response is other than 200 response code
reportsendpoint:
<?xml version="1.0" encoding="UTF-8"?>
<endpoint name="reporsendpoint" xmlns="http://ws.apache.org/ns/synapse">
<http method="get" uri-template="http://localhost:6547/generatereports/1.0/Reports/{uri.var.dcuid}/{uri.var.vcid}"/>
</endpoint>
I assume you want to send a mail if the status code is other than 200. Then you can use mailto transport or mail connectors such as gmail connector outlook connector and add the configuration in the default section in the configured switch mediator.
I have a problem with wso2 esb.
I wrote a proxy and in that I call an endpoint to do some changes on original input. but the log before call and after call is the same(it should be different). It seems the call is not working at all.when I send respone to outsequence it is null. Can any one say why this happen? (I have tested my endpoint in soupUI)
this is my proxy:
<inSequence>
<property name="transport.vfs.ReplyFileName" value="GET" scope="transport"/>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
<smooks config-key="smooks-csv1">
<input type="text"/>
<output type="xml"/>
</smooks>
<iterate continueParent="true"
preservePayload="true"
attachPath="//csv-set"
expression="//csv-set/search"
sequential="true">
<target>
<sequence>
<xslt key="gov:/first.xsl"/>
<xslt key="gov:/second.xsl"/>
**<log level="full"/>
<call blocking="true">
<endpoint>
<address uri="MyEndPiont"/>
</endpoint>
</call>
<log level="full"/>**
</sequence>
</target>
</iterate>
<respond/>
</inSequence>
<outSequence>
<aggregate>
<completeCondition>
<messageCount min="0" max="100"/>
</completeCondition>
<onComplete expression="//Guest">
</onComplete>
</aggregate>
</outSequence>
Try this. List of changes:
Removed respond mediator.
Replaced call by send.
Added send in out sequence.
<inSequence>
<property name="transport.vfs.ReplyFileName" value="GET" scope="transport"/>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
<smooks config-key="smooks-csv1">
<input type="text"/>
<output type="xml"/>
</smooks>
<iterate continueParent="true"
preservePayload="true"
attachPath="//csv-set"
expression="//csv-set/search"
sequential="true">
<target>
<sequence>
<xslt key="gov:/first.xsl"/>
<xslt key="gov:/second.xsl"/>
<log level="full"/>
<send>
<endpoint>
<address uri="MyEndPiont"/>
</endpoint>
</send>
</sequence>
</target>
</iterate>
</inSequence>
<outSequence>
<aggregate>
<completeCondition>
<messageCount min="0" max="100"/>
</completeCondition>
<onComplete expression="//Guest">
</onComplete>
</aggregate>
<send />
</outSequence>
Try blocking="false". Please note that making this change does not make the call mediator is asynchonus. It's synchronous regardless of whether blocking is true or false. Blocking is just an implementation detail.
The Call mediator is used to send messages out of the ESB to an
endpoint. You can invoke services either in blocking or non-blocking
manner.
When you invoke a service in non-blocking mode, the underlying worker
thread returns without waiting for the response. In blocking mode, the
underlying worker thread gets blocked and waits for the response after
sending the request to the endpoint. Call mediator in blocking mode is
very much similar to the Callout mediator.
In both blocking and non-blocking modes, Call mediator behaves in a
synchronous manner. Hence, mediation pauses after the service
invocation and resumes from the next mediator in the sequence when the
response is received. Call mediator allows you to create your
configuration independent from the underlying architecture.
Quoted from https://docs.wso2.com/display/ESB500/Call+Mediator
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 Proxy Service deployed on ESB is calling another standalone REST service. This service returns HTTP status 200 along with some data in the response body. My question is how I can retrieve HTTP status from response. Here is my configuration:
<proxy name="CQProxy"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<switch source="get-property('Action')">
<case regex="getTaskTicket">
<sequence key="GetTaskTicket"/>
</case>
<default/>
</switch>
</inSequence>
<outSequence>
<log>
<property xmlns:ns="http://org.apache.synapse/xsd"
name="Status"
expression="get-property('HTTP_SC')"/>
</log>
<send/>
</outSequence>
<faultSequence/>
</target>
<publishWSDL key="gov:/services/cqproxy/CQProxy.wsdl">
<resource location="CQProxy.xsd" key="gov:/services/cqproxy/CQProxy.xsd"/>
</publishWSDL>
</proxy>
<sequence name="GetTaskTicket">
...
<property name="REST_URL_POSTFIX"
value="/16783484?oslc.select=dcterms:title,oslc_cm:status"
scope="axis2"
type="STRING"/>
<property name="HTTP_METHOD" value="GET" scope="axis2" type="STRING"/>
<send>
<endpoint>
<address uri="http://.../simpleQuery"
format="rest"/>
<property name="OSLC-Core-Version" value="2.0" scope="transport"/>
<property name="Accept" value="application/rdf+xml" scope="transport"/>
</endpoint>
</send>
</sequence>
...
I tried the following code:
<log>
<property xmlns:ns="http://org.apache.synapse/xsd" name="Status" expression="get-property('HTTP_SC')"/>
</log>
And this one too:
<log>
<property xmlns:ns="http://org.apache.synapse/xsd" name="Status" expression="get-property('axis2', 'HTTP_SC')"/>
</log>
But all of them returned null.
After reading WSO2 documentation in more details, I found the right answer:
<property xmlns:ns="http://org.apache.synapse/xsd" name="Status" expression="$axis2:HTTP_SC"/>
It is weird that the documented get-property('axis2', 'HTTP_SC') does not work.
Posting the solution that worked for me:
<property scope="default" type="STRING" name="HTTP_STATUS_CODE" expression="get-property('axis2', 'HTTP_SC')"/>
<log level="custom">
<property expression="get-property('HTTP_STATUS_CODE')" name="HTTP status code received: "/>
</log>
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/