abdera-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From James Snell <jasn...@gmail.com>
Subject Non-blocking operations in Abdera2...
Date Fri, 30 Dec 2011 23:24:09 GMT
I've been going through an updating the documentation for Abdera2 to
highlight the various new features. As part of that effort, I've been
playing around with a few of the new capabilities. One of the
particularly interesting ones is that the integration with the Guava
Libraries Function and Concurrency utilities allows applications built
with Abdera2 to leverage a variety of non-blocking mechanisms. For
instance, it's now possible to encrypt, decrypt, digitally sign and
verify signatures on Atom documents without blocking the current
thread of execution. Here's a quick example...

First, we need to prepare the encryption provider (we use Bouncy
Castle by default)


    KeyHelper.prepareDefaultJceProvider();

 Now the cipher key...
    String jceAlgorithmName = "AES";
    KeyGenerator keyGenerator =
        KeyGenerator.getInstance(jceAlgorithmName);
    keyGenerator.init(128);
    SecretKey key = keyGenerator.generateKey();

Create the entry to be encrypted...
    Abdera abdera = Abdera.getInstance();
    Entry entry = abdera.newEntry();
    entry.setId("http://example.org/foo/entry");
    entry.setUpdatedNow();
    entry.setTitle("This is an entry");
    entry.setContentAsXhtml("This <b>is</b> <i>markup</i>");
    entry.addAuthor("James");
    entry.addLink("http://www.example.org");

Here's where it starts to get fun... The security api has been
revamped and simplified in Abdera2...

    Security absec = new Security(abdera);

The EncryptionOptions class is now immutable and threadsafe using the
new common factory pattern...
    EncryptionOptions options =
      absec.getEncryption().getDefaultEncryptionOptions()
        .dataEncryptionKey(key).get();

Abdera2 uses the Guava Library to provide a Function object that wraps
the encryption logic, we can then in turn wrap that function with a
"Future Function", an Abdera2 concept that allows a Guava Function to
be be executed within a separate thread. All we need to do is pass in
an ExecutorService instance...

    ExecutorService exec = MoreExecutors2.getExitingExecutor();

    Function<Document<Element>,Future<Document<Element>>> ff =
      MoreFunctions.futureFunction(
        absec.encryptor(options),
        exec);

Now we can call our non-blocking encryption function...
    Future<Document<Element>> future =
      ff.apply(entry.getDocument());

The Future returned by the function is an instance of the Guava
ListenableFuture interface, allowing us to attach a listener that will
wait for the completion of the encryption operation without blocking
the current thread...

    com.google.common.util.concurrent.Futures.addCallback(
      (ListenableFuture<Document<Element>>) future,
      new FutureCallback<Document<Element>>() {
        public void onSuccess(Document<Element> result) {
          try {
            System.out.println("The results:");
            result.writeTo(System.out);
          } catch (Throwable t) {
            t.printStackTrace();
          }
        }
        public void onFailure(Throwable t) {
          t.printStackTrace();
        }
      },exec);

And that's it... non-blocking encryption of an Atom document. There
are ways that I can compose that together with the digital signature
capability to perform signing and encrypting in a single non-blocking
operation.

This is good stuff :-)

Mime
View raw message