Skip to content
Roland Huß edited this page Mar 25, 2013 · 1 revision

In order to keep the core small and allow for more controlled extensions points sharing the same mechanism, Jolokia needs to be refactored to support the various needs. This document describes the current situation, the requirements and the various ways to lookup services. A targeted solution should not reinvent the wheel, but add a meta layer on top of the various lookup mechanisms, so that the Jolokia agent, which is targett=ed to run in many different environments can be easily managed and extended. In the future, there won't be that "single" Jolokia agent, but various variants ("pure","all","jumbo",...) containing different services and it must be easy to assemble an own Jolokia agent a la carte.

For 2.0, every service implementation should be extracted into an own Maven module, even when this will add some performance and maintenance penalty to the build process. The art is to keep the right balance and to not go over board.

As global theme it is important that the size of the smallest agent for WAR, JVM and OSGi must still remain below 300k.

Current Services

RequestDispatcher

This dispatcher is repsonible for dispatching request to so called RequestHandler. Currently there exist 2: the LocalRequestDispatcher for calling the local JVM and the Jsr160RequestDispatcher. These dispatcher are configured direct in the Jolokia configuration, either as a servlet init parameter or OSGi properties. The implementations must have a constructor with the following signature:

    /**
     * Constructor
     *
     * @param pConverters object/string converters
     * @param serverInfo server info for dealing with version information
     * @param restrictor restrictor for restricting access to certain MBeans
     */
    public RequestDispatcher(Converters pConverters,
                             ServerHandle serverInfo,
                             Restrictor restrictor);

Converters holds the converters used of up- and downstream JSON serialization. ServerHandle is the result returned by ServerDetectors. Restrictor is responsible for access control (see below)

Extractor

Extractor is part of the conversion mechanism and is responsible for downstream JSON conversion of a single Type. Extractors are currently created and used hardcoded in ObjectToJsonConverter

Simplifier

A special version of an extractor, which can reduce the amount of information for certain types which were obtained by an BeanExtractor using reflection. E.g. an URL is reduced to a single string representation. Simplifiers are looked up the same way as Extractors (defined in META-INF/simplifiers)

Detector

A detector is used to examine the runtime environment. It registers specific MBeanServers found and return a ServerHandle holding runtime information.

It is currenlty looked up via jolokia.util.ServiceObjectFactory during startup by fixed named property files (META-INF/detectors) found in the classpath, much similar to a java.util.ServiceLoader (with some extensions). There is currently no way to look up extractors via OSGi services. However, there exists detectors for OSGi containers (which uses a thread local BundleContext injected just before the detection phase).

Restrictor

One or more restrictors are used for accesscontrol. There exists a full featured default implementation which uses an XML policy file. Restrictors can be looked up as OSGi services (for the OSGi agent) or given programmatically as constructor argument to the servlet. The PolicyRestrictor is used as default, if a policy file is configured. Finally an AllowAllRestrictor is used as fallback.

NotificationBackend new

A notification backend is responsible for delivering JMX notifications. The Jolokia JMX notification mechanism has two major parts: One for managing notifications subcsriptions. This is done via the Jolokia protocoal. And one for delivering the notifications. There exists one default based on a pull mechanism, where notifications are fetched via JMX reads on a certain MBean. More in this Notifications elsewhere. Currently the backend is hardcoded, waiting for a solution on this story.

Converters

Different subsystems uses Converters doing the up/dowsntream JSON conversion to Java objects. It is lighweight, but the API is not nice. It is also tighlty integrated where a singleton object is passed down the layers via constructors. It would be nice to exposed this as a service and maybe even pickup up other implementations, maybe even something big like Spring data converters or a Jackson based implementation.

Lookup mechanisms

  • Classpath Lookup (a la ServiceLoader) for default services used and for non-OSGi environments.
  • OSGi Services (via ServiceTracker) for OSGi environments.
  • EJB lookup ?
  • Spring lookup ?

Requirements

  • Must work in various enviroments and also in non-OSGi environments
  • Classpath lookup should work across module/jar boundaries, so that a simple assembly (e.g. packaging within a war) selects differents services.
  • Must support dynamic behaviour (for OSGi Services), i.e. services can come and go.
  • Classpath Lookup can be static (i.e. during startup) since it is suppossed that the classpath wont change during the lifetime of an agent.
  • The result of various kind of lookups must be merged
  • It must be possible to specify an order (important for simplifiers and detectors). See jolokia.util.ServiceObjectFactory for the current solution of ordering, defaults and even removing default entries (its similar to a ServiceLoader but more flexible in the configuration format).
  • The service must have a way to access the Jolokia Configuration. Some services (RequestDispatcher) need more context information to work. In an OSGi environment these extra context could be exposed, but we cannot guarantee to runder under OSGi.

Notes

  • The current solution to propagate a BundleContext in OSGi is to put it into a ThreadLocal during lookup. This could be a solution for creating the services, too, so that their constructor (non-arg) have access to the contact information. Or the service mechanism is so flexible to allow for custom constructors (or both).
  • The active, recognized services should be returned via the version command.
  • There should be a base Service interface/class for
    • Getting meta information for a service
    • Maybe getting signature information for creating the service
  • Service found on the classpath get created by the ServiceManager, service offered by OSGi must be created elesewhere. They need to get their dependencies via OSGi services as well. So the either the core must export these, either as direct services or as reference to OSGi services providing these.