How to create extension point

OpenLMIS allows extending or overriding certain behavior of service using extension points and extension modules. Every independent service can expose extension points that an extension module may utilize to extend its behavior. Extension point is a Java interface placed in the service. Every extension point has its default implementation that can be overridden. Extension modules can contain custom implementation of one or more extension points from main service.

Decision about which implementation should be used is made based on the configuration file extensions.properties. This configuration file specifies which modules (implementations) should be used for the Service's extension points.

Instructions

Prepare core service to enable extensions

  1. Add ExtensionManager and ExtensionException to src/extension in the repository where extension point should be included (See commit here).

  2. Add extension point interface in src/extension/point, for example: AdjustmentReasonValidator.

  3. Add final ExtensionPointId class with the extension point ids defined like here.

  4. Add Default class which implements the extension point interface. See an example. Default class needs to have Component annotation with the value of its id:

    @Component(value = "DefaultAdjustmentReasonValidator")
  5. Update the usage of the extension point. Now it should use ExtensionManager to find proper implementation. See example here.

  6. Add runtime dependency to build.gradle file in the repository like here.

  7. In build.gradle add tasks that sign archives and publishes repository itself to Maven (check details in this ticket).

  8. Run the CI build job to publish the repository to Maven.

Extension point implementation and usage

  1. Create a new extension module, which contains code that overrides extension point, for example: selv-v3-fulfillment-extension.

  2. Annotate your implementation of the extension point with @Component annotation with the value of its id like here.

  3. Create an appropriate CI job (example). Build the job to publish the repository to Maven.

  4. Create a new extensions module which collects extension points for all services. The selv-v3-extensions-config is an example of such a module.

  5. Modify extensions.properties with the name of the extended component

  6. Add the extension to the "dependencies" configuration in build.gradle.

  7. Create a dedicated docker-compose.yml file with the extensions-config service. See the example: docker-compose.selv-v3-fulfillment-extension.yml.

  8. Add the extensions module as volume to the extended service in the docker-compose.yml file.

OpenLMIS: the global initiative for powerful LMIS software