spring web-services transform namespace before endpoint-selection - spring-ws

is it possible to transform a request-body in a spring-ws interceptor before the endpoint-selection takes place. The client who calls us uses a different xml-namespace (but the same schema, don't ask why facepalm)
the Payload-interceptor described here http://static.springsource.org/spring-ws/sites/2.0/reference/html/server.html#server-endpoint-interceptor can only be applied after an endpoint was selected. But since our endpoint is mapped with #PayloadRoot and the namespace and localPart the messageDispatcher cannot find an applicable endpoint and rejects further processing

I think you need to take a look at the PayloadTransformingInterceptor. That can be used to transform the incoming message. Using this you can support multiple versions of your WSDL for instance.

Related

Fn project is missing http operations (CRUD)

I have spent my afternoon getting very excited about the container-native serverless platform 'fn project' - http://fnproject.io/.
I love the idea of the FaaS model but have no intention of locking myself into a particular cloud vendor for most of the lifetime of an app - and several other reasons including the desire to spin up the entire app on a small server anywhere if I choose.
fn project seems great for my needs until I finish perusing the documentation and all the relevant blog posts and suddenly think 'what? Wait....what??? Where are the http operations?'.
I cannot find a single reference anywhere that states if it is even possible to to have http triggers for different http operations (ie POST, PUT, PATCH, DELETE), let alone how I would do it.
I want to build REST api's (or certainly at the very least json-serving http-based RPC apis - if it doesn't have hypermedia links it isn't REST ;) but let's not get into that one in this thread)
Am I missing something here (certainly the correct bit of documentation)??
Can anybody please enlighten me as to how I would do this, or even tell me if I have totally misunderstood what I should use this for?
My excitement has gone soft for now but I'm hoping someone that will change with the right information.
It feels odd that I can't find anyone else complaining about this, so I think that indicates my misunderstanding perhaps.
Other solutions such as OpenFaaS look interesting but I dont wan't to have to learn how to deploy kubernetes and docker swarms if I can avoid it :)
I'm not an expert, but as of now it seems not possible to specify the http method inside the trigger. Check latest trigger spec : as you can see, there is no notion of http method here.
However, handling different HTTP methods can be done inside the function itself.
For example, in Java (with fdk-java v1.0.80), you can use com.fnproject.fn.api.httpgateway.HTTPGatewayContext as the first parameter of the function, as described in the section "Accessing HTTP Information From Functions" of the documentation :
In Fn for Java, when your function is being served by an HTTP trigger (or another compatible HTTP gateway) you can get access to both the incoming request headers for your function by adding a 'com.fnproject.fn.api.httpgateway.HTTPGatewayContext' parameter to your function's parameters.
Using this allows you to :
...
Access the method and request URL for the trigger
...
You can then retrieve the HTTP method by calling getMethod() on the HTTPGatewayContext passed as parameter.
In other languages (with others fdk), it's possible to do the same :
in Go : example calling RequestMethod() on context
in Ruby : class HTTPContext
in Python : class HTTPGatewayContext
in Node : class HTTPGatewayContext
From this different contexts, you'll then be able to get method parameter passed when fn invoke --method=[GET|POST|...] (via fn-http-method header).
The main drawback here is that all HTTP methods should be handled in the same function. Nonetheless, you can structure your code to have only one class per method.
After some further thought it seems fairly clear now what my actual misunderstanding was....
When I have built Serverless framework services in the past (or built and deployed Lambda functions using terraform) I have been deploying to AWS and so have been using AWS's API Gateway offering (their product is actually called API gateway but its important to recognise that API Gateway is a distributed systems / micro-sevices design pattern).
API gateway makes it possible to route specific http request types including the method (GET,POST,PUT,DELETE) to the desired functions.
Platforms such as Fn project and OpenFaaS do not provide an out of the box api gateway solution and it seems we would need to take care of this ourselves.
These above mentioned platforms are about deployment of functions. We find the other bits via our product of choice.

Is there a way to use Swagger just for validation without using the whole framework?

Suppose I have an existing Java service implementing a JSON HTTP API, and I want to add a Swagger schema and automatically validate requests and responses against it without retooling the service to use the Swagger framework / code generation. Is there anything providing a Java API that I can tie into and pass info about the requests / responses to validate?
(Just using a JSON schema validator would mean manually implementing a lot of the additional features in Swagger.)
I don't think there's anything ready to do this alone, but you can easily do this by the following:
Grab the SchemaValidator from the Swagger Inflector project. You can use this to validate inbound and outbound payloads
Assign a schema portion to your request/response definitions. That means you'll need to assign a specific section of the JSON schema to your operations
Create a filter for your API to grab the payloads and use the schema
That will let you easily see if the payloads match the expected structure.
Of course, this is all done for you automatically with Inflector but there should be enough of the raw components to help you do this inside your own implementation

