Realization of Custom System Modules¶
Methods Used by Modules¶
Universe products are based on a modular architecture. New features can be added to the system by implementing a new module.
A module is a piece of code packaged in a .jar file that implements the org.unidata.mdm.system.type.module.Module
interface. In addition, a module must have a special entry in the MANIFEST.MF file denoting the implementing class. For example:
Unidata-Module-Class: org.unidata.mdm.data.module.DataModule
Custom modules can be created using a set of mandatory methods. Implemented modules are loaded into the Universe product.
The org.unidata.mdm.system.type.module.Module
interface has several mandatory methods for implementation:
/**
* Gets module ID, i. e. 'org.unidata.mdm.core'.
* @return ID
*/
String getId();
/**
* Gets module version, consisting of major.minor.rev, i. e. '5.4.3'.
* @return version
*/
String getVersion();
/**
* Gets module localized name, 'Unidata Core'.
* @return name
*/
String getName();
/**
* Gets module localized description, i. e. 'This outstanding module is for all the good things on earth...'.
* @return description
*/
String getDescription();
If a module has dependencies on other modules, it must also implement the method:
/**
* Returns the dependencies of this module.
*/
Collection<Dependency> getDependencies()
The Module Service will check and load dependencies before running the module.
The module identifier must match the module root package if the module uses Spring and implements bean components from other modules, as the module root package will be scanned by the Spring framework to detect classes annotated with Spring annotations.
A class implementing org.unidata.mdm.system.type.module.Module
must not itself be a bean component, although @Autowire or JSR330 @Inject can be used within the implementing class.
Regardless of how the module interface is implemented - using Spring or not - the @ModuleRef annotation can be used to inject an instance of the module into the necessary space, e.g.:
@ModuleRef
private DataModule dataModule;
// or
@ModuleRef("org.unidata.mdm.data")
private Module dataModule;
There are also a number of other methods that can be implemented:
/**
* Runs module's install/upgrade procedure.
* Can be used to init / mgirate DB schema or other similar tasks.
*/
default void install() {
// Override
}
/**
* Runs module's uninstall procedure.
* Can be used to drop schema or similar tasks.
*/
default void uninstall() {
// Override
}
/**
* Runs module's start procedure.
* Happens upon each application startup.
* Should be used for initialization.
*/
default void start() {
// Override
}
/**
* Runs module's stop procedure.
* Happens upon each application shutdown.
* Should be used for cleanup.
*/
default void stop() {
// Override
}
/**
* Runs after platform startup (all modules have successfullty executed method start) in the order of dependency resolution
*/
default void ready() {
// Override
}
If module contains custom configs that module uses: reapply method AbstractModule.getConfigurationProperties()
. Working with database is not custom configs, you don't need reapply method.
Adding Custom Modules¶
Once a module is implemented, it needs to be added to the Universe product. Adding options:
Place the module in the universe-integration directory in $CATALINA_HOME/universe-integration in Tomcat. Next, add the universe-backend.xml configuration file to $CATALINA_HOME/conf/Catalina/localhost.
Place the module in the universe-integration directory in Docker.
The module will then be loaded by the system.
Note
Module must be have all needed for him work access rights. For example, rights to create and edit DB tables. Else you see errors when system starts. For external modules (LDAP etc): module ignores when system starts. For internal modules (search etc) system doesn't start.