Resteasy 2.3.5 Released

2 Comments

After a bit of delay, Resteasy 2.3.5 is finally out.  It is pretty much a maintenance release.  I want to thank Ron Sigal and Wei Nan Li.  They did almost all the work for this release (minus patches submitted by users).  Resteasy 3.0 beta later this week!

Go to Resteasy website for links on how to download, you can check out the release notes too.

What should be in next Restful Java Book?

9 Comments

JAX-RS 2.0 is around the corner. We’re ironing things out in the JSR group and alpha implementations should be out soon along with the public draft. I talked to O’Reilly and the sales of my Restul Java book were good enough to justify a revision. So…

What do you want in Restful Java 2.0?

The obvious things are new spec features, specifically new chapters on:

  • Client API
  • Filters and Interceptors
  • Asynchronous HTTP

There’s a few other minor features that will be sprinkled about in existing chapters of the book.  We’ll also need to update the Java EE integration section as when the book was written, it hadn’t really be finalized yet.

For the filters and interceptors chapter, I was thinking about walking through (with code examples) the use cases that were the inspiration for these features in the spec.

For the asynchronous HTTP chapter, I was thinking of using/implementing  a slimmed down simple version of the HornetQ REST interface.  That way I can throw in bits about Atom as well as some useful restful patterns.

For security, I was thinking of talking a bit more about Resteasy’s S/MIME and DKIM support and how they fit into the security picture.  We could also talk about OAuth too.

What else?  Please comment.

Resteasy 2.3.1 Released

1 Comment

This is a maitenance release of 2.3.x series.

As always, to download and see documentation follow the links from our website.  Take a look at our Jira release notes.  You might also want to check out the Migration guide to view what has broken as far as backward compatibility if you’re upgrading from an earlier version.

Resteasy 2.3-RC1 Released, Please Testdrive!

3 Comments

Resteasy 2.3-RC1 has just been released.  Please follows links on main resteasy page to see documentation and download links.  We do have some backward-incompatibilities, so see the Migration Guide.  If you can, please testdrive it!  We will be doing a 2.3.GA release in 2 weeks so its up to you to find any critical blocker bugs we might have introduced!

After 2.3 is released we will be starting to work on Resteasy 3.0, a JAX-RS 2.0 implementation.  In conjunction we will also be moving source control to github.

Resteasy 2.2.2 Released

Leave a comment

This is just a maintenance release to fix a few minor and critical bugs found by the community.  You can download 2.2.2 here.  Release notes are here.

Hopefully we can now focus on getting a 2.3 beta out the door.  Currently I’m working on S/MIME integration as well as a decentralized auth protocol discussed in previous blogs.

Resteasy 2.2.1 Released

4 Comments

This is just a maintenance release to fix a few minor and critical bugs found by the community.  You can download 2.2.1 here.  Release notes are here.

Resteasy 2.2 Released

2 Comments

After baking in the oven the last few months, Resteasy 2.2 has been released to the world and is available for download.  You can view our documentation here.  We fixed a lot of bugs since the 2.1 release which can be viewed in the release notes of previous beta and RC releases:

Features wise we’re starting to focus on security solutions for RESTful web services.  In this release we focused on a digital signature framework based on DOSETA and DKIM.  I wrote a blog a few months ago about some possible use cases for digital signatures.  It will be interesting to see how people use our digitial signature framework, but more importantly how and if they want to use the DOSETA and DKIM protocols for digital signature propagation.  We are extremely interested in feedback and suggestions for improving the protocol and how it might solve (or not solve) any security use cases you might have.

Beyond that, writing the digital signature framework also helped to flush out the Resteasy interceptor API.  For instance, we found that it was very useful to hold off marshalling header objects into string formats until the stream is written to.  This allowed us to pass information through header objects to the interceptors that are performing signing and verification.  Writing down these requirements will be very applicable to the JAX-RS 2.0 JSR as we’re currently focusing on interceptors there.

What’s Next?

Further 2.x releases will focus mainly on adding security features.  We’re also going to be developing Resteasy 3.0 in parallel.  Here’s some points:

  • message body encryption with both multipart/encrypted and develop a new Content-Encoding. This will also help us flush out interceptors more I think
  • SAML/Picketlink. I think we may be able to integrate with SAML, specifically Picketlink to provide some hub/spoke authentication/authorization.
  • Clean up our OAuth support.
  • JAX-RS 2.0 has started which we will implement in Resteasy 3.0. The client API is shaping out and I might deliver a prototype of it when the next revision is submitted by the JAX-RS spec leads.

