Spring-WS: Converting SOAP Faults into Specific Exceptions - web-services

When using Spring-WS as a SOAP client, I have a hard time converting incoming faults to their specific Java Exceptions.
For example, if the web service operation I am calling can return a ClientNotFoundFault and let's say, an InvalidAmountFault, can I make Spring-WS throw either a ClientNotFoundException or an InvalidAmountException?
Can Spring-WS throw something different than SoapFaultClientException?
I can do this the other way around when writting the web service myself. There, using the SoapFaultMappingExceptionResolver, I can easily convert Exceptions into their equivalent fault. I just couldn't find anything about doing it when writting the client...
I am using Spring-WS 2.1.0.RELEASE with JDK 1.7.6
Thanks and let me know if I am not clear enough or if you need some code example.

There is no equivalent resolver on the client side. The resolver interface is there all ready for someone to write a similar mapper. Should be very straight forward to hold a map of fault codes vs exception classes.
See org.springframework.ws.client.core.FaultMessageResolver
This is implemented by SoapFaultMessageResolver at the moment which simply wraps the fault message in the SoapFaultClientException that you are seeing.

Related

Retry on AmazonSQSClient

I'm using AmazonSQSClient to interact with the SQS service and using the default client configuration which means it already is using the DEFAULT_RETRY_POLICY.
Let's say I make a call in my Java code to the "sendMessage" method.
As per the doc, the method can throw 2 types of Exceptions: InvalidMessageContentsException & UnsupportedOperationException.
Now let's say that the SQS service was unavailable due to whatever reason, and even after retries the SQSClient could not perform the sendMessage operation. I'm trying to understand how would I get to know that in my Java code. I can catch the aforementioned exceptions but I don't think these exceptions would have the info I need. They seem more related to an invalid message or an unsupported operation.
Am I missing something? Thoughts?
This looks like the relevant Java SDK code. This section leads me to believe you'll receive a SdkClientException with the causal exception inside of it.

Service layer validation - throw exceptions or have wrapper ServiceResponse type

This is a general, architecture question, not a request for code examples or particular code solutions.
In a multi-layered applications we have 2 major options of handlings service layer validations:
Service layer throws exception which Presentation layer should catch and handle.
PRO for this approach is lightweight service layer signature but on the other hand there is a potential overhead of exceptions being thrown all around the place and since exceptions themselves are not the cheapest options one might want to reconsider this option.
Introduce ServiceResponse wrapper type
The type might be something like (pseudo code):
class ServiceResponse{
boolean IsOk;
array ErrorMessages;
object OkResponse;
}
This is also in line with REST Services (although question is not about them) where Http response message actually acts as a ServiceWrapper with its StatusCode and Content.
What approach do you prefer in your service layers and why?
If Iam understanding your question correctly, your service layer is a library of some sort that you inject or depend upon, in your UI layer. It's better to throw exceptions at this level. If you ever decide to **Physically separate ** the services layer and expose it via an API layer (REST). You can always catch those exceptions at API Layer and return http response with correct http code and exception message. So yeah stick to exceptions to start with.

Error codes vs soap faults in soap based service

I have developed a soap based web service. It returns java objects which contains data fields as well as error code and error message fields in case any error occurs or any exception is carched.
I have heard of soap fault messages that should be used for errors and exceptions.
My question is should i stick with current approach or should i use the soap fault messages?
Use SOAP Faults. That's why they were invented.
Using faults, your wsdl2java or equivalent tool will create a Java exception class for each fault type. When the fault occurs, the callers of the service can catch it using try/catch blocks. This makes it much easier to use the service, as it will not be necessary to check for error codes on every call.
It also means that code can't just forget to check for error codes.

How does Delphi web-services work ? ( Adding method in runtime ?? )

I've created web-service in Delphi XE using WSDL importer.
Delphi generated for me module ITransmitter1.pas with
ITransmitter interface and GetITransmitter function.
To use webservice i use:
var Transmitter: ITransmitter;
begin
Transmitter := GetITransmitter(True, '', nil);
Transmitter.Transmit(Memo1.Text, OutXML);
end;
But i cant see anywhere body of method Transmit ...
In ITransmitter.pas i see:
InvRegistry.RegisterInterface(TypeInfo(ITransmitter), 'urn:TransmitterIntf-ITransmitter', 'utf-8');
InvRegistry.RegisterDefaultSOAPAction(TypeInfo(ITransmitter), 'urn:TransmitterIntf-ITransmitter#Transmit');
If i comment this lines i get "interface not supported" error.
As i see here delphi is adding method in RunTime !
How does it work ? Can i add method in runtime to my own class ?
If you created a web service client with the WSDL importer, the generated client code will invoke a method on the server. So in fact, the method 'body' (code) is on the web service server.
Delphi generates a Soap request based on the WSDL, and behind the scenes RTTI (introspection) is used to generate parameters etc. of the web service call as XML. This XML is sent to the server, which executes the method implementation and sends back a Soap response.
Things are opposite if you create the web service server, in this case the Delphi application of course needs to implement all method bodies.
You're in fact calling a method defined in a Interface, which in turn inherits from IInvokable, declared in System.pas.
If you check your source code you'll note that no local object in your project implements the IInvokable interface you're calling, that's because that method is remotely executed in the server.
Before that occurs, there's some pascal code used to create a proper SOAP request to the server, send it and then wait and interpret the server response, consider this implementation details. If you're interested in know a bit more how this works, enable the "use debug .dcus" compiler option, so you can debug inside the VCL/RTL.
Then, as usual, use the StepInto (F7) command to ask the debugger to execute the Transmit method step by step... after some assembler in the TRIO.GenericStub method you'll get to the TRIO.Generic method where the packet is prepared and sent.
For a btSOAP binding I'm using to write this response, the relevant part starts at line 943 in the Rio.pas unit:
try
FWebNode.Execute(Req, Resp);
finally
{ Clear Outbound headers }
FHeadersOutBound.Clear;
end;
THTTPReqResp.Execute then uses wininet.dll functions to perform the connection, send and receive of information with the server using.
There are some levels you can go deep with this... how far you want to go will depend on your interests and the great amount of details are far beyond the scope of my answer here... feel free to post more questions with specific tings you're interested in.
I'm not sure about, but details can change between Delphi versions... I'm using Delphi XE right now.

Best Practices for Designing a Simple Web Service w/ Return Codes

I'm designing a WCF service that will return a response code (such as 0 for success, or another number for errors). Also, all methods of the web service will perform several common validations (such as authenticating an apiKey).
I am wondering if there is a best practice approach or organizing and retrieving these response codes and messages.
Thanks for any suggestions.
Ideally, don't use response codes. Return something usable on success (or void) and throw an exception on failure.
People deal with exceptions. We often forget to look at returned codes, especially when 99% of the time it's success, and we don't care about any response. So we don't capture. Then we don't bother checking for failure. Then we spend 2 days tracking down a bug that we can't find because no exception was thrown and we have no idea where the 600,000 line application failed that used your webservice... we don't even know it was a call to your webservice that failed. Just that some data is wrong for some unknown reason.
There's a topic on SO about this: Which and Why do you prefer Exceptions or Return Codes
Don't use return codes directly. Return codes usually mean success, set of expected fails and unexpected fail. Web services replace this mechanism with expected faults and unexpected faults. Check FaultContract and FaultException<T> for implementation details for expected faults. Unexpected fault is any other exception. That is the best practice.