Resources

If the following sections sound a little cryptic you might want to read a little about the IoC pattern. Below are some documents you might find useful when translating some of this babble:

Components and Services

The server is designed as a system of highly granular components. Some components are a collection of other components with a facade to form a subsystem of the server. Subsystems can contain other subsystems and one component can depend on zero or more other components.

A micro kernel or component container is required to run the server. By default the server uses its oun glue rather than a container with all the bells and whistles. However it can run in any micro kernel using service wrappers. A micro kernel is a peice of code operating as a component container providing services for that component and running the component through a set of life-cycles. The server is designed to run on any micro kernel using component wrappers. The subsystems and components are designed as Plain Old Java Interfaces and Objects (POJIs and POJOs) that can be wrapped to make them interoperate within different containers.

Each component within the server has a public service interface which declares what that component can do for its clients. It is always good to keep the interfaces separate from any specific implementations. You can have many implementations for the same service interface. Secondly the classloader heirarchy in containers often puts implementation classloaders under a classloader containing the service interface. This allows containers to manage multiple implementations for the same service without having conflicts. Also implementations can be created and destroyed in separate classloaders without affecting one another.

Container Independence

One of the biggest impediments we've had to deal with while developing the server and its precursors was having containers go in and out of fashion. We lost several months of development time while switching from Pheonix to Merlin for example. Today we use some custom glue instead.

The server has been designed this time from the ground up to be independent of any container. We are doing this by making the default implementation of a service a Plain Old Java Object (POJO). Wrapper implementation projects, one for each supported container, are used to wrap these POJO components to introduce container specific lifecycles and to encapsulate container idiosyncrasies.

This approach we have found has several advantagous side-effects. One benefit was a nice separation of concerns. By separating out the container specific code, configuration and build aspects, developers no longer need to be aware of container details. They can focus on the core implemenation as a simple class implementing an interface. Those interested in making the server run in one container as opposed to another can focus on their container wrapper without the clutter of another container getting in the way. This reduces the complexity and learning curve for all those involved in developing the directory server's components and subsystems.

Monitors Verse Loggers

Above we provided a link to Paul Hammant's concept of using Monitors in place of Logging. Briefly without restating his wiki we'd like to review how we use Monitors instead of Loggers alone.

Like any other server we need to log what goes on. But rather than log we need to monitor. Logging is a specific type of monitoring for the sake of archiving what we monitor. Paul proposed that every service should propose a very specific Monitor interface. This is a good idea because it is the responsibility of the service to announce those interesting, and monitoring worthy events. The interface forces signatures to explicitly describe what information is involved in the monitoring of an event.

This makes the component implementation logging system independent which is provided by a container implementation. Each wrapper implementation can provide its own Monitor implementation to interface with the Logging system of the target container.

We gain by becoming more container independent but more importantly we are forced to consider what events in a service constitutes a noteworthy event. This throught provoking aspect is perhaps the most beneficial.

Configuration Beans

Containers are neat because they give component developers a lot of nice features out of the box and that's what they should do. The key to maintaining container independence is to abstract away from these features while still taking advantage of them. This usually translates into a few extra interfaces and classes.

One benefit of containers is to provide a means to associate a configuration with a component. Most allow for configurations to be stored in properties files and/or XML files. Containers read and load the configuration as a part of processing the lifecycles of components.

Rather than have POJO component implementations depend directly on configuration interfaces specific to a container we explicitly define configuration beans. POJO implementations are then designed to take configuration beans as constructor arguments if the number of parameters is large and putting so many parameters into a constructor would be too cumbersome.

  • No labels