Friday, April 29, 2011

CXF JAX-RS: Moving ahead with WS-Trust integration

Making sure existing WS-Trust STS services can be used to enforce the security of deployed web services is of high importance to customers who have invested into WS-Trust based security solutions. It's just a common sense for them.

CXF provides some very advanced support for securing communications between JAX-WS consumers and providers and delegating to STS for validating the security tokens. CXF JAX-RS endpoints rely on HTTPS. That is as far as it can get at the moment. That is sufficient in many cases but the fundamental issue is that customers who want to use STS can not depend on it for additionally securing JAX-RS endpoints.

Now, I've seen people talking about RESTifying STS services, i.e, making sure plain HTTP consumers can talk to it. That is probably a worthy idea as it is likely will make it easier to communicate with STS. It does not solve the issue of using STS for validating all sort of security tokens (SAML assertions, etc) though.

But the thing is that in CXF we have a very good integration between JAX-WS and JAX-RS frontends.
Reusing JAX-WS and WS-Security runtimes for talking to STS is the fastest and most effective way to ensure JAX-RS endpoints can also be protected with STS.

Right now, we've done a very small step forward, we can get Basic Authentication credentials validated by STS, see this section for more info.

More work will have to be done for supporting SAML assertions passed via HTTPS or as part of XML security protected payloads.

OAuth and OpenId are also there. CAS is there. Other efforts are under way. These are of interest to us. We have a brilliant OAuth contribution from Łukasz Moreń in the CXF sandbox. But at this stage the integration with WS-Trust/STS is of high priority.

Stay tuned!

Thursday, April 28, 2011

Transform Feature demonstrated in Talend Service Factory 2.4.0

Talend Service Factory 2.4.0 has several new advanced demos shipped as part of the examples distribution.

Please check Glen's blog for the information about WS-Trust and WS-SecurityPolicy demos.

Here I would like to describe a "jaxrs-jaxws-transformations" demo which shows the new Transform Feature at its best.

Many options for enhancing the existing XML schemas are possible. Usually, a namespace gets changed to indicate a breaking change to do with reordering elements, changing their names or structure or introducing new elements into a type with a closed schema content. Things are more complicated in the real world where best practices can require namespace changes for all updates made to a given schema.

The demo 'works' with the case where a Customer type has had a new optional property added to it. In addition, the namespace has also been modified, even though we are not dealing with the breaking update here.

The demo shows how:

* old and new JAX-RS clients can talk to existing (old) and new JAX-RS endpoints respectively - usual case
* old and new JAX-WS clients can talk to existing (old) and new JAX-WS endpoints respectively - usual case

Next, it shows how:

* new JAX-RS clients can talk to old JAX-RS endpoints
* new JAX-WS clients can talk to old JAX-WS endpoints

and

* old JAX-RS clients can talk to new JAX-RS endpoints
* old JAX-WS clients can talk to new JAX-WS endpoints

In this latter case, with old clients talking to new endpoints, two assumptions are made. First one is that the old clients know they are talking to new endpoints and thus Transform Feature affecting outgoing and incoming payloads is applied on the client side. Second one is that clients do not know that new endpoints will be used to handle their requests - the server side redirection and Transform Feature are used in tandem to make it work.

Finally, XMLSource is also shown in action on the client side.

This is a fairly involved demo trying to show how backward and forward compatibility may get achieved.

Try this demo and see if you can find it useful for the work you do in the real world.

Enjoy !

Tuesday, April 19, 2011

Building FIQL queries in CXF

Building FIQL queries is not a difficult process. Typical queries are simple enough to build them manually, for example:

_s=id=le=123

More complex queries relying on 'and' or 'or' conditions (possibly composed with each other) and multiple operators are a bit more tedious and complex to build.

CXF 2.4.0 introduces a SearchConditionBuilder utility class (thanks to Andy Michalec) which can be used to simplify building FIQL queries and working with CXF JAX-RS endpoints already supporting FIQL queries.

Have a look please at this section, try SearchConditionBuilder and provide the feedback.

Thursday, April 14, 2011

