Return a soap fault from spring ws - web-services

I'm looking for some way to respond to a SOAP request with a soap fault.
Right now I can only create a fault when an exception is thrown via an AbstractEndpointExceptionResolver.
I have looked at an EndpointInterceptorAdapter but I'm not sure how to inspect or modify the response. For instance if an endpoint returns a ValidResponse but there were no values found or returned in a list in the response I would like to respond to the users request with a SoapFault instead.
We make efforts to follow "Don't Use Exceptions For Flow Control" but I've been un-successful with creating a SoapFault from an interceptor or from the endpoint without throwing an exception.

Well, I think AbstractValidatingInterceptor comes to the rescue. At least from source code part: how to handle response from interceptor and how to deal with WebServiceMessage response.
Bear in mind, the WebServiceMessage can be cast to the SoapMessage and you can populate your custom SoapFault using its SoapBody:
SoapBody soapBody = ((SoapMessage) messageContext.getResponse()).getSoapBody();

Related

Customize endpoint mapping in spring-ws

I'm implementing a SOAP web service using Spring WS.
Most of my implementation is done using types with #Endpoint annotations and methods in these types with #SoapAction annotations. Some endpoint interceptors also help glue things together.
I'm using Spring exception handling with SoapFaultAnnotationExceptionResolver that enriches the SoapFault with some specific details.
This works very well. But I have a customer requirement that says that I also have to provide customized SoapFaults for those cases where the service is invoked with an invalid soap-action. Meaning, a soap action for which I have no matching #SoapAction annotation.
What happens now is that Spring logs this:
[WARN] org.springframework.ws.server.EndpointNotFound No endpoint mapping found for [AxiomSoapMessage {http://www.example.com/myservice/xml.schema/2010/06/01}MyRequest]
I get this returned along with a 404 return code from the Jetty server that hosts this web service.
How can I catch these exceptions and add some custom soapfault handling in this situation? It seems like if only org.springframework.ws.NoEndpointFoundException had a #SoapFault annotation, I could have it go through my exception resolver and customize it that way. But it doesn't, unfortunately.
I think I may have to implement some custom "catch-all" endpoint mapping but I'm just not sure how to do this, and how to ensure that mapping to the specific endpoints are attempted first.
Anyone have a suggestion for how to do this?
The exception seems to be thrown from the class MessageDispatcher in the method dispatch:
mappedEndpoint = getEndpoint(messageContext);
if (mappedEndpoint == null || mappedEndpoint.getEndpoint() == null) {
throw new NoEndpointFoundException(messageContext.getRequest());
I suggest to extends this class and instead of throwing an exception, you could add a soap fault as such:
SoapMessage response = (SoapMessage) messageContext.getResponse();
String faultString = "any message"
SoapBody body = response.getSoapBody();
SoapFault fault = body.addServerOrReceiverFault(faultString, getLocale());
You can take a look SimpleSoapExceptionResolver that deals with exceptions on the endpoints.

How can I mediate a multipart message in WSO2 ESB 4.8.1?

I have to mediate a multipart message in a API resource, so that, at first I have to call virus scan service and depending on the response:
If the response is 200 OK continue.
Else, the response is 401 Unauthorized drop message and return 401 response.
I have tired drop message (due to limitations in measuring multipart messages) if I get 401 in mediation, but the original message always go on.
Is there any solutions for that? Is possible mediate message with Java class mediator?
Is there any way to drop parent message by messageID?
If you use a simple <drop/> in your sequence, the message shouldn't be processed further. How does your API/Proxy look like?
You can also process your message inside your custom Java class. See the following link for an example.
https://docs.wso2.com/display/ESB481/Sample+380%3A+Writing+your+own+Custom+Mediation+in+Java

Call an async fire and forget SOAP webservice with JMeter

I'm calling an async fire-and-forget SOAP webservice using jmeter and showing the results in a table.
If i use an WebService(SOAP) Request sampler, it will log the call result as an warning, even if the status code is 200, cause the ws respond with an empty message.
With a SOAP/XML-RPC Request, the log table show te request as concluded.
It's possible to tell to an WebService(SOAP) Request to understand a empty response as a valid response ?
Thanks.
In code of WebService Soap sampler it is said that:
// It is not possible to access the actual HTTP response code, so we assume no data means failure
Code excerpt:
// It is not possible to access the actual HTTP response code, so we assume no data means failure
if (length > 0){
result.setSuccessful(true);
result.setResponseCodeOK();
result.setResponseMessageOK();
} else {
result.setSuccessful(false);
result.setResponseCode("999");
result.setResponseMessage("Empty response");
}
So you don't have a solution with this sampler.
Another solution is to use HTTP Sampler with Raw Post Body and test only response code with assertion.
I opened a Bugzilla Enhancement request:
https://issues.apache.org/bugzilla/show_bug.cgi?id=53978

Is it proper to use HTTP response code representing business exception on server side?

The background is like this:
The client web browser send a request to the server;
The server program will launch some biz check rules before doing the real work.
If check fail, some tips should be feed back to the client browser.
So, here is the question. Should I use an error response http code to indicate this, or use 200 directly, and then parse the message from response body.
Sometimes, this is not a problem. But, some client component give some util methods if error code returned. So, that's a hard decision to make:
return 200,and error message. parse and show them myself;
return some code like 500, let the client component to show it directly.
I would suggest to use as many http status codes as possible. That is a standard and why should you not use them?
Here are some examples where IMHO the usage of http status codes makes sense:
Somebody wants a dataset wich is not aviable use 404 not found
A secured ressource needs an authentification use 401
A ressource which is not aviable for the currient user should get a 403 forbidden
A error accours which you cannot handle well write out an 500 status
And so on
Look also for the logic for REST-APIs there you can see the advantages.
Typically, you'll want to indicate the reason the service failed. Returning custom errors can also potentially allow the client application to respond in an appropriate way. If an input validation check fails, for instance, I imagine the user would appreciate the chance to fix and resubmit the request. An HTTP error won't be enough to indicate what exactly went wrong.

How to handle Exceptions in Apache CXF

I'm using the CXF for developing webservices.
But I was wondering what is Best Practice for handling exceptions? Let's say I have a webservice-operation, create(User user).
The incoming user is an instance of my User domain class, and can be saved directly by the UI Team by calling user.save()
If the save() for some reason fail (e.g. some Network connectivity fail , or some data validation error from User DTO ), how would Best Practice dictate that I serve this exception to the client?
I mean: Which type of Exception would be suitable?
Should this Exception be included in the operations signature ??
public Response createUser(User user);
#WebService
public interface EmpService {
public Response createUser(User user);
}
And how should the client-side handle this exception?
One company I was working in, with web services had almost 15 years of experience, so I have learned some things. We handled the exception simply by specified throws statement in the method. And if some expected error occurred, we just simply constructed the exception and throw it with the message which pointing to reason why something has failed.
The client should handle all exceptions thrown by service in anyway he likes to do it. If you are developing a web service, you need to be worried about how to correctly create an exception with appropriate reason in it. And when exception occurs the client will see it anyway.