Installation
Requirements
SwiftMQ requires Java 11 or later.
The Streams Swiftlet requires a JavaScript scripting engine which is part of the JDK up to Java 14 (Nashorn scripting engine). From Java 15 onwards the Nashorn scripting engine has been removed from the JDK. SwiftMQ detects that during startup and disables the Streams Swiftlet automatically. So, all functionality provided from this Swiftlet, like the message scheduler, will be unavailable.
To use Java 15 or later with Streams Swiftlet, you need to run SwiftMQ with GraalVM CE which is a next-generation polyglot JVM, based on the standard OpenJDK and provided from Oracle. SwiftMQ has been highly optimized for GraalVM and we recommend using it instead of the standard OpenJDK.
GraalVM CE is free and can be obtained from https://graalvm.org. If you use GraalVM 22.2.0 or later, you need to install the JavaScript engine separately:
$JAVA_HOME/bin/gu install js
Installing GraalVM with the install
script
Since 12.5.0
The install
script is located in the scripts
folder of the distribution and can be used to automatically install the latest tested GraalVM used from this router only.
Using a Web Proxy
Before you invoke it, check whether your host uses a web proxy. In that case, you need to set environment variables (the values are examples) before you invoke the script.
Unix / MacOS:
export proxyhost=192.168.178.34
export proxyport=9080
Windows (PowerShell):
$env:proxyhost='192.168.178.34'
$env:proxyport='9080'
Windows (Terminal CMD.EXE):
set proxyhost=192.168.178.34
set proxyport=9080
Invoking the install script
Invoke the script with
./install [-d]
If you specify -d
, a prior installation of GraalVM will be removed before install.
The script downloads GraalVM and installs Graal.js to execute SwiftMQ Streams. On MacOS you will be asked to enter the sudo
password to remove the quarantine attributes.
Installation from an Archive
Distribution Content
After you have unpacked the archive, you will find the following directory structure below the distribution's top-level directory:
Directory | Content |
---|---|
certs | Self signed TLS certificates and server/client key stores. |
data | All dynamic data of the router like configuration, logs, persistent store |
jars | jar files |
kernel | jar files and config meta data of all Kernel Swiftlets |
optional-swiftlets/extension | Directory for Extension Swiftlets. |
samples | SwiftMQ samples |
scripts | Shell scripts to start the router and cli |
streams | SwiftMQ system streams |
Changing the Heap Memory
To overwrite the default JVM parameters, set the environment variable SWIFTMQ_JVMPARAM
accordingly:
export SWIFTMQ_JVMPARAM="-Xmx4G"
The default setting is -Xmx2G
.
Using a Web Proxy
Since 12.5.0
SwiftMQ normally does not connect to the outside world, except for routing connections. However, if you are using SwiftMQ Streams (or Flow Director flows) on that router which opens REST connections via http/s, you need to set the web proxy as shown here.
Starting the Router
Go to the scripts
directory and start the router as follows:
./router [<preconfig>]
If you are starting it under Windows and use preconfig files, please set it in quotes!
Running SwiftMQ as Docker Container
Preparation
A SwiftMQ Router running in a Docker container has a standard configuration and is stateless. That is, changes in the configuration and persistent data are lost when the container stops. To avoid this, the following preparations need to be done per container.
Recommended Directory Structure per Container on the local Machine
Create the following directory structure somewhere on the machine on which the container is started:
<routername>/
preconfig/
data/
Preconfig
Preconfig is a way to modify an existing router configuration before the router is started. A preconfig is stored in an XML file and contains modifications so that the resulting router configuration exactly matches your router node's configuration.
In the case of a Docker container, the routerconfig.xml
on the first startup of the container is always the standard routerconfig.xml
.
Have a look here at how to create preconfig files.
If you want to connect via JNDI/JMS, the router returns a connectaddress
in the connection factory that points to the internal container hostname, so you can't connect. In your preconfig you should add this JMS listener:
<listener name="internal" port="5001" connectaddress="localhost"/>
If you want to connect with NAT translation from outside a firewall to your Docker host you need to add this JMS listener too:
<listener name="external" port="5002" connectaddress="publichost"/>
Starting the Docker Container
Getting the latest SwiftMQ CE Docker image takes place with:
docker pull iitsoftware/swiftmq-ce:latest
JMS required Hosts
If you have added the external
JMS listener to the preconfig as described before, you need to specify the IP addresses of the host.
Put
--add-host publichost:<public-ip>
to the command line of the Docker container.
Mounts
To ensure that dynamic data such as configuration, logs, persistent data etc survive a container stop, you need to map internal container directory data/
to a directory on your local machine. This is called mount and is done via the -v
option at the command line:
-v <local-directory>:<container-directory>
The internal data directory is under /swiftmq/data
. To map it to a local directory, use (example):
-v /opt/edge1/data:/swiftmq/data
Setting Environment Variables
If you want to apply preconfig files to the container, specify this environment variable:
-e SWIFTMQ_PRECONFIG="/swiftmq/preconfig/preconfig.xml,/swiftmq/preconfig/queues.xml,/swiftmq/preconfig/topics.xml"
The files are applied in the order of definition. Note: The preconfig directory is the directory inside the container (/swiftmq/preconfig
).
To overwrite the default JVM parameters, set environment variable SWIFTMQ_JVMPARAM
accordingly:
-e SWIFTMQ_JVMPARAM="-Xmx4G"
The default setting is -Xmx2G
. Since SwiftMQ runs on GraalVM inside the Docker container, you must use the settings for GraalVM.
Port Mapping
The various ports specified in the router's configuration file needs to be mapped to a port at the local machine by using the -p
option:
-p <local-port>:<container-port>
For example, to map the ports 4001 and 4100 of the above preconfig we use these options:
-p 4001:4001 -p 4100:4100
Start
To start a docker container as a daemon with SwiftMQ CE use this command:
docker run -d <mount-options> <port-mapping-options> <environment-var-options> iitsoftware/swiftmq-ce:<release>
Stop
Stopping a Docker container must always be done with
docker stop <docker-pid>
to ensure a graceful shutdown of the router.
Do not use
docker kill <docker-pid>
as it will hard kill the router which might lead to inconsistencies of the persistent store.
Using Docker Compose
Docker Compose is a docker tool that composes and manages multiple docker container services. It can also be used to manage a single container service. It is very convenient to use.
A yaml
file called docker-compose.yml
must be used to specify the service properties:
version: '3'
services:
swiftmq:
image: "iitsoftware/swiftmq-ce:latest"
ports:
- "4001:4001" # JMS
- "5672:5672" # AMQP
- "1883:1883" # MQTT
- "4100:4100" # Routing Listener
environment:
- SWIFTMQ_PRECONFIG=/swiftmq/preconfig/mynode.xml
volumes:
- ${PWD}/router/preconfig:/swiftmq/preconfig
- ${PWD}/router/data:/swiftmq/data
extra_hosts:
- "dockerhost:${myIP}"
Then create a small shell script that gathers the dockerhost's IP addess:
#!/bin/bash
export myIP=`ifconfig $(netstat -rn | grep -E "^default|^0.0.0.0" | head -1 | awk '{print $NF}') | grep 'inet ' | awk '{print $2}' | grep -Eo '([0-9]*\.){3}[0-9]*'`
export PWD=`pwd`
case "$1" in
start)
docker-compose pull swiftmq
docker-compose up -d
;;
stop)
docker-compose down
;;
status)
docker ps
;;
*)
echo "Usage: $N {start|stop|status}"
exit 1
;;
esac
exit 0
Running a SwiftMQ Router Network on the Same Host
A SwiftMQ Router Network consists of single SwiftMQ Routers that connect and build a network. Some preparations are necessary if these routers run in Docker containers on the same host.
Determine the local IP Address of the Docker Host
The docker host is the machine where all Docker containers are started. To determine the IP address of the host, use ifconfig
. Say it results of a local IP address of 192.168.1.3
.
Publish the Ports of the Routing Listeners
One or more routers of the network will have a routing listener. Say we have 1 router which has a listener on port 4001. This needs to be exposed by the -p
option:
-p 4100:4100
Use the local IP Address in the Routing Connectors
Other routers in the network will connect to one or more routing listeners of other routers. Use the IP address of the Docker host in your preconfig file (example for `edge2``:
<router name="edge2">
<swiftlet name="sys$routing">
<connectors _op="clear">
<connector _op="add" name="edge1" hostname="192.168.1.3" port="4100"/>
</connectors>
<swiftlet>
</router>
Another alternative is to use:
<router name="edge2">
<swiftlet name="sys$routing">
<connectors _op="clear">
<connector _op="add" name="edge1" hostname="dockerhost" port="4100"/>
</connectors>
<swiftlet>
</router>
and use the option:
--add-host dockerhost:192.168.1.3
at the command line of the connecting routers.
This will connect to the Docker host on port 4100 on which the router with the routing listener (done with -p
) is listening. Both containers can now connect.
Recommended Directory Structure for Router Networks
Create a folder somewhere. For each router in the network create a subfolder with the router name. Each of these folders should be structured as described at the beginning of this page (Recommended Directory Structure...).
network/
<routername1>
preconfig/
data/
<routername2>/
preconfig/
data/
Create a new shell script file in this folder (network/
in this example) called rundocker
. It should have this content for SwiftMQ CE:
P=`pwd`
docker run -v "$P/$1/preconfig:/swiftmq/preconfig" \
-v "$P/$1/data:/swiftmq/data" \
$2 \
-e SWIFTMQ_PRECONFIG=/swiftmq/preconfig/preconfig.xml iitsoftware/swiftmq-ce:12.0.0
Say, we have 4 routers, edge1
to edge4
. edge1
has a JMS listener on port 4001 and a routing listener on port 4100. All others have only a routing connector to edge1
.
To start all 4 nodes, use:
./rundocker edge1 "-p 4001:4001 -p 4100:4100" &
./rundocker edge2 "--add-host dockerhost:192.168.1.3" &
./rundocker edge3 "--add-host dockerhost:192.168.1.3" &
./rundocker edge4 "--add-host dockerhost:192.168.1.3" &
All nodes should now be up, running and connected.
Running the Router Network with Docker Compose
The following docker-compose.yml
runs the same above containers:
version: '3'
services:
edge1:
image: "iitsoftware/swiftmq-ce:latest"
ports:
- "4001:4001"
- "4100:4100"
environment:
- SWIFTMQ_PRECONFIG=/swiftmq/preconfig/preconfig.xml
volumes:
- ${PWD}/edge1/preconfig:/swiftmq/preconfig
- ${PWD}/edge1/data:/swiftmq/data
extra_hosts:
- "dockerhost:${myIP}"
edge2:
image: "iitsoftware/swiftmq-ce:12.0.0"
environment:
- SWIFTMQ_PRECONFIG=/swiftmq/preconfig/preconfig.xml
volumes:
- ${PWD}/edge2/preconfig:/swiftmq/preconfig
- ${PWD}/edge2/data:/swiftmq/data
extra_hosts:
- "dockerhost:${myIP}"
edge3:
image: "iitsoftware/swiftmq-ce:12.0.0"
environment:
- SWIFTMQ_PRECONFIG=/swiftmq/preconfig/preconfig.xml
volumes:
- ${PWD}/edge3/preconfig:/swiftmq/preconfig
- ${PWD}/edge3/data:/swiftmq/data
extra_hosts:
- "dockerhost:${myIP}"
edge4:
image: "iitsoftware/swiftmq-ce:12.0.0"
environment:
- SWIFTMQ_PRECONFIG=/swiftmq/preconfig/preconfig.xml
volumes:
- ${PWD}/edge4/preconfig:/swiftmq/preconfig
- ${PWD}/edge4/data:/swiftmq/data
extra_hosts:
- "dockerhost:${myIP}"
With this shell script:
#!/bin/bash
export myIP=`ifconfig $(netstat -rn | grep -E "^default|^0.0.0.0" | head -1 | awk '{print $NF}') | grep 'inet ' | awk '{print $2}' | grep -Eo '([0-9]*\.){3}[0-9]*'`
export PWD=`pwd`
case "$1" in
start)
docker-compose up -d
;;
stop)
docker-compose down
;;
status)
docker ps
;;
*)
echo "Usage: $N {start|stop|status}"
exit 1
;;
esac
exit 0
Starting CLI
To start CLI, SwiftMQ's command-line interface, perform a
./cli
from the scripts
directory. As username/password press the return key (anonymous) or use admin
, password secret
.
Standard Configuration
This distribution contains a standard configuration of a single SwiftMQ router with the name router
.
Authentication
Authentication is disabled, so you can use all resources without defining special grants. To log in, use either the anonymous user (no username, no password) or the administrator account (username admin
, password secret
).
JMS
A JMS listener is configured on port 4001. The JMS listener uses thecom.swiftmq.net.PlainSocketFactory
. A connection factory can be looked up under plainsocket@router
, ConnectionFactory
, QueueConnectionFactory
, TopicConnectionFactory
.
AMQP
An AMQP listener is configured on port 5672 (non-TLS).
MQTT
An MQTT listener is configured on port 1883 (non-TLS).
Routing
A Routing listener is configured on port 4100 (non-TLS).
Point-to-Point Resources
The router has a predefined queue testqueue
which can be looked up via JNDI on testqueue@router
.
Pub/Sub Resources
There is one predefined topic testtopic
that can be looked up via JNDI under this name.
Examples
There are several JMS, AMQP, CLI, and router network examples included in the samples
directory. There is also a Readme.txt
in the samples directory which you may consult before using it.