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

User-defined module type example



This article shows an example for user-defined module types. For this example, we will use a user-defined module type for Python modules, rather than using the built-in Python modules.

Configuration

Suppose the following file configuration:
      <files>
         <file url="applications.xml" />
         <file url="services.xml" />
         <file url="types.xml" />
         <file url="properties.xml" />
         <property key="customFactories" value="myPythonFactory.jar" />
      </files>
The configuration contains a customFactories key, to specify the path of our user-defined module factory jar file.

User-defined module factory

User-defined module factory manifest

The user-defined module factory is contained in a jar file called myPythonFactory.jar. This jar file has the following Manifest:
      moduleFactory: org.da.test.PythonModuleFactory
      moduleType: python

User-defined module factory implementation

We suppose that we want to support the following framework properties to mimic what is already done in the Python modules:
  • "thePythonRuntime": refer to the Python runtime executable path


We also want to support the following implementation parameters:
  • "inputPort", "inputSize", "outputPort", and "outputSize": define the ports which will be used to communicate between the java application and the Python Script. If the ports are not specified, the framework will find free local ports. If a size is not specified, the framework will use a default port size


The factory class will have the following code:
      public class CustomPythonModuleFactory implements CustomModuleFactory{
        private static final Map<String, Class<?>> MODULE_PROPERTIES_TYPES = new HashMap<>();
        private static final Map<String, Classlt;?>> FRAMEWORK_PROPERTIES_TYPES = new HashMap<>();
        private URL pythonRuntime = null;

        static {
          MODULE_PROPERTIES_TYPES.put("inputPort", Integer.class);
          MODULE_PROPERTIES_TYPES.put("outputPort", Integer.class);
          MODULE_PROPERTIES_TYPES.put("inputSize", Integer.class);
          MODULE_PROPERTIES_TYPES.put("outputSize", Integer.class);
          MODULE_PROPERTIES_TYPES.put("className", String.class);
          FRAMEWORK_PROPERTIES_TYPES.put("thePythonRuntime", URL.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 framework properties supported by the factory and their associated property types.
        *
        * @return the framework properties supported by the factory and their associated property types
        */
        @Override
        public Map<String, Class<?>> getFrameworkPropertiesTypes() {
          return FRAMEWORK_PROPERTIES_TYPES;
        }

        /**
        * Set a framework property value.
        *
        * @param key the framework property key
        * @param value the framework property value
        */
        @Override
        public void setFrameworkProperty(String key, Object value) {
          if (key.equals(PYTHON_RUNTIME)) {
            pythonRuntime = (URL) value;
          }
        }

        /**
        * 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;
        }
      }
See the CustomPythonModuleFactory Java specification.

Module definition

The module definition will only be used to store the framework properties and the module parameters.

      public class CustomPythonModuleDefinition extends CustomModuleDefinition implements CustomModuleParameters {
        private int sendingPort = -1;
        private int receivingPort = -1;
        private int sendingSize = -1;
        private int receivingSize = -1;

        /**
        * Constructor.
        *
        * @param factory the custom module factory
        * @param appli the application definition
        * @param name the module name
        * @param id the module ID
        */
        public CustomPythonModuleDefinition(CustomPythonModuleFactory factory, ApplicationDefinition appli, String name, long id) {
          super(factory, appli, name, id);
        }

        @Override
        public void setModuleParameter(String key, Object value) {
          if (key.equals(SENDING_PORT)) {
            sendingPort = (Integer) value;
          } else if (key.equals(SENDING_SIZE)) {
            sendingSize = (Integer) value;
          } else if (key.equals(RECEIVING_PORT)) {
            receivingPort = (Integer) value;
          } else if (key.equals(RECEIVING_SIZE)) {
            receivingSize = (Integer) value;
          }
        }

        /**
        * Return the port from Java to Python.
        *
        * @return the port from Java to Python
        */
        public int getSendingPort() {
          return sendingPort;
        }

        /**
        * Return the port from Python to Java.
        *
        * @return the port from Python to Java
        */
        public int getReceivingPort() {
          return receivingPort;
        }

        /**
        * Return the size of the port from Java to Python.
        *
        * @return the size of the port from Java to Python
        */
        public int getSendingSize() {
          return sendingSize;
        }

        /**
        * Return the size of the port from Python to Java.
        *
        * @return the size of the port from Python to Java
        */
        public int getReceivingSize() {
          return receivingSize;
        }
See the CustomPythonModuleDefinition Java specification.

Module

The module will contain the logic of the Java / Python communication. The code will be very similar to the built-in Python module implementation.

See the CustomPythonModule Java specification.

Applications configuration

The following applications configuration will use our new factory:
      <applications>
         <application name="publishAppli">
            <modules>
               <customModule name="PublishModule" type="python">
                  <implementation path="myAppli">
                     <parameter key="inputPort" value="6000" />
                     <parameter key="outputPort" value="6005" />
                     <defaultSendEntryPoint method="publish" />
                  </implementation>
                  <interfaces>
                     <eventReceived service="event"/>
                     <cyclic service="published" frequency="200ms" attach="attach"/>
                  </interfaces>
               </customModule>
            </modules>
         </application>
      </applications>

See also


Categories: concepts | development | tutorials

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