- System design
- Building the system
- Plugin design
- Plugin development
- Plugin components
- Registering in Maven project
- Interaction between the plugin and the core
- Frontend
- Localization
- Database and migration
- Mobile API
- Core development
Plugin components
The plugin (its server-side part) is a Maven module and includes the following components:
- Database scheme including at least the registration of the plugin in the plugins table
- Backend code, in particular:
- Code for data models
- Implementation of the PluginConfiguration interface
- Implementation of the mobile API (if required)
- Frontend code
The plugin should have a unique identifier, which is used to name various plugin artifacts, such as DB objects created and managed by the plugin, URI for HTTP API provided by the plugin, etc.
The plugin code must be placed in the subdirectory of the plugins directory named as the plugin identifier. The plugin code structure is described in the previous section.
Registering in Maven project
To include the plugin in Headwind MDM, the following steps should be done:
- Add the dependency element referenced to the plugin to the Maven configuration file of the main web app (server/pom.xml).
<dependency> <groupId>com.hmdm.plugin</groupId> <artifactId>yourProjectName</artifactId> <version>0.1.0</version> <scope>runtime</scope> </dependency>
Notice: this dependency is written in one line in server/pom.xml. This is done for the proper work of internal Headwind MDM scripts not included in the source code; in your development, you do not need to write them in one line.
- Add the module element to plugins/pom.xml.
Interaction between the plugin and the core
To attach to the core, the plugin must implement the interface com.hmdm.plugin.PluginConfiguration.
This interface specifies the plugin text identifier, as well as the list of Guice modules initializing the plugin.
When the main web app is started, the main initializer will create an instance of the class implementing the com.hmdm.plugin.PluginConfiguration interface and will upload its modules to the Guice container for further usage.
Frontend
In the initialization phase, the main web app frontend downloads the list of available plugins and retrieves the JavaScript code of each plugin module from the server.
The frontend module of the plugin should fulfill the following requirements:
- If the plugin must have the UI being called from the “Functions” menu of the core web app, the Angular module of the plugin must add a state named as plugin-<pluginname> in $stateProvider in the following way (see example in the “Messaging” plugin):
- If the plugin must have the UI being called from the “Settings” menu of the core web app, the Angular module of the plugin must add a state named as plugin-settings-<pluginname> in $stateProvider:
- If the plugin needs an entry in the popup menu of the device list, it should add a handler to the event named plugin-<pluginname>-device-selected in the $rootScope of the main web app. This handler will be called when the user selects the corresponding entry in the popup menu of the device list. The identifier of the selected device is passed to the handler, and the handler must forward the user to an appropriate plugin webpage.
The main web app will add an entry in the “Functions” menu. When a user clicks this entry, the plugin main web page will open.
The main web app will add an entry in the “Settings” menu. When a user clicks this entry, the plugin settings web page will open.
Localization
To initialize the localization module in the frontend app, localization.loadPluginResourceBundles method must be called in the .run method of the plugin module.
The localization strings must be stored in files named as i18n/xx_XX.json. To avoid interference with other localization strings of Headwind MDM, they must (by convention) contain a plugin.<pluginname> substring.
Database and migration
The plugin is responsible for creating and migrating its part of the database. Creation and migration of database schemes is done via the Liquibase library.
The plugin must maintain the database migration log in the Liquibase format, and contain the class inheriting from com.hmdm.guice.module.AbstractLiqubaseModule. This class must be included in the list of Guice modules returned by the plugin configuration interface.
To avoid conflicts between plugins, the database objects must fulfill the following requirements:
- Names of all entries of the DB migration log must begin with plugin_<pluginname>_
- Names of all DB objects (tables, indexes, constraints, etc.) must begin with plugin_<pluginname>_
- The DB migration log should contain a record registering the plugin in the plugins table. This record should contain:
- Plugin identifier
- Plugin name (it will be used as a text label for menu entries related to the plugin)
- Plugin description (optional)
- Path to the JavaScript file containing the Angular module of the plugin
- Path to the HTML template for the page available in the “Functions” menu of the main web app (if this page is provided by the plugin)
- Path to the HTML template for the page available in the “Settings” menu of the main web app (if this page is provided by the plugin)
- Permissions to restrict access to the plugin functions and settings (if required)
Mobile API
To accept and process requests from mobile devices, plugins may provide the HTTP-based REST API.
The URLs of the plugin REST API must start with /rest/plugins/<pluginname>/ to avoid conflicts with other URLs of Headwind MDM.
For example, the “Photo” plugin retrieving the images from mobile devices provides the following API URL: /rest/plugins/photo/photo/upload.
It is assumed that a mobile device will send its identifier (Device Number) as the request parameter. Using this parameter, the plugin can identify both the device and the organization to which this device belongs (in the case of multi-tenant usage).