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.
Related
For my POC, created simple lambda function , which will give emp information through rest api.
Created lambda function and access all the emp data using API gateway.
Facing some challenges while accessing particular data.
i am looking for
emp/1 - to retrieve emp id
emp/_search?name="apple" - search name contains apple.
Question is how to retrieve path and request parameters in java code.
public class TestAwsLambdaFunction implements RequestHandler<Map<String, Object>, String> {
#Override
public String handleRequest(Map<String, Object> input, Context context) {
String empID= null;
try {
#SuppressWarnings("unchecked")
Map<String, String> pathParameters = (Map<String, String>) input.get("querystring");
empID= pathParameters.get("id");
System.out.println(empID);
// TO-Do Business logic -
} catch (Exception e) {
// TODO: handle exception
}
return "Hello from Lambda!" + empID;
}
}
What is the best way to expose my data in Rest api call. Bit confused with Lambda or serverless .
have any option to show the data via page wise. Since i am new to AWS. Please guide me
Question is how to retrieve path and request parameters in java code.
You can use mapping template to send $input.params('name') property in the request body to your Lambda function.
What is the best way to expose my data in Rest api call
Use the proxy integration with these guidelines:
Avoid greedy path variables, except perhaps for a catch-all 404.
Avoid using the ANY method.
Define request models and enable request validation (remember it’s off by default).
In your Lambda, check that the content-type header matches one of your request models, and return a 415 Unsupported Media Type status code if it doesn’t (the proxy integration uses the WHEN_NO_MATCH passthrough behavior). After this check, your Lambda can assume the request validation is fully enforced.
By Ben Kehoe
https://read.acloud.guru/how-you-should-and-should-not-use-the-api-gateway-proxy-integration-f9e35479b993
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html#api-gateway-proxy-integration-lambda-function-java
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-call-api.html
https://github.com/vaquarkhan/Serverless-AWS-Lambda-guide/blob/master/01-aws-lambda-serverless-framework/02-building-rest-api-in-nodejs-with-lambda-gateway.md
https://www.puresec.io/blog/aws-security-best-practices-for-api-gateway
https://www.stackery.io/blog/serverless-function-architecture-principles/
https://technology.finra.org/code/enjoying-auto-scaling-integrated-authentication-low-host-cost.html
You need to choose Lambda Proxy Integrations when you set up your API Gateway. Here's official document Set up Lambda Proxy Integrations in API Gateway.
In this case, API Gateway will pass the whole request data to Lambda, including the request headers, query string parameters, URL path variables and so on. Then you can parse the data using your Java code.
I am trying to configure spring integration using annotation. Instead of payloadqnameendpoint mapping I would like to use URI endpoint mapping. I found many examples with default URI endpoint but I required an annotation example without default end point.
Let's take a look to the AnnotationActionEndpointMapping support in the Spring WS! As you see it is based on the division between POJO methods and annotations on the them. The POJO is a main word there. This kind of framework magic allow us to separate low-level protocol from end-application business logic. From other side Spring Integration's AbstractWebServiceInboundGateway implements MessageEndpoint meaning that the whole SOAP hard work will be done in this implementation. It isn't a POJO.
Of course this topic is a different story, but you should understand from here that MessageEndpoint and MethodEndpoint work a bit different. At least they do messaging logic from different levels of SOAP request.
So, we really can't map <int-ws:inbound-gateway> with #Action or similar just because it is a whole SOAP endpoint already.
From other side, having AnnotationActionEndpointMapping from Java config, you can fully get rid of <int-ws:inbound-gateway> and configure your Endpoint to delegate desired #Action to the methods of #MessagingGateway. And it will work beucase the hard SOAP work has been done already by Spring WS framework.
I don't know you that this code will work, but you can check or let me know and I'll test it and come back to again:
#Endpoint
#MessagingGateway
public interface OrderEndpoint {
#Action("http://samples/RequestOrder")
#Gateway(requestChannel = "getOrderChannel")
Order getOrder(OrderRequest orderRequest);
#Action("http://samples/CreateOrder")
#Gateway(requestChannel = "createOrderChannel")
void order(Order order);
}
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();
I'm writing some functional tests in play, however I want to test my stack isolated from other http endpoints.
Is there a mechanism for me to say "Direct WS calls to this set of canned responses" or some other way of stubbing out calls to http endpoints that won't be available for automated tests?
Alternatively, how does fakeApplication config get presented to the rest of the application so I can just set the URL to some localhost server which I'll build myself to provide canned responses
You could create a structural type that mimics the WS signature and use that in your code.
type WSLike = {
def url(url: String): WSRequestHolder
}
Then you can inject your own version of a WSLike class. In combination with a mock library I guess you could do about anything you want.
As for the second question. You could call it like this:
val url = Play.current.configuration
.getString("my.webservice.url")
.getOrElse(throw new PlayException(
"Configuration error",
"Could not find my.webservice.url in settings"))
WS.url(url)
Then in your application.conf add the correct url. You can supply a different one using the FakeApplication.
FakeApplication(additionalConfiguration =
Map("my.webservice.url" -> "http://localhost/service"))
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.