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 |
An interface for your Foo control |
|
FooImpl |
A simple implementation of your Foo control |
|
FooFactory |
Factory for your control |
|
FooDecorator |
Decorates your control so the codec can handle it while encoding and decoding |
|
FooGrammar |
The Grammar defining the transition states while decoding your control |
|
FooContainer |
A container for packaging your control but soon this might not be needed |
|
Anything else |
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.