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):
  • Headwind MDM plugin frontend Angular code

    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.

    Headwind MDM plugin entry in Functions menu

  • 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:
  • Headwind MDM plugin frontend Angular code

    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.

    Headwind MDM plugin entry in Settings menu

  • 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.

Headwind MDM plugin frontend Angular code

Headwind MDM plugin entry in the device list

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).