Contains classes that let you develop plug-in components.
This model is based on three major objects. First, a plug-in
manager PluginManager
is responsible for finding all the plug-in
factories that are present, for invoking each factory to create the plug-in
instances, and for managing the collection of plug-ins that are present. The
other two objects are the plug-in factories and the plug-in instances. The
factories are implementations of a very simple interface ImsPluginFactory
that returns a collection of plug-in
instances. There is a common plug-in interface ImsPlugin
that each plug-in component instance must implement
which allows control of the plug-in lifecycle and helps with plug-in
management. Each plug-in object can, of course, implement an arbitrary number
of other interfaces to actually perform its function.
This basic interface only does some simple lifecycle
management, and provides access to the set of plug-ins—any additional semantics
are built in a layer above the basic architecture.
The system provides no guarantee of the order that plug-ins
will be resolved in, and has no provision for inter-plug-in dependencies.
Therefore, no plug-in may be dependant on functionality from another plug-in—plug-ins
can only be dependent on the core CA Identity Manager functionality.
Plug-in Manager
The Plug-in Manager lives in the LLSDK so that all levels
of CA Identity Manager can access the plug-in collection without introducing
dependencies to the LLSDK. While the basic plug-in interfaces also live in the
LLSDK, each plug-in implementation may also implement interfaces that the LLSDK
knows nothing about.
There are two different ways to get a Plug-in Manager, and
the behavior of the interface is different depending on how you acquire it.
You can acquire a “global Plug-in Manager” by using a
static factory function on the ImsApi object. This Plug-in
Manager works only with the set of ‘global’ plug-ins, i.e. plug-ins that are not associated with an environment. Any factory that
identifies as a global factory will be invoked when the ImsApi’s static
initializer runs, and the plug-ins generated by these
factories will be the global plug-ins which can be managed by the global Plug-in
Manager.
A Plug-in Manager interface is also accessible via a new accessor method on the ImsEnvironment
object. The manager you get from this method is an “environment level” plug-in
manager. This manager has access to both the collection of global plug-ins and
the collection of plug-ins associated with this environment. When the
environment instance is first created, all the factories that identify as
‘environment level factories’ are invoked to create their plug-ins. This
invocation is passed the environment object, so that the factories can
read/write configuration data, etc, to the linked data of the environment.
(I.e. what plug-ins an environment level factory returns may depend on
configuration data in the environment.) Additionally, each plug-in instance
created by a factory invoked from the manager may have access to a reference to
the environment. This means that the plug-ins themselves can read/write to the
additional properties of the environment to store configuration information. So
not only we decide what plug-ins to create based on stored data, but each
instance can also be configured based on stored data.
An environment-level plug-in manager responds to requests
for plug-ins with a List that includes all global plug-ins of that key and all plug-ins
of that key for this environment.
The Plug-in Manager has two major methods: initPlugins
, which trigger the scanning of factories
and building of the plug-in lists, and getPlugins
, which returns a List of plug-ins of a
specified type.
initPlugins takes no parameters,
but does pass along a reference to the environment “under the covers”. For the
global init, this parameter will be null.
The getPlugins method will include a
lazy init check—if initPlugins has not yet happened,
invoking getPlugins
will trigger it.
Invoking the initPlugins method after it has
previously been invoked will cause the current plug-in set to be cleanly
destroyed (i.e. their cleanup() methods invoked and the
internal collections emptied) and the scan/build process will be re-run. This
might be done to force a rebuild of the plug-in set, or to reflect changes made
to the environment settings.
(Like all other environment settings, changes to plug-in
configurations will require a cluster restart, since they are persisted to the
policy store, but not reflected in-memory in any server instances besides the
one they are made in.)
getPlugins takes a String parameter
which is the key for the type of plug-ins you want to enumerate. A List of ImsPlugin
objects which match that key are returned. If there are no matching plug-ins
the method succeeds and returns an empty list.
Every plug-in jar should include at least one
implementation of one of the ImsPluginFactory
interfaces (if it doesn’t, it’s
kind of useless as a plug-in jar since it won’t create any plug-in instances),
and the implementating classes must live in the com.netegrity.ims.plugin.factory package.
Both ImsGlobalPluginFactory
and ImsEnvironmentPluginFactory
are
descendants of a common ImsPluginFactory
interface, which has no methods. The plug-in manager differentiates global and
environment-level plug-in factories based on whether or not the factory
implements these interfaces. A given implementing class could actually
implement both interfaces and return different lists for global and
environment-level behaviour.
Each interface has only one method, createPluginInstances.
The ImsGlobalPluginFactory version of
this method takes no parameters. The ImsEnvironmentPluginFactory version
takes an ImsEnvironment
object.
In either case the createPluginInstances
method returns a List
of instances of ImsPlugin. Any given factory can return one or more
plug-ins, and the plug-ins can be of the same, or of differing types (i.e. can
all have the same key, or many different keys).
Plug-in Interface
The ImsPlugin
interface, which must be implemented by each plug-in
(indeed, being a plug-in is defined by implementing this interface) covers
three main areas: plug-in lifecycle, plug-in management, and reporting.
The plug-in lifecycle methods allow rudimentary control of
state information in the plug-in. The init()
method is invoked when the plug-in is first
created, the start()
method is invoked when the system first plans to use the plug-in, and the cleanup()
method is
called when the system is removing references to the plug-in instance. The isStarted()
method is used
to determine if a specific plug-in instance has been started already.
Plug-in management is controlled by the getPluginTypeKeys
method. This method returns a List of Objects that are
type keys for this plug-in. This allows the plug-in to be associated with one
or more keys.
The reporting methods can be used to show information
about plug-ins. In addition to the isStarted method, there are
methods to get a name, a description, and a version