Skip to main content

On-Premise Configuration

The recommended setup for running a DPU (Dimml Processing Unit) is to use Docker. By default the image will load dimml files from /opt/dimml/dimml. To connect the platform to the outside world and load files from the host file system use:

docker run -d -p 80:80 --name my_o2mc -v `pwd`/dimml:/opt/dimml/dimml dimml

This will bind the local dimml directory to the container and start in detached mode. You can follow the output from the platform using:

docker logs -f my_o2mc

To test if everything is working, create the following host file ~/dimml/prod/test.service.dimml:

concept Test {
match `once`@service

val timestamp = `new Date()`@groovy

flow console
}

You should now see the current date as a 'timestamp' field in the output log of the platform.

Custom configuration

The platform is highly configurable. The main configuration is stored in /opt/dimml/conf/dimml.yaml, but the location can be changed using a Java system property:

docker run -e 'JAVA_OPTS=-Ddimml.config=/path/to/dimml.yaml' dimml

An example configuration file:

version: 2.15-local # optional version used to identify this platform in a multi-platform setup
host: dimml.example.com # hostname accessible from the internet
port: 80 # optional HTTP listening port
productkey: # product key to enable production workload
repository: # load dimml files from a database and local file system
- "jdbc:mysql://dimml-db.example.internal/dimml?user=dimml&password=password&useSSL=true&requireSSL=true&verifyServerCertificate=false"
- "file:dimml"
ssl: # enable ssl
letsencrypt: true # automatically obtain certificates
sni: true # enable sni to allow virtual host certificates (multiple DNS CNAME records)
port: 443 # optional HTTPS secure port
api: # setup API access, required by O2mc Studio, DSM, QMon and others
db:
type: mysql
serverName: dimml-db.example.internal
databaseName: dimml
user: dimml
password: password
token: wGz76s3Yz2JbUJJmJ3EYu2NAFP3HRAEs # token that gives access to the API

To start the platform with a configuration file, bind it to a file on the host:

docker run -p 80:80 -p 443:443 -v `pwd`/dimml.yaml:/opt/dimml/conf/dimml.yaml

Configuration options in the file can be overwritten with environment variables. To do so, start the variable with DIMML_ and concatenate the keys using the underscore as separator. The following will start the platform with SSL enabled:

docker run -p 80:80 -p 443:443 -e DIMML_SSL_LETSENCRYPT=TRUE -e DIMML_HOST=dimml.example.com dimml

When using SSL it is best to bind a host directory to /root/.dimml/cert in the container. This is where the platform will store keys and certificates. When using a platform with multiple nodes (or a multi-platform), see below, this certificate directory should be in a central location (e.g. a NAS or cloud storage). The nodes in such a platform will select a single node to start a domain authorization while all nodes are able to handle the resulting HTTP Challenge.

docker run \
-p 80:80 -p 443:443 \
-e DIMML_SSL_LETSENCRYPT=TRUE \
-e DIMML_HOST=dimml.example.com \
-v `pwd`/cert:/root/.dimml/cert \
-v `pwd`/dimml:/opt/dimml/dimml \
dimml

API database setup

The platform API requires a database for dimml file storage. Both MySQL and Microsoft SQL Server are fully supported. Other databases might work or require small modifications to dimml.api.dimml, the dimml file governing the API.

Database schema for Microsoft SQL Server (Transact SQL):

CREATE TABLE dimml (
path VARCHAR(512) NOT NULL PRIMARY KEY,
lastmodified DATETIME NOT NULL DEFAULT getDate(),
code NVARCHAR(MAX),
KEY lastmodified (lastmodified),
KEY path (path(255))
)

CREATE TABLE error (
id BIGINT IDENTITY(1,1) PRIMARY KEY,
stamp BIGINT NOT NULL,
domain VARCHAR(128),
server VARCHAR(64),
env VARCHAR(64),
partner CHAR(8),
trace NVARCHAR(MAX) NOT NULL
)

GO

CREATE TRIGGER dimml_lastmodified ON dimml AFTER UPDATE AS
UPDATE dimml
SET lastmodified = getDate()
WHERE path IN (SELECT path FROM inserted)

GO

Database schema for MySQL / MariaDB:

CREATE TABLE dimml (
path VARCHAR(512) NOT NULL PRIMARY KEY,
lastmodified TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
code MEDIUMTEXT,
KEY lastmodified (lastmodified),
KEY path (path(255)),
) DEFAULT CHARSET=utf8mb4;

CREATE TABLE error (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
stamp BIGINT NOT NULL,
domain VARCHAR(128),
server VARCHAR(64),
env VARCHAR(64),
partner CHAR(8),
trace MEDIUMTEXT NOT NULL
);

Clustering setup

The O2mc platform is horizontally scalable but some features require negotiation between worker nodes (e.g. leader selection, streaming to an external file, running services, etc.). The platform utilizes Hazelcast for managing cluster communication and distributed state. The setup largely depends on the cluster layout. In the following section we assume a layout with multiple hosts running Docker independently.

Add the following section to dimml.yaml on host 1, assuming the ip address of host 2 is 10.0.20.2:

hazelcast:
private:
port: 5701 # optional port, can be omitted
ip: 10.0.20.2

And add the following section to dimml.yaml on host 2:

hazelcast:
private:
port: 5701
ip: 10.0.20.1

Make sure to expose the hazelcast port when running the container:

docker run -p 80:80 -p 5701:5701 -v `pwd`/dimml.yaml:/opt/dimml/conf/dimml.yaml dimml

Docker compose / swarm mode is experimental. It requires communication between the containers using an overlay network. The easiest way to get Hazelcast to select the proper network from within the container is by using DNS Round Robin instead of the default routing mesh. The configuration is as follows:

hazelcast:
private:
docker: dimml_service_name

The setup with DNS Round Robin requires a separate load balancer, e.g. HAProxy, which can also be installed with Docker: HAProxy docker.

Multi-platform setup

A multi-platform setup allows separation of production traffic from development traffic and routes and processes the traffic in separate containers / hosts. The setup works best with a 'global' hazelcast instance joining all nodes and 'private' hazelcast instances that join the nodes of a particular platform. Without the global hazelcast the different platforms need to be aware of one another through configuration and cache invalidation will not work, which results in longer delays before code changes take effect.

hazelcast:
global:
port: 5702
docker: dimml_service_name

Dimml files optionally start with a version directive that instructs a node on which version of the platform the code is meant to run. When a node is aware of a remote version that more closely matches the version of the dimml file, it will proxy traffic and generate Javascript appropriately. This mechanism is used in conjunction with special directives on the jdbc repository loader:

repository: # load dimml files from a database and local file system
- "jdbc:mysql://dimml-db.example.internal/dimml?dimmlProdVersion=2.15-prod&dimmlDevVersion=2.15-dev&user=dimml&password=password&useSSL=true&requireSSL=true&verifyServerCertificate=false"

Now all that remains is to configure Dimml development and production nodes accordingly:

version: 2.15-dev
host: dimml-dev.example.com
version: 2.15-prod
host: dimml.example.com