I have two wso2esb instances:
1) receives a rest uri-template and sends it as a soap request.
Example request: http://myipadd:8280/restcontext/mypath
2) receives and process the soap request from #1.
When I log the request from #1, it logs that my header "To: /services/MyService" is set correctly as expected. But when I receive it from #2, it appends the path: "To: /services/MyService/mypath".
Now, my proxy service is not able to resolve this.
Use this before sending soap request to remove your REST_URL_POSTFIX:
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
Related
I have three different systems. I am using Spring integration to sync data in all these system.
System 1 calls --- > System 2 via http:inbound gateway
<int-http:inbound-gateway id="gateway"
path="/save" supported-methods="POST, PUT"
request-channel="requestChannel" reply-channel="replyChannel"
request-payload-type="com.model.Request"
mapped-request-headers="source" error-channel="errorChannel" />
System 2 will call service method to persist data which returns response if request is valid else throws exception
<int:service-activator ref="serviceMethod"
method="saveIfValid" input-channel="requestChannel"
output-channel="serviceOutput" />
<int:recipient-list-router id="id1"
input-channel="serviceOutput">
<int:recipient channel="system1" />
<int:recipient channel="system3" />
</int:recipient-list-router>
I need to send service method response to system 1 and system 3 only if operation is successful.
After calling service method, based on service method response, request for system 3 will be generated using transformer. After transformer I am putting request in mq queue.
<int:transformer id="transformer1"
method="convert" input-channel="system3"
output-channel="jmsInput">
<bean
class="com.transformer.System3Transformer" />
</int:transformer>
<int-jms:outbound-channel-adapter id="adapter"
channel="jmsInput" destination-name="queueName">
</int-jms:outbound-channel-adapter>
Updated JMS outbound code
<int-jms:outbound-channel-adapter id="jms1"
channel="jmsIn" destination-name="queueName">
<int-jms:request-handler-advice-chain>
<bean
class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
<property name="onSuccessExpression" value="T(Boolean).TRUE" />
<property name="successChannelName" value="afterSuccessDeleteChannel" />
<property name="onFailureExpression" value="T(Boolean).FALSE" />
<property name="failureChannelName" value="afterFailRenameChannel" />
</bean>
</int-jms:request-handler-advice-chain>
</int-jms:outbound-channel-adapter>
My question is
if service class fails I need to send error response and stop the flow
if service method successful persisted data, but transformation fails, system 1 should get success response and error should be logged.
Here as I am using error channel in outbound adapter, even if error occurs in transformer it is returned to system 1.
please suggest how can i handle error without using global error channel and how to handle error in jms outbound adapter.
thank you for answering my quesion
For the first case you should really just rely on the exception propagation - the flow stops and error is sent to the system1 as an HTTP response.
For the second (transformer) case you should take a look into the ExpressionEvaluatingRequestHandlerAdvice and use it with the <request-handler-advice-chain> for the <transformer>.
The same can be applied for the <int-jms:outbound-channel-adapter>, if you should acknowledge to the system1.
http://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html#expression-advice
https://github.com/spring-projects/spring-integration-samples/tree/master/intermediate/retry-and-more
I'm trying to implement my specific transport for WSO2 ESB based on some proprietary binary protocol. From protocol specification I need acknowledge every packet I receive only if I'm 100% sure that it will be processed in future. For those reasons some persistent store must be used.
I want to implement that protocol logic via WSO2 ESB sequence that gets protocol packets/messages and stores them to temporary messageStore which is used as a queue in producer/consumer pattern (where producer is transport itself and consumer is my packet processor).
I have to be sure that my packet got to the messageStore before sending acknowledge to the client. But AxisEngine.receive() does always return CONTINUE even if message store is not available.
The configuration of the proxy is:
<proxy name="MyProxyService">
<target>
<inSequence>
<store messageStore="MyStore" sequence="onStoreSequence"/>
</inSequence>
<outSequence>
<send/>
</outSequence>
<faultSequence>
<makefault version="soap11" response="true">
<code xmlns:tns="http://www.w3.org/2003/05/soap-envelope" value="tns:Receiver"/>
<reason expression="get-property('ERROR_MESSAGE')"/>
</makefault>
<send/>
</faultSequence>
</target>
</proxy>
The code I use in transport is:
MessageContext msgContext = confContext.createMessageContext();
AxisConfiguration axisConf = confContext.getAxisConfiguration();
try {
msgContext.setTransportIn(axisConf.getTransportIn(transportName));
msgContext.setTransportOut(axisConf.getTransportOut(transportName));
msgContext.setIncomingTransportName(Constants.TRANSPORT_LOCAL);
msgContext.setAxisService(axisConf.getService("MyProxyService"));
msgContext.setEnvelope(TransportUtils.createSOAPMessage(msgContext));
msgContext.setServerSide(true);
Handler.InvocationResponse response = AxisEngine.receive(msgContext);
log.error(String.valueOf(response));
} catch (Exception e) {
log.error("ERROR", e);
}
The behaviour I want to have is what I see in HTTP transport: http request from the client (SOAP UI) is translated to Axis2 MessageContext and delivered to MyProxyService. If everything is ok - I get positive response, otherwise - error code and SOAP fault.
After additional investigation I can say that idea behind HTTP transport request/response is that for sending response the HttpSender not HttpReceiver is used. HttpReceiver gets request from HTTP connection, sets link to HTTP connection to the message context, uses AxisEngine.receive() to deliver message to the ESB and returns.
HTTP response itself is received via HttpSender, identified as response to the previous request (via empty To header) and sent to the connection referenced from the message context.
I deployed exactly the same WS-proxy in 4.5.1 and 4.6. With 4.5.1 it works correctly, but with 4.6 I get:
ERROR - AxisEngine The endpoint reference (EPR) for the Operation not found is /services/registro.registroHttpSoap11Endpoint and the WSA Action = . If this EPR was previously reachable, please contact the server administrator.
The source is the following:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="registro" transports="http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<outSequence>
<send/>
</outSequence>
<endpoint>
<address uri="http://localhost:15080/SIGEM_RegistroPresencialWS/services/ServicioRegistroWebService"/>
</endpoint>
</target>
<publishWSDL uri="http://localhost:15080/SIGEM_RegistroPresencialWS/services/ServicioRegistroWebService?wsdl"/>
<description></description>
</proxy>
What do I have to do for 4.6. to make it work?
Thanx.
To enhance ESB performance pass-through transport has been enabled by default starting from ESB 4.6.0 version that is not the case for ESB 4.5.1. It seems your proxy service depends on SOAP body based dispatching but pass-through transport does not support for SOAP body based dispatching. SOAP body based dispatching build the message body and use first element's local name for dispatching which effect to proxy performance badly that is the reason it was not supported in pass-through transport. We are in a process to fix this limitation for future ESB releasees without loosing any advantage of pass-through transport.
BTW for the moment you can use one of the following workarounds.
When sending a messages to the proxy service append operation name to the endpoint URL
e.g - http://serverName/app/serviceName/operationName
Modify client level code to send expected SOAPAction value ( like Try-It case)
I'm not sure your backend service's WSDL defined "" as the value of SOAPAction if that is the case you may modified the backend service to have value other than "" per each operation. AS an example for JAX-WS services you can use #WebMethod annotation for this.
e.g - #WebMethod(action="XXXX")
Note : In case if your backend WSDL defining a value other than "" for SOAPAction while your client send message with SOAPAction="" then it's a violation of service contract by the client and need to be fixed on client level.
I have faced the same problem with wso2 ESB 4.7 and the web service is also developed by me for the company.
What worked for me is adding soapAction attribute to wsdl soap:operation element like below.
<soap:operation soapAction="http://localhost:8080/MyWebApp/services/hello" style="document"/>
We have CXF based SOAP web services and we are hitting these services from SOAP UI with no problem. With one of these services, I setup a ProxyService on barebone WSO2 ESB 4.6.0. The proxy service seems to be working with the "Try It" option from the admin console. When I try to access it from SOAPUI, the WSO2 ESB starts complaining that
"The endpoint reference (EPR) for the Operation not found is /services/HelloWorldProxyService and the WSA Action = . If this EPR was previously reachable, please contact the server administrator."
Now, when I change the endpoint URL in SOAPUI as http:// hostname:8280/services/service-name.port-name/operation-name things start to work.
Does anyone know how to fix this issue? Are there configuration options on the WSO2 ESB which will let us use traditional SOAPUI with WSO2 ESB?
You can point the proxy service url(you can view this, via service dashboard of the particular proxy) in soapui and for the "action", in the insequence of the proxy define a property call;
. header name="Action" value="soap action"
Here is the guide on vailable properties
http://wso2.org/project/esb/java/3.0.0/docs/properties_guide.html
I have the same problem if I put operation1 at the end of WS URI (http://somedomain.com/WebServiceProxyName/operation1), but post a SOAP message body with constructs for another operation(operation2,3,4,5...) it works!!!
Sample
POST http://somedomain.com/..../operation1 HTTP/1.1
....
....
<soap:Envelope ...>
<soap:Header/>
<soap:Body>
<ws:operation2>
</ws:operation2>
</soap:Body>
</soap:Envelope>
Try to change the (original) WSDL and put the soapAction there:
You can define it as an attribute of the http://schemas.xmlsoap.org/wsdl/soap/:operation element in the binding section, e.g.
<wsdl:binding name="healthcheck-1.0.0SOAP" type="tns:HealthCheck100PortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="doHealthCheck">
<soap:operation soapAction="http://www.xyz.ch/healthcheck-1.0.0/doHealthCheck"/>
Using BizTalk 2010 to consume a WCF webservice with BasicHttp binding.
My service is rejecting the requests coming from BizTalk. I can see using tracing and soapUI that the reason is the "To" header emitted by BizTalk in the outgoing message:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://biztalk01:81/StuffServices.svc</To>
</s:Header>
<s:Body>
<ns0:GetMyStuff xmlns:ns0="http://example.com/stuff" xmlns:ns1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<ns0:inputArray>
<ns1:string>80220</ns1:string>
</ns0:inputArray>
</ns0:GetMyStuff >
</s:Body>
</s:Envelope>
This request gives a fault back both in BizTalk and in soapUI, but if I try in soapUI to send the exact same request without the To header (deleting the "<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://biztalk01:81/StuffServices.svc
"), then it works fine and returns the correct response.
Thus my question: what are my options to make BizTalk not emit that "To" soap header in that outgoing request?
Actually that header was never in the request sent by BizTalk, it was added by WCF tracing in the log. Using Fiddler to capture the real request sent allowed me to see that the problem was elsewhere. It's possible to get the BizTalk query to go through fiddler by adding the proxy http://127.0.0.1:8888 in the binding configuration of the send port.