You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@abdera.apache.org by James Snell <ja...@gmail.com> on 2011/12/31 00:24:09 UTC

Non-blocking operations in Abdera2...

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 :-)

Re: Non-blocking operations in Abdera2...

Posted by Chad Lung <ch...@gmail.com>.
Wow, this is some powerful stuff!  Thanks for the post James.

Chad


On Fri, Dec 30, 2011 at 5:24 PM, James Snell <ja...@gmail.com> wrote:

> 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 :-)
>