Spring-WS payload based endpoint mapping unsuccessful in case of WS-Security Encryption

When using PayloadRootAnnotationMethodEndpointMapping together with WS-Security Encryption, I get this error: [EndpointNotFound] No endpoint mapping found for [SaajSoapMessage {http://www.w3.org/2001/04/xmlenc#}EncryptedData]
Spring WS wants first finding the right Endpoint, and only later decrypts the SOAP body. This is obviously not the right thing to do.
Please dont tell me that the SoapActionAnnotationMethodEndpointMapping is the solution. Is not there a better way? I would not like routing based on SOAP Action or WS-A Action.
Unfortunately, using the SoapActionAnnotationMethodEndpointMapping or AnnotationActionEndpointMapping are the only provided mappings you can use. In Spring-WS, the EndpointMapping is queried before any of the interceptors are invoked - including the security interceptor, and such you have to find a mapping that does not depend on the encrypted message payload.
That said, since EndpointMapping is an interface, you can also write your own, and include any kind of routing logic you can think of. Extending from AbstractAnnotationMethodEndpointMapping is a good start for this approach. When your mapping is done, just wire it up in the application context and it should be detected automatically by Spring-WS's MessageDispatcher.

ServiceMix + broadcasting message

New to ServiceMix, I'm not sure if it can do what I need:
I've an interface defined by wsdl
I have several endpoints that implement that interface defined by the wsdl
I've a service that can only send the message to one endpoint.
Can service mix do the following:
Producer sends to an endpoint in servicemix (with the wsdl).
ServiceMix broadcasts to the different endpoints the message.
Thanks for the advice and / or pointers!
The simplest would be to use a Camel Recipient List. This would allow you to have either static or dynamic destinations for your broadcast.
It sounds as if your application doesn't require termination of the SOAP message (de/serialize the payload to/from an object) at the ServiceMix consumer. Therefore it can be kept very simple by using a Camel Jetty proxy:
There are further details on the link above on how to configure static (the example above) and dynamic routing.
If your application changes and does require termination of the SOAP message at the ServiceMix consumer in the future, then change out the Camel Jetty consumer endpoint with a Camel CXF endpoint and set bridgeEndpoint to false.
As for ServiceMix you will need to enable the Camel Jetty component. To have it enabled by default you need to edit the etc/org.apache.karaf.features.cfg file and add camel-jetty to the featuresBoot property. This is typically the best practice for features required by your application. You can also install the feature at the ServiceMix console with the command "features:install camel-jetty".
The Recipient List capability is part of the Camel Core API which is installed by default and if not, as a dependency of any other Camel component.
Best Regards,
Scott ES

What is the "Best Practice" for SOAP servers to implement error notification?

I am developing some SOAP web services using Ruby on Rails and considering how to handle generic failures. These generic errors are applicable to all the methods within the service and include the following :-
Missing Request element
Missing Authentication element (Custom)
Invalid Authentication details
I can intercept these errors within my controller before calling the relevant method and respond appropriately. My question is which implementation is easiest to manage from a Client perspective. My options for handling these errors seem to be as follows.
Raise an exception and let the SOAP service generate a SoapFault. This would be fine except I have little (no) control over the structure of the message contained within the SOAP fault.
Return an Http 400 response with an agreed data structure to indicate the error message. This structure would not be defined within the WSDL though.
Include a Status element in all responses, whether successful or not and have that status element include a code and an array of error data (Including error messages).
Option three seems like the best solution but is also the most error prone to implement as the implementation of web services in ROR precludes me from implementing this in a generic way and each method becomes responsible for checking the result of the checks and rendering an appropriate response. Admittedly this would be a single function call and return on failure but it is relying on the developer to remember to do this as we add more options.
I appreciate that most ROR developers will say that this should be implemented as a REST service and I agree, in fact we already have REST services to do this but the spread of SOAP in the corporate world, and its impressive tooling support means that we have to provide SOAP services to remain competitive.
In your experience what would be the easiest implementation for clients to handle and does this differ dependant upon the libraries/language of the client process.
A SoapFault would be the preferred way to signify errors. SoapFaults can contain additional information in their <detail> element.
The advantage of a SoapFault over some status element is that the caller can use standard exception handling, instead of checking for some status field.

Resources