This document at this point represents the end state of the codec subsystem. We are presently trying to get to this state. The point is this is where we want to be and by documenting it we can all align towards this end state.

Final Configuration

The codec is an extensible subsystem enabling extension for new controls and extended operations. It hides internal implementation details as much as possible exposing a very simple API for using it for embedding purposes. An SPI is provided for those extending it while still exposing as little as possible, however much more is exposed by the SPI to enable pluggable controls and extended operations.

The codec is naturally embedded into the client API, studio and the server. Although we don't foresee many using the API, it helps us keep the embedding interface as small as possible for our internal projects. Then again others may have a reason for embedding the codec into their applications. By making this portion of the codec into a separate jar/bundle and only depending on it in our projects, we can be certain to prevent implementation creep into the rest of our stack.

The codec exposes much more in its SPI for those wanting to extend it with new controls and extended operations. This SPI is a separate module in itself. This makes sure more implementation details do not seep into higher levels in our project yet making sure all necessary details are exposed to extenders.

Control and Extended Operation Modularity

Although we just talk about controls, this also applies to extended operations as well which use the same mechanism.

The extension mechanism uses OSGi. Control bundles are provided by developers and loaded. On load, via activators, the control bundles register their ControlFactory implementations with the LdapCodecService. Bundle providers should only export their control interface and perhaps optionally a simple implementation of their control. The bundle should contain the following items:

Class

Visibility

Purpose

Foo

(thumbs up)

An interface for your Foo control

FooImpl

(thumbs up)

A simple implementation of your Foo control

FooFactory

(thumbs down)

Factory for your control

FooDecorator

(thumbs down)

Decorates your control so the codec can handle it while encoding and decoding

FooGrammar

(thumbs down)

The Grammar defining the transition states while decoding your control

FooContainer

(thumbs down)

A container for packaging your control but soon this might not be needed

Anything else

(thumbs down)

Up to you

You might have more than one control in your bundle. Whether you do or not, you'll want to keep all your control interfaces and simple implementations in a directory separate from your implementation classes. This way you can just export this package from your bundle. Client code outside of the codec will still want to use your control interfaces and classes while issuing them in various LDAP operations.

A Maven archetype will be made available to generate control and extension bundle projects so those wanting to extend the codec can start working quickly on new own controls and extensions.

Configuration and Loading

Either a specified directory or configuration parameters can be used to instruct the codec where to find extension bundles. We'll document that as we go.

Either the entire codec will run inside an OSGi environment (future goal) or it will use an embedded instance of Felix. Embedding Felix into the codec itself allows us to interface with bundles that can be dynamically loaded to register their controls and extended.

http://felix.apache.org/site/apache-felix-framework-launching-and-embedding.html

The codec top level directory is located under shared. It is a maven multi-project having the following directory layout:

codec/                       --> top level codec directory under shared/
   internal/                 --> codec internals: things we want hidden to everyone
   api/                      --> codec's public API needed to embed it and use it only
   spi/                      --> codec's service provider interface needed to extend it
   controls/                 --> top level for control extensions
      replication/             --> for example replication controls
      ppolicy/                 --> or the password policy controls
      .../                     --> many more may come ...
   extended/                 --> top level for extended request and response extensions 
      cancel/                  --> cancel operations
      certGeneration/          --> certificate generation requests
      storedProcedure/         --> for stored procedure operations
      .../                     --> many more may come ...

Future

In the future it would be nice to have the SPI really be an annotation library. Users annotate their control interface and this is the only Java artifact in their extension bundle. The codec on registration of this interface (instead of the old factory method), reads the annotations to determine how to build the grammar, container, and decorator. It also generates the simple implementation. This is all done dynamically at registration time.

ASM can be used to create these classes or something more dynamic can be used to avoid runtime class generation. The annotations can be simple instructions about the ASN.1 composition of the Control interface properties. With such a system writing new controls would be very easy to do.

Studio can also provide tooling support for those who want to build and deploy a new control. It can help them design the control with annotations, and help test the operation of the control to verify it's correct definition with round trip tests that are automatically generated. This can take out the tediousness from the entire process and rapidly speed up enhancements to the client, the server and even to studio.

  • No labels