Interceptors in JAX-RS 2.0

1 Comment

If you don’t know already, JAX-RS 2.0 JSR has started.  Right now things are focused on the Client API and also interceptor model.  The initial proposal for the client API and its corresponding interceptor model is based on Jersey:

I’ve submitted a counter proposal that tries to simplify the class hierarchy and model interceptors based more on what Resteasy has to offer.

Santiago Pericas-Geertsen, one of the spec leads, recently blogged about another proposed interceptor model.  He does a great job of setting some precedence by looking at EJB and CDI interception models.  I think there are some requirements he has overlooked though with his initial proposal that I’d like to address in this blog (and that is addressed in the Red Hat proposal linked above).

Interceptor Use Cases

Resteasy’s interceptor model was driven by use cases.  There were a bunch of features I, and others, wanted Resteasy to have and an interceptor model provided the needed abstractions to implement these features.  Specifically:

  • Server-side custom security
  • Client response caching
  • Sever response caching
  • content encoding: GZIP
  • Header decoration: i.e. annotations that add Cache-Control header
  • Digital Signature generation: the DKIM stuff I’ve been working on lately

All these features have been implemented using our interceptor model.  Another feature I want to add, that I also think might effect the requirements of an interceptor API is:

  • Message Body encryption and the ability to transparently handle it for the client or server.

Interceptor Requirements

Interceptor APIs aren’t a new thing.  They have been implemented in many different frameworks over the years.  One thing that I think throws a wrench in JAX-RS is asynchronous invocations (both on client and server side).  Asynchronous HTTP has become pretty popular both on client and server side.  In this case, different threads may post a request and process the response.

An interceptor model much take into account asynchronous invocations

The Red Hat proposal has 4 different types of interceptors:  Pre, Post, Reader, and Writer.  They are invoked in the following way on the client (pseudo code):

public ClientResponse execute(...) {
  ClientResponse response = invokePreProcessors();

  if (res == null) {
     invokeWriterInterceptors();
     response = invokeHttpInvocation();
  }

  response = invokePostProcessors();
  return response;
}
// application code
ClientResponse response = execute(...);
Something Something = response.getEntity(Something.class); // application acquires entity

// getEntity() invokes ReaderInterceptors.

The server side pseudo code would be very similar.  Why the need for 4 interfaces? 4 interception points?  What is the purpose of each interception point?  Let’s look at our original list of use cases to see:

  • First and foremost, we need to be able to support an asynchronous model.  On the client, different threads may be sending and processing requests and responses.  This is the reason for the pre and post splits.
  • Notice that if a pre-processor returns a response object, no HTTP invocation is done.  Client cache use case needs this because it may have the requested entity cached.  In that scenario, HTTP invocation will want to be circumvented.
  • On the server, with custom security, a pre-processor needs to be able to abort an incoming invocation before it reaches the JAX-RS method if the request is not authenticated.
  • A pre-processor may want to decorate request headers.  The client cache implementation will want to set If-None-Match and If-Modified-Since headers if it believes a cached entry is stale (to perform a conditional GET).

So, thats all the things that might be done be a pre-processor.

What is a WriterInterceptor for? Why is a specific WriterInterceptor needed instead of just piggy backing off of the pre-processor (on client) or post processor (on server).

  • There are two separate use cases for WriterInterceptors.  GZIP encoding and Digital Signatures.  A GZIP WriterInterceptor needs to compress the outgoing response, so it needs to wrap the OutputStream in a GzipOutputStream.  For Digital Signatures (in the DKIM case), a hash of the body needs to be calculated and added to the DKIM-Signature request (client-side) or response (server-side) header.  THis means the outgoing body needs to be buffered as well as hashed so that the header can be set before the body is written.
  • Why a separate interface from pre-processor (client) post-processor (server)? The most compelling reason to have a separate WriterInterceptor is reusability on client and server.  Writer interception happens in different places from the client and server.  Client it happens during request pre-processing.  SErver it happens during response post-processing.
  • Another reason for a separate interface is that a WriterInterceptor has a clear order and interception point.  A client cache interceptor wants to avoid streaming an entity body altogether.  While a content-encoding interceptor wants to intercept stream output.

