Home
Categories
Dictionary
Glossary
Download
Project Details
Changes Log
What Links Here
FAQ
License

User-defined module types



It is possible to define your own user-defined module types, which allow to define your own kind of modules and refer to them in the applications configuration. For example, you could define specific module types to handle Simulink modules, or other kinds of modules linked to any other framework or library[1]
There is a tutorial showing how to create a user-defined module type for Python scripts, having the same kind of functionality as the built-in Python modules
.

The idea is to specify a Factory which will be responsible for interpreting the content of the implementation for your user-defined module type. The factory will manage the Metadata of you specific implementation. For example, we could have a module which would be implemented in Simulink:
      <applications>
         <application name="publishAppli">
            <modules>
               <customModule name="PublishModule" type="simulink">
                  <implementation path="myAppli">
                     <parameter key="simulinkRuntime" value="C/Programs/Mathlab" />
                     <defaultSendEntryPoint method="publish" />
                  </implementation>
                  <interfaces>
                     <eventReceived service="event"/>
                     <cyclic service="published" frequency="200ms" attach="attach"/>
                  </interfaces>
               </customModule>
            </modules>
         </application>
      </applications>

Architecture

userdefinedmodule
Custom Module factories are instantiated if the customFactories key is found in the configuration. Then depending on the content of each module configuration, the factory is called to create the Module definition and the associated Module.

The Custom Module factory is a class which implements a Java interface which allows to:
  • Define which specific framework properties are supported for the custom module implementation
  • Define which implementation parameters are supported for the custom module implementation, and which ones are mandatory
  • Create a module definition
  • Create the associated module and parse the associated module implementation parameters

Factory definition

The factory is an instance of the CustomModuleFactory interface, which will be instantiated by reflexion. The jar file containing the factory must define where to find it in its Manifest.

Factory Manifest definition

The Manifest must contain two properties:
  • moduleFactory: the path of the Factory
  • moduleType: the type of the module which will be created by the factory


For example:
      moduleFactory: org.da.test.PythonModuleFactory
      moduleType: python

Factory class definition

The class which implements the factory must implement the CustomModuleFactory interface:

      /**
      * Return the framework properties supported by the factory and their associated property types.
      *
      * @return the framework properties supported by the factory and their associated property types
      */
      public default Map<String, Class<?>> getFrameworkPropertiesTypes() {
      return new HashMap<>();
      }

      /**
      * Return the keys for the mandatory module implementation parameters
      *
      * @return the keys for the mandatory module implementation parameters
      */
      public default Set<String> getMandatoryModuleParameters() {
      return new HashSet<>();
      }

      /**
      * Set a framework property value. The value is guaranteed to be consistent with the type defined in {@link #getFrameworkPropertiesTypes()}.
      *
      * @param key the framework property key
      * @param value the framework property value
      */
      public default void setFrameworkProperty(String key, Object value) {
      }

      /**
      * Return a framework property value. The value is guaranteed to be consistent with the type defined in {@link #getFrameworkPropertiesTypes()}.
      *
      * @param key the framework property key
      * @return the framework property value
      */
      public default Object getFrameworkProperty(String key) {
      return null;
      }

      /**
      * Return the module implementation parameters supported by the custom module and their associated parameter types.
      *
      * @return the module implementation parameters supported by the custom module and their associated parameter types
      */
      public default Map<String, Class<?>> getModuleParameterTypes() {
      return new HashMap<>();
      }

      /**
      * Creates a custom module definition.
      *
      * @param appli the application definition
      * @param name the module name
      * @param id the module ID
      * @return the custom module definition
      */
      public CustomModuleDefinition createModuleDefinition(ApplicationDefinition appli, String name, long id);

      /**
      * Creates a custom module.
      *
      * @param appli the application
      * @param name the module name
      * @return the custom module
      */
      public Module createModule(Application appli, String name);

      /**
      * Return the class used to define custom modules for this factory.
      *
      * @return the class
      */
      public Class<?> getModuleDefinitionClass();

Supporting specific framework properties

The factory can specify which specific framework properties it supports. The relevant methods are:
      /**
      * Return the framework properties supported by the factory and their associated property types.
      *
      * @return the framework properties supported by the factory and their associated property types
      */
      public default Map<String, Class<?>> getFrameworkPropertiesTypes() {
      return new HashMap<>();
      }

      /**
      * Set a framework property value. The value is guaranteed to be consistent with the type defined in {@link #getFrameworkPropertiesTypes()}.
      *
      * @param key the framework property key
      * @param value the framework property value
      */
      public default void setFrameworkProperty(String key, Object value) {
      }

      /**
      * Return a framework property value. The value is guaranteed to be consistent with the type defined in {@link #getFrameworkPropertiesTypes()}.
      *
      * @param key the framework property key
      * @return the framework property value
      */
      public default Object getFrameworkProperty(String key) {
      return null;
      }


For example, for a Simulink module type:
      <files>
         <file url="applications.xml" />
         <file url="services.xml" />
         <file url="types.xml" />
         <file url="properties.xml" />
         <property key="customFactories" value="mySimulinkFactory.jar" />
         <property key="mathlabPath" value="C:/program/Mathlab" />
      </files>

Supporting specific module implementation parameters

The factory can specify specific module implementation parameters to handle for the custom module implementation in the module configuration. These parameters allow to configure the module depending on the type of module. For example:
  • For a Python custom Module, if we start an external Python runtime executable, we might want to specify the ports by which we will communicate with the Python script


