Go plug-in architecture allows Go application to be modular, customizable, and easily extensible by creating extension points. Extension points are defined by set of java interfaces and classes which abstract specific aspect of Go application. Plugins can be developed against these extension points by implementation of interfaces or extending abstract classes. Every plugin is packaged as a Java Archive (jar). Go plug-in architecture will extract these plug-ins and converts them into OSGi bundles and load them at run time. Go plug-in architecture has the following modules.
- Go Plugin Infrastructure:
This module is responsible for responding to any changes in plug-ins, converting plug in into into OSGi bundles and loading them.
- Go Plugin Activator:
This module is responsible for loading all classes in the plug-in which are not in the dependency directory and registering services for the plug-in extensions.
- Go Plugin Api:
This module mainly contains API's for all extension points and annotations which are required to mark various aspects of a plug-in.
- Go Plugin Api internal:
This module contains API's for bunch of services which will be made available to plug-in at run time, for example PluginHealthService and LoggingService.
- GoPluginDescriptor is representation of plugin which essentially contains id, name, version, status , jar location, bundle location, OSGi bundle instance and any other information of plug-in.
- GoPluginDescriptorBuilder builds GoPluginDescriptor from plug-in XML which is part of plug-in jar. If plug-in XML is missing GoPluginDescriptor will be built with default values.
- DefaultPluginRegistry maintains list of plug-ins which are loaded.
DefaultPluginJarLocationMonitor periodically monitors plug-in jar location for any changes by spawning a java thread, whenever any changes are detected DefaultPluginJarLocationMonitor determines if plug-in jar is added/deleted/updated based on the in memory known plug-in list maintained by DefaultPluginJarLocationMonitor. DefaultPluginJarLocationMonitor can register list of PluginJarChangeListener and when plug-in is added/deleted/updated changes are accordingly notified to all the registered PluginJarChangeListener. Currently plug-in jars can be located at bundled directory or external directory.
Bundled directory contains plugins bundled with Go. Any unbundled plugins put in this directory will be removed. The directory is meant exclusively for plugins bundled with the product.
External directory contains all the unbundled plugins. This directory is recommended for use by plugin developers.
DefaultPluginJarChangeListener is the default implementation of PluginJarChangeListener. DefaultPluginJarChangeListener listens to plug-in add/delete/update events, upon listening to these events DefaultPluginJarChangeListener constructs GoPluginDescriptor using GoPluginDescriptorBuilder, after performing necessary validations plugin jar is extracted into bundle directory, GoPluginDescriptor will be added to DefaultPluginRegistry and OSGi bundle will be loaded using GoPluginOSGiFramework.
GoPluginOSGiFramework is responsible for loading and unloading OSGi bundles given a GoPluginDescriptor. All the communication between Go application and plug-ins will be facilitated through GoPluginOSGiFramework. Given java class service reference and plug-in id, GoPluginOSGiFramework can find service reference instance.
DefaultGoPluginActivator is an implementation of OSGi BundleActivator and is responsible for loading all classes in the plug-in which are not in the dependency directory and registering services for the plug-in extensions.
Go Plugin Activator module gets packaged as separate jar and added as dependency JAR into each plug-in by copying activator jar into bundle directory of plug-in.
This module contains all the API's which are specific to extension points and also API classes which are common across all the extension. Go Plugin Api module also contains various java annotation classes which are required to mark various aspects of a plugin.
Every plugin needs to interact with GO server to capture certain information and it is represented as Configuration class. Configuration is either provided by GO application or by user. Configuration has list of Property. Each Property has name, value and set of Options associated with Property.
Any java interface or class inside Go Plugin Api module which is annotated with GoPluginApiMarker indicates to the plug-in framework that the interface or class will be implemented by a plugin. and will be treated as extension point provided by Go. Plugin authors are required to mark extension implementation class with Extension annotation. Go Plugin Api module also provides following java annotations
Load : Annotation that marks a method to be called when a plug-in is loaded.
UnLoad : Annotation that marks a method to be called when a plug-in is unloaded.
UsedOnGoAgent : A method mark by this annotation indicates that the method is invoked on the Go Agent.
UsedOnGoServer : A method mark by this annotation indicates that the method is invoked on the Go server.
Go application leaks bunch of service implementations to plug-in which can be used at various stages of plug-in execution. This module contains interfaces for such service implementations.
PluginHealthService: Go plugin infrastructure will load every plug-in through Go plug-in activator. If Go plugin activator encounters any issues while loading they will be notified to Go server via PluginHealthService
LoggingService: Go application provides Logger class via Go plug-in api which can be used by plug-in to log various events. All the logging which is performed by Logger class will be logged along with Go server log in a separate file which is specific to each plug-in. Logger class uses LoggingService behind the scene.