Hi everyone,

As I'm sure you've noticed, I've been doing a lot of work on 2.0, and so its 
time I took a break and explained some of the key changes, why I've made them, 
and what the current status is.

Project structure
============

I've broken the project down into a number of components, all built as Maven 
modules. So the server is now a component in its own right, as well as the 
parser and connector. I've replaced all of our Ant and Ivy scripting with Maven 
for all the Java components, but widgets are still built and deployed using Ant 
from within their own subproject. The server can run for development using 
Cargo, which deploys it using Tomcat.

Back when Wookie joined ASF I was initially not so keen on using Maven, but the 
experience of using it in Apache Rave has been useful in seeing how it can, if 
used appropriately, make a project easier to understand and extend, and other 
community members have commented before about the Wookie project structure 
being non-standard and therefore harder to get started with. So hopefully this 
change will make it easier for everyone to work with Wookie and to contribute 
new modules.

So how does the project now look? Well, inside wookie-project, the various 
sub-modules look like this:

wookie-services is where the service  integration lives. The core API is in the 
wookie-spi submodule (more on this below) and there are also the wookie-redis 
and wookie-jpa implementations.
wookie-features is where the runtime features live, so all the injected JS 
packages are here.
wookie-parser is the W3C parser Jar
wookie-widgets is where the widgets and templating system lives (thought maybe 
templates needs its own module)
wookie-server is the actual server itself.
wookie-connector is the connector framework

There is also the wookie-master module at the top level of our svn which is 
where common metadata is stored for all modules, such as committer names etc.

The pom.xml in wookie-project lists which modules are built, so if you create a 
new one, you can add it to the list.

You can build and run Wookie by following the instructions in BUILDING.

SPI
===
I've broken out the repository  management from the server into an SPI (service 
provider interface) package. 

This means that how Wookie stores user preferences, shared data and 
participants - and even the widget metadata - can be determined at runtime 
using dependency injection.

The injection mechanism I've put in place is the JDK built-in service loader, 
which doesn't have a lot of features but does have the benefit of being both 
simple and not requiring any other dependencies. For example, if you create a 
module that implements the Preferences SPI, you put the class name of your 
implementation in a single-line text file at:

wookie-server/src/main/resources/META-INF/services/org.apache.wookie.services.PreferencesService
 

… and as long as its on the classpath when the server starts, Wookie will use 
it.

The default implementations of the SPI are very simple in-memory hash tables 
and tree models, so Wookie can run without any database at all for simple 
testing. I've also created a Redis NoSQL SPI provider, and started porting the 
JPA code to work as an SPI provider (it doesn't work yet, as there is a lot to 
untangle). Other options could be an Apache Rave SPI, for example, or modules 
for MongoDB or cloud storage using AWS.

If you want to have a go at creating another SPI provider, take a look at the 
Redis one as an example as its fairly simple.

AuthToken
========

The concept of "WidgetInstance" has been replaced with that of an "AuthToken". 
This is an encrypted token based on the same concept (and some of the same 
code) used in Shindig for its security token implementation, and can convey the 
same information needed to contextualize a widget for a user and link it with 
stored preferences etc.

The tokens have an expiry time built in, so connectors will need to 
periodically refresh tokens; this will need thinking through as to what are 
good practices here that won't impact usability.

The main effect of AuthToken implementation is there is now no need to store 
"WidgetInstance" information, greatly simplifying the server back end.

HMAC-Signed REST API methods
===========================

In Wookie 1.0 we used an API key for REST calls, assuming that the connection 
itself should always be secured (e.g. using HTTPS, or not exposed outside an 
intranet). 

However in Wookie 2.0 I've implemented HMAC signatures on methods, based on the 
approach used for Amazon Web Services. This means that API messages are given a 
nonce, timestamped, and signed with a shared secret that is never transmitted 
across the network. 

The upshot of all this is that it is much more difficult to gain access to API 
calls even when made over the open web on an unencrypted connection.  It also 
means that in Wookie 2.0, if a secret is compromised for any reason, then it 
can be revoked and changed without needing to change any of the stored data - 
something that is quite tricky in Wookie 1.0.

This does require more work on the connector side to correctly sign messages, 
but I've implemented it in both Java and JavaScript successfully, and the code 
for other languages such as Python, PHP and Ruby looks like it could follow the 
examples given for connecting to AWS. If you have a look inside the 
implementing classes in the Java connector and in wookie-server you should be 
able to figure out what's needed, but I'll also write up a proper spec at some 
point.

What's next?
==========
The things I've listed above are primarily changes to the underlying structure 
of Wookie, and don't really impact the user much. However it should provide a 
basis for other improvements. For example, for some time we've also wanted to 
move away from DWR to a framework with better support for WebSockets and other 
new web technologies such as WebRTC, or perhaps use JSR-356.

I've finished my "refactoring sprint" for now so there should be no more major 
changes going in, so feel free to check out the 2.0 code in trunk and start 
working with it. If anything doesn't make sense, just ask.

Have fun!

-S

Attachment: PGP.sig
Description: This is a digitally signed message part

Reply via email to