Usage of SoapActionEndpointMapping in Spring-ws - web-services

I'm trying to create a WS based on a WSDL that defines one Request and one Response. The incoming request should be mapped to an endpoint depending on the SOAPAction defined in the SOAP message. To achieve this I'm trying to use the SoapActionEndpointMapping in my servlet.xml config file and define the mappings, as described in the Spring documentation.
<bean id="endpointMapping" class="org.springframework.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping">
<property name="mappings">
<props>
<prop key="http://myCompany/MyService/MyRequest/mySoapActionOne">myFirstEndpoint</prop>
<prop key="http://myCompany/MyService/MyRequest/mySoapActionTwo">mySecondEndpoint</prop>
</props>
</property>
My endpoint extends AbstractMarshallingPayloadEndpoint and should be able to handle the requests.
The problem is that when I try to send a request (with SoapUI) i get the following error in the log:
WARN [EndpointNotFound] No endpoint mapping found for [SaajSoapMessage {http://schemas.mycompany/MyService}MyRequest]
I have used the PayloadRootQNameEndpointMapping with great success earlier but can not this to work.
Any help is appreciated.
Regards.

Do you have a handler adapter bean defined also? You'll need one in order to use a MarshallingPayloadEndpoint, so that spring knows how to perform the marshalling. The adapter is called something like MarshallingEndpointHandlerAdapter, or similar.

In your SOAP client (SOAPUI), you'll need to add the SOAPAction header to your request, to supply spring with the SOAP action to use in its mapping.
E.g. SOAPAction=http://myCompany/MyService/MyRequest/mySoapActionOne
It shouldn't make any difference what type of Endpoint you're using, because currently, you're receiving a 404 response - your request isn't finding its way to any endpoint.

Related

Custom error messages and HTTP return codes in WSO2DSS

I am using Wso2 DSS and building RESTful webservices from an oracle DB and trying to return custom error messages in case no records found or invoked using invalid parameters.
And I also want to control the HTTP return code for these error responses.
For example. Lets say there is a webservice: /getemployee/{empno} that returns employee details in JSON/XML format.
If I call getemployee with an empno that doesn't exists in the DB then
I want the response to be like something similar to below
<Error>
<Error_code>No employee found </Error_code>
</Error>
It should not have the normal employee details message structure that would go as response when an employee is found.
At the moment if record is not found by the underlying query DSS just returns empty message with just root element.
The HTTP return code for this response should be 404 as opposed to the success code 200.
By default all responses get HTTP return code 200 in DSS.
Is this possible at all just by using DSS?
Appreciate your help
You would need WSO2 ESB to do that. You can make a proxy service in ESB that will call DSS and then transform the response for you based on its contents and your needs. You can do so using XSLT.
You can set manually the desired HTTP return code, using the property HTTP_SC:
<property name="HTTP_SC" scope="axis2" type="STRING" value="404"/>
You can also use switch and payload factory, if you know what you will receive and the output will be a static one.

WSO2 API Manager - Replace URLs in response body

I'm trying to setup a proxy for my RESTful API using WSO2 API Manager. My problem is that the responses from the backend API are left untouched so all the urls that connect to other endpoints still reference the backend server rather than the proxy. I need a way to replace those url values in the response body to point to the proxied api. I understand this can be accomplished via Mediation Extensions, using ESB Mediators.
I'm not familiar enough with them to pick the one better suited for the job. URLRewrite mediator looks pretty straightforward, but it doesn't seem to apply to the message body but the headers. Payload Factory seems to require a fixed structure for the message, which is not very convenient for me, since I need it to work on the different responses that my API provides (and I wouldn't want to maintain those structures in the mediator definition).
I've managed to solve it by setting the headers my application checks to build its urls:X-Forwarded-Host and X-Forwarded-Proto.
So I've created a Header Mediator that looks like:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="WSO2AM--Ext--In">
<header name="X-Forwarded-Host" expression="get-property('transport','Host')" scope="transport"/>
<header name="X-Forwarded-Proto" value="https" scope="transport"/>
</sequence>
And that did the trick.

cxf webservice over jms, how to get wsdl

I have a webservice configured like this.
<jaxws:endpoint
id="helloWorld"
xmlns:hello="http://service.test.com/"
serviceName="hello:MyServiceImplService"
endpointName="hello:MyServiceImplPort" address="jms://"
implementor="com.test.service.MyServiceImpl" >
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" />
<bean class="org.apache.cxf.transport.jms.JMSConfigFeature">
<property name="jmsConfig" ref="jmsConfig"/>
</bean>
</jaxws:features>
</jaxws:endpoint>`
I want to have the cxf generate the wsdl for me. when the service is http, I can access the wsdl from a url like this http://localhost:8080/server/hello?wsdl, after I change the transport to jms, how do I access the wsdl? what's the jms message I need to send to get the wsdl. or I have to write the wsdl first and expose it through a regular http request. I am asking this because the client need to know the wsdl to get all the type and binding information to generate class. client should already know how to connect the queue.
You can use commandline java2ws tool (see http://cxf.apache.org/docs/java-to-ws.html) passing it your implementation class. There is also a sample invocation from Ant script. It will generate WSDL which your client can use to generate client code.

Create a multipart response with WSO2 ESB

I'm trying to create a WSO2 ESB proxy that would generate an HTTP multipart response, basically with 2 parts: XML and an attached binary file (an image for example).
The sequence would be as follow:
the service is exposed as an HTTP GET request
we first call an endpoint that returns a binary file
we create an XML that describe the binary file
we mix the 2 elements together and provide the multipart response
(XML + binary file)
After several attempts and looking around on samples and forums I couldn't find how to solve this particular case.
I've managed to call the endpoint. I can see in the debug logs that the response is transferred as binary in the soap internal message.
I suspect I then need to use the MultipartFormDataFormatter. As far as I understand the code of the formatter, it takes all the child nodes of the body of the internal soap message to create one part by child.
So I've tried to append my XML content as a sibling node of the binary node (the message looks as expected in the logs), and force the ContentType with :
<property name="messageType" value="multipart/form-data" scope="axis2"/>
<property name="ContentType" value="multipart/form-data" scope="axis2"/>
to be sure to call the correct formatter.
Unfortunately this does not seem to work, the response is indeed in multipart/form-data, but with zero bytes data.
Any help?
Thanks
Yannick
You need to enable Binary Relay builders in axis2.xml file to use the multipart/form-data message formatting.
<messageBuilder contentType="multipart/form-data"
class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
<messageFormatter contentType="multipart/form-data"
class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
Thanks for your answer.
I've made several tests, by enabling Binary Relay builders, but I did not get the exact multipart response I was expecting.
So, I've finally created my own Formatter. It constructs the multipart response from the body children, and looks for some specific properties to specify header information such as part content id, transfer encoding and content type.
Maybe this will be useful to someone else:
You can set the multipart builders by uncommenting the following property in /repository/conf/axis2/axis2.xml file
<messageBuilder contentType="multipart/related" class="org.wso2.carbon.relay.BinaryRelayBuilder"/>
As per our understanding requirement here is to make a single response message using an xml content and a png attachment received from different endpoints.
In order to accomplish your goal, we can use a custom mediator. By using a custom class mediator you can build a response with xml metadata and png images.
Writing a java class to build the message with both responses could be the best way to achieve this in WSO2 way. You can use message builder and crate message methods to create the message in the way that you want. And you can use the class mediator, which can be found in this documentation to use it with ESB
As a further clarification, please note that the enrich mediator attaches the given resources.

Configuring an HTTP proxy in a Spring web app

I have been searching around for a proper way to configure an HTTP proxy in a Spring web application. Unfortunately, each time the results I get are about AOP proxies and not HTTP proxies.
Basically, one module of my application is running a webservice client configure in the Spring XML file with JAX-WS, giving something like :
<bean id="heartBeatWebservice" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="the.web.service.interface"/>
<property name="wsdlDocumentUrl" value="http://thehost:theport/theservicename.wsdl"/>
<property name="serviceName" value="TheServiceName"/>
<property name="namespaceUri" value="http://the.namespace/"/>
<property name="portName" value="TheWebServicePortName"/>
</bean>
But my app has to run behind an HTTP proxy for being able to call the web service, and I must acknowledge that I don't know how to do it properly within the Spring context.
I tried in some main class that I wrote to try out this code at first :
System.setProperty("http.proxyHost", "my.proxy.addr");
System.setProperty("http.proxyPort", "8080");
Unfortunately, it didn't work as expected. I assume there is a nice way to configure an HTTP proxy in a Spring context but can't find out how ...
Can you give me a hint ?
There isn't any Spring-specific HTTP proxy configuration required.
It should use the standard Java HTTP proxy settings, so you're going along the right lines.
Can you try running the main class using -Dhttp.proxyHost=my.proxy.host -Dhttp.proxyPort=8080 rather than using System.setProperty?