What are post-processors for?  Why the separation/distinction of a ReaderInterceptor compared to a PostProcessor?

  • On the client side, a cache interceptor will want to cache the raw bits of a response entity *BEFORE* it is unmarshalled.  Also, based on the status code (i.e. NOT MODIFIED), it may want to pull an entry from the cache itself and set the input stream and override some response headers.  A post processor would be used for this.
  • One of the problems on the client is that application code basically needs to decide when unmarshalling happens.  Application code may make decisions based on a status code and/or a response header before it decides how a entity body is unmarshalled, or even if it is unmarshalled.  Because a cross cutting concern (like caching) may need to modify a response code or header, you need this distinction between post processing of a response, and reader interception.
  • One last use case for post-processor is header decoration on the server side.  Think of a @CacheControl annotation that builds and sets a Cache-Control response header.

What are ReaderInterceptors used for?

  • decoding GZIP encoded streams.  Verifying digital signatures.
  • Like WriterInterceptors, it is nice to have the concept of a ReaderInterceptor as it can be used both on the client and server side.

Review of Requirements

Here’s a shorter list of requirements, without the explanation.  A few others are added in here without detailed explanation

  • Need to support both synchronous and asynchronous invocation styles seemlessy without a lot of redundant code.
  • ability to add/modify/remove headers from an outgoing or incoming request
  • ability to add/modify/remove headers from an outgoing or incoming response
  • Ability to abort/interrupt/bypass request processing and return a custom response
  • Ability to intercept before unmarshalling to add/modify/remove headers or change the status code.
  • You need to be able to pass information between interceptors.  Servlet API has request attributes.  Something similar is needed in a JAX-RS interceptor model
  • Interceptors need to be able to obtain metadata from the things they are intercepting.  They need to be able to introspect anntotations on the server side (on the client side too if we standardize Resteasy’s proxy framework).

Hopefully I didn’t miss anything here.

Interceptor ordering

Another thing to talk about is how should interceptors be ordered?  While interceptor developers should try to make their implementations as order independent as possible, this isn’t always possible.  If you are writing a library of interceptors you want to be usable by a wide variety of applications (like the ones we have in Resteasy), you don’t want to require any extra configuration by the user to specify interceptor ordering.  You want them to just be able to pick up interceptors just as they would automatically have their services scanned for and deployed.

To help mitigate this problem, Resteasy has the concept of logical ordering, or “named” precedence.  Resteasy defines a default set of precedence catagories:  SECURITY, HEADER_DECORATOR, DECODER, ENCODER.  If an application interceptor falls into one of these catagories, they just annotate their interceptor with the precendence catagory desired.  New catagories can be created and defined as coming before or after a preconfigured precedence catagory.

It probably doesn’t need to be that complicated.  In Santiago’s blog he suggested a numeric ordering.  What an application could do is define constants that represent a catagory.  Much easier to plug things in this way than the Resteasy model. 🙂

Anyways, this blog is getting quite long.  Hopefully I’ve articulated the use cases and requirements of interceptors good enough so that you can see that the Red Hat proposal is a sound one based on extensive experience using the model.  I also want to say that the JAX-RS 2.0 process seems to be moving along pretty smoothly.  With Paul and Roberto leaving so abruptly I was a little worried at first, but I think Santiago and Marek have things in hand.

Resteasy 2.2-beta-1 released with new digital signature framework

2 Comments

Fixed a lot of bugs check out jira.  Also some notable new features, specifically:

– Our new digital signature framework inspired by Greg Totsline.  This is the implementation and JAX-RS integration I was talking about the last few blogs.
– Improved interceptors a little bit by allowing attribute passing.

Hopefuly an RC release in April (about a month, I”m traveling a little bit the next month) followed by a quick GA release very soon after.  As always go to our main resteasy page for download and documentation links.

Adding objects that are @Context injectable

2 Comments

One thing I’ve forgotten to document thoroughly is how to add objects that are injectable via the @javax.ws.rs.core.Context.  Usually you’ll want to use CDI or Spring to inject your dependencies or configuration into a provider or a service, but you may have situations where you cannot depend on these facilities being available to you.

import org.jboss.resteasy.core.Dispatcher;

import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;

public class MyApplication extends Application
{
   public MyApplication(@Context Dispatcher dispatcher)
   {
      MyClass myInstance = new MyClass();
      dispatcher.getDefaultContextObjects().put(MyClass.class, myInstance);
   }

}

The myInstance variable is now available for injection via the @Context annotation.

Older Entries Newer Entries