Transforming XML in CXF

Working with XML based web services does not only involve having a proxy or HTTP client invoking on the remote endpoint with the underlying data-binding magically populating a given bean instance with the values contained in XML tags.

Working with XML also implies that some care has to be taken for all those clients distributed all over the enterprise and the WEB at large be able to consume the existing and newer endpoints.

If you have a newer endpoint deployed that can handle the payloads from the older clients then the backward compatibility is maintained. If the validation is enabled then this is usually achieved by adding optional elements to the updated schema.

What happens if you have so many endpoints that they have to be gradually replaced by newer ones, should newer clients be blocked from consuming the old endpoints ? Is it really needed if all the new payloads add is some ignorable content that makes the information about a given concept more complete for newer endpoints ? Is it even realistic as in the case of the WEB ? Is telling such clients 'wait, the endpoint is being upgraded' is the cheapest/simplest option ?

This is where the forward compatibility comes in and it implies that the unrecognized content has to be ignored. Disabling the validation is not always safe as the newer clients providing new content can expect that that new content has been processed into account as opposed to being ignored. Validation will prevent the important unrecognized tags from being dropped. But it also will prevent the forward compatibility altogether.

The new CXF Transform Feature has been introduced and hopefully it will help users with resolving all sorts of backward and forward compatibility issues. CXF JAX-WS and JAX-RS endpoints and clients can be configured for namespaces be dropped or changed, elements dropped, changed or appended to existing elements. This is all realized at the STAX XMLStreamReader and XMLStreamWriter levels so it is fast and effective.

Does your web service need to talk to the legacy server which does not understand what namespaces are ? Do you need to consume a response from the newer endpoint which has a new namespace introduced ? Do you need certain elements ignored or dropped on the input/output ?

Use the transformation feature, get inspired and write the services which just work and don't cause all the clients be recompiled/updated whenever a minor change to the new endpoint has been applied. Have the web service clients talking to a variety of endpoints without changing the code.

The use of the transform feature in combination with the servlet-based redirection allows for replacing the old endpoints with the new ones and redirecting the requests from the old clients to the new endpoints. Which is quite cool. See this web.xml (CXFServletV1 redirects to CXFServletV2, effectively changing final URI path from /v1/rest-transform to /v2/rest-transform), with CXFServletV2 serving a jaxrs:endpoint with the "restTransform" id, the last jaxrs endpoint in this beans.xml. Note this endpoint relies on the transform feature which drops the namespaces from the inbound payloads and changes the name of the outbound element, only for redirected requests - so that V1 clients can talk to V2 endpoints without V2 clients being affected.

Finally, if you use the default CXF JAX-RS JSONProvider then the transform feature can be applied to input/output JSON sequences too, surely you don't want the JSON clients failing to parse the JSON data if you happen to add one more property to the JAXB bean which is used to produce a JSON sequence :-).

Most of it can also be done by custom CXF interceptors as well, which can register custom STAX handlers or use XSLT or XPath. I've updated the Advanced XML section on the CXF JAX-RS wiki, have a look please.

Jettison 1.3 is released

As it happens, Dan and Dejan have let me manage the Jettison project from now on. And thus I'm happy to announce that Jettison 1.3 has been released.

Jettison 1.3 has had two patches from CXF users applied.

MappedXMLStreamReader can now read top-level explicit arrays containing qualified and unqualified tags - this allows JAXB to deserialize such JSON sequences into explicit collections (lists, etc). For this to work, the support for older convention assuming a top-level array may only contain a single node had to be dropped. Additionally, simple tags explicitly set to null have no CHARACTER events reported.

I think the good news is that Jettison will keep moving forward. One thing I'd like to clarify is that I won't be actively working with Jettison - however you can definitely expect patches addressing open JIRA issues being applied. Jettison has a small code base, so if you use it and see some issue then just check out the trunk and create a patch.

This latest release has really being driven by lingering issues opened against CXF JAX-RS but you don't have to use CXF for Jettison JIRAs be fixed - if you like working with Jettison then providing a patch is the only thing you need to do for the given issue be addressed :-)