Chapter 35. How To Create an Internal Domain

This chapter describes how to implement a domain for the OpenEngSB environment. A domain provides a common interface and common events and thereby defines how to interact with connectors for this domain. For a better description of what a domain exactly consists of, take a look at the architecture guide Chapter 5, Architecture of the OpenEngSB.

35.1. Prerequisites

In case it isn't known what a domain is and how it defines the interface and events for connectors, then Section 5.4, “OpenEngSB Tool Domains” is a good starting point.

35.2. Creating a new domain project

To get developers started creating a new domain a Maven archetype is provided for creating the initial project structure. The openengsb-maven-plugin (see ???) or the etc/scripts/ script (which only wraps the invocation of the plug-in) simplifies the creation of a domain.

35.2.1. Using the Maven Archetype

It is not recommended to use the maven archetype directly, because the genDomain goal of the openengsb-maven-plugin executes additional tasks, i.e. renaming of the resulting project. Furthermore it tries to make sure that the new project is consistent with the naming conventions of the OpenEngSB project.

The following parameters have to be specified to execute the correct archetype:

  • archetypeGroupId - the groupId of the OpenEngSB domain archetype.
  • archetypeArtifactId - the artifactId of the OpenEngSB domain archetype.
  • archetypeVersion - the current version of the OpenEngSB domain archetype.

The following parameters have to be defined for the parent of the new domain. It is not solely parent of the domain implementation, but parent of all connectors of this domain too.

  • groupId - the groupId of the project parent. Has to be "<yourDomain>".
  • artifactId - the artifactId of the project parent. Has to be "openengsb-domains-<yourDomain>-parent".
  • version - the version of the domain parent, which is usually equal to the current archetype version.
  • name - the name of the parent module. Has to be "OpenEngSB :: Domains :: <yourDomain> :: Parent"

The following parameters have to be defined for the implementation of the new domain.

  • implementationArtifactId - the implementation artifact id. Has to be "openengsb-domains-<yourDomain>-implementation".
  • package - the package for the source code of the domain implementation. Has to be "<yourDomain>".
  • implementationName - the name of the implementation module. Has to be "OpenEngSB :: Domains :: <yourDomain> :: Implementation"

Where <yourDomain> has to be replaced by your domain name which is usually written in lower case, i.e. report for the report domain.

Note that the archetype will use the artifactId to name the project, but the OpenEngSB convention is to use the domain name. Therefore you will have to rename the resulting project. Do not forget to check that the new domain is included in the modules section of the domains pom.

35.2.2. Using mvn openengsb:genDomain

Simply invoke mvn openengsb:genDomain from the domains directory in your OpenEngSB repository (alternatively the etc/scripts/ script can be used which invokes the openengsb-maven-plugin for you).

        domains $ mvn openengsb:genDomain

You'll be asked to fill in a few variables which are needed to create the initial project structure. Based on your input, the mojo tries to guess further values. Guessed values are displayed in brackets. If the guess is correct, simply acknowledge with Return. As example, the following output has been recorded while creating the Test domain:

Domain Name [mydomain]: test <Enter>
Version [1.0.0-SNAPSHOT]: <Enter>
Prefix for project names [OpenEngSB :: Domains :: Test]: <Enter>

Only the domain name has been filled in, while the rest has been correctly guessed. After giving the inputs, the Maven archetype gets executed and may ask for further inputs. You can simply hit Return, as the values have been already correctly set. If the mojo finishes successfully two new Maven projects, the domain parent and domain implementation project, have been created and setup with a sample implementation for a domain.

35.2.3. Project structure

The newly created domain should have the exact same structure as the following listing:

-- src
|  -- main
|     -- java
|        -- org
|           -- openengsb
|              -- domain
|                 -- [mydomain]
|                    -- [MyDomain]
|                    -- [MyDomain]
|                    -- [MyDomain]
|     -- resources
|        -- OSGI-INF
|           -- blueprint
|              -- [mydomain]-context.xml
|           -- l10n
|              --
|              --
|           --
-- pom.xml

The project contains stubs for the domain interface, the domain events interface and the domain provider and a resources folder with the spring setup and property files for internationalization.

Although the generated domain does in effect nothing, you can already start the OpenEngSB for testing with mvn clean install openengsb:provision and the domain will be automatically be picked up and started.

The blueprint setup in the resources folder already contains the necessary setup for this domain to work in the OpenEngSB environment. Furthermore the default implementation proxies for the domain interface, which forwards all service calls to the default connector for the domain and the default implementation of the domain event interface, which forwards all events to the workflow service of the OpenEngSB are configured.

Each OpenEngSB bundle (core, domain, connector) has been designed with localization in mind. The Maven Archetype already creates two bundle*.properties files, one for English ( and one for the German ( language. Each connector has to provide localization through it own properties files. For domains, this only means localization for a name and description of the domain itself.

35.3. Components

  1. Domain interface - This is the interface that connectors of that domain must implement. Operations that connectors should provide, are specified here. Events that are raised by this Domain in unexpected fashion (e.g. new commit in scm system) are specified on the Interface. The Raise Annotation and the array of Event classes it takes as an argument are used. If the Raise annotation is put on a method the events that are specified through the annotation are raised in sequence upon a call.

  2. Domain event interface - This is the interface the domain provides for its connectors to send events into OpenEngSB. The event interface contains a raiseEvent(SomeEvent event) method for each supported event type.

  3. Domain Provider - The domain provider is a service that provides information about the domain itself. It is used to determine which domains are currently registered in the environment. There is an abstract class, that takes over most of the setup.

  4. Blueprint context - There are three services, that must be registered with the OSGi service-environment. First, there is the Domain Provider. Moreover, the domain must provide a kind of connector itself since it must be able to handle service calls and redirect it to the default-connector specified in the current context. And finally the domain provides an event interface for its connectors which can be used by them to send events into OpenEngSB. The default implementation of this event interface simply forwards all events sent through the domain to the workflow service. However, domains can also provide their own implementation of their event interface and add data to events or perform other tasks. There is a bean factory that creates a Java-Proxy that can be used as ForwardService both for the forwarding of service calls from domain to connector and for the forwarding of events to the workflow service. The service call to ForwardService looks up the default-connector for the specified domain in the current context and forwards the method-call right to it. The event forward service simply forwards all events to the workflow service of OpenEngSB.

35.4. Connectors

For information regarding the implementation of connectors for the newly created domain see Chapter 34, How To Create an Internal Connector.