The relevant methods are:
      /**
      * Return the keys for the mandatory module implementation parameters
      *
      * @return the keys for the mandatory module implementation parameters
      */
      public default Set<String> getMandatoryModuleParameters() {
        return new HashSet<>();
      }

      /**
      * Return the module implementation parameters supported by the custom module and their associated parameter types.
      *
      * @return the module implementation parameters supported by the custom module and their associated parameter types
      */
      public default Map<String, Class<?>> getModuleParameterTypes() {
        return new HashMap<>();
      }


For example, for a custom Python module type:
      <applications>
         <application name="publishAppli">
            <modules>
               <customModule name="PublishModule" type="python">
                  <implementation path="myAppli">
                     <parameter key="inputPort" value="6000" />
                     <parameter key="outputPort" value="6001" />
                     <defaultSendEntryPoint method="publish" />
                  </implementation>
                  <interfaces>
                     <eventReceived service="event"/>
                     <cyclic service="published" frequency="200ms" attach="attach"/>
                  </interfaces>
               </customModule>
            </modules>
         </application>
      </applications>

Creating the Module Definition and the Module

The factory has several methods to specify the module definition and the module. The relevant methods are:
      /**
      * Creates a custom module definition.
      *
      * @param appli the application definition
      * @param name the module name
      * @param id the module ID
      * @return the custom module definition
      */
      public CustomModuleDefinition createModuleDefinition(ApplicationDefinition appli, String name, long id);

      /**
      * Creates a custom module.
      *
      * @param appli the application
      * @param name the module name
      * @return the custom module
      */
      public Module createModule(Application appli, String name);

      /**
      * Return the class used to define custom modules for this factory.
      *
      * @return the class
      */
      public Class<?> getModuleDefinitionClass();

Module definition

The module definition is a subclass of the CustomModuleDefinition class which will be returned by the factory.

The Custom module definition has only one abstract method:

For example, for a custom Python module type:
      <applications>
         <application name="publishAppli">
            <modules>
               <customModule name="PublishModule" type="python">
                  <implementation path="myAppli">
                     <parameter key="inputPort" value="6000" />
                     <parameter key="outputPort" value="6001" />
                     <defaultSendEntryPoint method="publish" />
                  </implementation>
                  <interfaces>
                     <eventReceived service="event"/>
                     <cyclic service="published" frequency="200ms" attach="attach"/>
                  </interfaces>
               </customModule>
            </modules>
         </application>
      </applications>

Module

The module is a subclass of the Module class which will be returned by the factory.

Example

Suppose the following file configuration:
      <applications>
         <application name="publishAppli">
            <modules>
               <customModule name="PublishModule" type="python">
                  <implementation path="myAppli">
                     <parameter key="inputPort" value="6000" />
                     <parameter key="outputPort" value="6001" />
                     <defaultSendEntryPoint method="publish" />
                  </implementation>
                  <interfaces>
                     <eventReceived service="event"/>
                     <cyclic service="published" frequency="200ms" attach="attach"/>
                  </interfaces>
               </customModule>
            </modules>
         </application>
      </applications>
Suppose the Manifest of the myPythonFactory.jar jar file is:
      moduleFactory: org.da.test.PythonModuleFactory
      moduleType: python
The factory class will have the following code:
      public class CustomPythonModuleFactory implements CustomModuleFactory {
        private static final Map<String, Class<?>> MODULE_PARAMS_TYPES = new HashMap<>();

        static {
          MODULE_PARAMS_TYPES.put("inputPort", Integer.class);
          MODULE_PARAMS_TYPES.put("outputPort", Integer.class);
          MODULE_PARAMS_TYPES.put("inputSize", Integer.class);
          MODULE_PARAMS_TYPES.put("outputSize", Integer.class);
        }

        @Override
        public CustomModuleDefinition createModuleDefinition(ApplicationDefinition appli, String name, long id) {
          CustomPythonModuleDefinition moduleDef = new CustomPythonModuleDefinition(this, appli, name, id);
          return moduleDef;
        }

        /**
        * Creates a custom module.
        *
        * @param appli the application definition
        * @param name the module name
        * @return the custom module
        */
        @Override
        public Module createModule(Application appli, String name) {
          CustomPythonModule module = new CustomPythonModule(appli, name);
          return module;
        }

        /**
        * Return the module implementation properties supported by the custom module and their associated property types.
        *
        * @return the module implementation properties supported by the custom module and their associated property types
        */
        @Override
        public Map<String, Class<?>> getModulePropertiesTypes() {
          return MODULE_PROPERTIES_TYPES;
        }

        @Override
        public Class<?>> getModuleDefinitionClass() {
          return CustomPythonModuleDefinition.class;
        }
      }
Then the current applications configuration will use this factory:
      <applications>
         <application name="publishAppli">
            <modules>
               <customModule name="PublishModule" type="python">
                  <implementation path="myAppli">
                     <parameter key="inputPort" value="6000" />
                     <parameter key="outputPort" value="6001" />
                     <defaultSendEntryPoint method="publish" />
                  </implementation>
                  <interfaces>
                     <eventReceived service="event"/>
                     <cyclic service="published" frequency="200ms" attach="attach"/>
                  </interfaces>
               </customModule>
            </modules>
         </application>
      </applications>

Notes

  1. ^ There is a tutorial showing how to create a user-defined module type for Python scripts, having the same kind of functionality as the built-in Python modules

See also


Categories: concepts | development

Copyright 2017-2020 Dassault Aviation. All Rights Reserved. Documentation and source under the LGPL v3 licence