The Kura simulator is a simulator framework which can act as a Kura gateway instance, without the nessary OSGi runtime and the required hardware abstractions. It can be used to create gateway simulations, testing Kapua.
The following sections assume that you are located in the project folder simulator-kura
and using a
bash-like shell running on Linux. While other environments are possible, some commands might need adaption
for this.
The default main class is org.eclipse.kapua.kura.simulator.main.SimulatorRunner
. It can be run after
the module was built by be executing e.g. (which will print out some basic help):
java -jar target/kapua-simulator-kura-*-app.jar -?
Once properly started the simulator will keep running (other forever or until the specified time elapsed) and then exit. While it is running it will try to stay connected to the broker. For more details about the behavior of the simulator see: Behavior of the simulator.
The application's behavior can be configured either by using command line arguments or by setting environment variables (not Java system properties).
Environment variables will take precedence over command line arguments.
The following options are supported:
-
-?
,--help
- Show help and exit
-
-a
,--account-name
,KSIM_ACCOUNT_NAME
<NAME> -
Set the Kapua account name, defaults to
kapua-sys
-
-c
,--count
,KSIM_NUM_GATEWAYS
<COUNT> -
The number of instances to simulate, defaults to
1
-
-n
,--base-name
,KSIM_BASE_NAME
<PREFIXS> -
The prefix used to construct the simulator id when using the
default
name factory, defaults tosim-
-
--name-factory
,KSIM_NAME_FACTORY
<NAME> - The name factory to use for creating simulator names based on the instance number. Also see Name Factories below.
-
-s
,--seconds
<SECONDS> - The number of seconds after which the simulator will exit. The default is to keep running.
Only one of the follow options may be active:
-
-q
,--quiet
- Suppress output
-
-v
,--verbose
- Show more details
-
-d
,--debug
- Enable debug output
The connection to the broker requires a URL. It is possible to either specify the full URL or specify only parts and let the simulator create the final URL. Both ways are mutually exclusive.
For specifying the full URL use the following option:
-
-b
,--broker
,KSIM_BROKER_URL
- The full URL to the broker
If the full URI is not specified then the simulator will create one based on the following
pattern: <schema>://<user>:<password>@<host>:<port>
using the following options or
their defaults:
-
KSIM_BROKER_SCHEMA
-
The transport schema of the broker, defaults to
tcp
. The following options are available:- tcp
- MQTT over TCP
- ssl
- MQTT over TCP with TLS
- ws
- MQTT over WebSockets
- wss
- MQTT over WebSockets with TLS
-
-h
,--broker-host
,KSIM_BROKER_HOST
-
The hostname of the broker, defaults to
localhost
-
KSIM_BROKER_PORT
-
The port number of the broker, defaults to
1883
-
KSIM_BROKER_USER
-
The user name to use for the MQTT connection to the broker, defaults to
kapua-broker
-
KSIM_BROKER_PASSWORD
-
The password to use for the MQTT connection to the broker, defaults to
kapua-password
If no broker connection options are specified this will result in a broker URL of: tcp://kapua-broker:kapua-password@localhost:1883
.
The simulator runner can also provide a stream of metrics to be sent to Kapua. For this it is necessary to provide a simple simulation model which maps data generators with the actual metrics names.
The simulation configuration is read from a JSON configuration file and can be specified using a local file system path, a URI from which the file can be loaded or a plain JSON content through an environment variable.
-
-f
,--simulation
,KSIM_SIMULATION_URL
- A local file system path or a URI to the JSON configuration file of the data simulation.
-
KSIM_SIMULATION_CONFIGURATION
- The actual JSON content for the simulation.
The following name factories are available:
default
- Use the "base name" as prefix and append the instance number
host:name
-
Use the local hostname as prefix, appending
-
and the instance number. All special characters will get replaces with dashes (-
). host:addr
-
Use the IP address of the local hostname as prefix, appending
-
and the instance number. All special characters will get replaces with dashes (-
). host:iface:name
-
Use the hostname of the main interface as prefix, appending
-
and the instance number. All special characters will get replaces with dashes (-
). host:iface:index
-
Use the index number of the main interface as prefix, appending
-
and the instance number. All special characters will get replaces with dashes (-
). host:iface:mac
-
Use the hex encoded MAC address of the main interface as prefix, appending
-
and the instance number. All special characters will get replaces with dashes (-
).
Once the connection to the broker is established it will issue a "birth certificate" including some dummy information. The information is intended to identify the different fields also by their content and the simulator ID.
The simulator currently supports the following control applications:
- Command The simulated command application will simply reply with some text indicating that the command could not be found.
- Deployment The deployment application will allow to view and controls OSGi bundles and allow to "download" DP archives. However the list of reported OSGi bundles and the download process are only simulated. But adding and removing DP archive will result in more or less OSGi bundles to be reported.
This section describes the simple simulation model which is available in the basic simulation runner. The model is intended to provide a stream of telemetry data for testing.
The basic runner allows to read a JSON representation of the model. Programmatically it is possible to also other other means of configuring a data simulator. This section will however focus on the JSON representation.
A default model would look like:
{
"applications": {
"example1": {
"scheduler": { "period": 2000 },
"topics": {
"t1/data": {
"positionGenerator": "spos",
"metrics": {
"temp1": { "generator": "sine1", "name": "value" },
"temp2": { "generator": "sine2", "name": "value" }
}
},
"t2/data": {
"metrics": {
"temp1": { "generator": "sine1", "name": "value" },
"temp2": { "generator": "sine2", "name": "value" }
}
}
},
"generators": {
"sine1": {
"type": "sine", "period": 1000, "offset": 50, "amplitude": 100
},
"sine2": {
"type": "sine", "period": 2000, "shift": 45.5, "offset": 30, "amplitude": 100
},
"spos": {
"type": "spos"
}
}
}
}
}
Each model consists of a number of "applications", which represent actual Kura applications.
Each application consists of a scheduler, topics and generators. The scheduler defines when the generator values will be refreshed. The topics then map the generated data to topics and metrics.
Generators typically generate their values on a function which maps from timestamp to a value. This makes the generated values comparable as it is clear what can be expected as values. As the scheduler runs all generators with exactly the same timestamp all generators in an application wil generate the same values. For simulators which spawn multiple instances in a single JVM, the scheduler will pass the same timestamp to all applications of all simulator instances.
Under the "generators" section the generator instances get defined. The key can be later on used for
referencing the generator. The simulation runner will search, using the Java ServiceLoader
mechanism
for generator implementations which can provide a generator. Typically the field type
is used to
identify a generator. However every generator factory can opt-in to provide a working generation. If no
generator can be found, then the simulator will fail during startup. This way it is also possible
providing additional generator factories.
Generators can provide three different kinds of payload (body, position, metrics). It depends on the generator implementation which kinds (maybe multiple) it provides. For metrics it also depends on the generator which metric names it provides.
For example the "sine" generator provide a single metric named "value".
The topics section defines a map of topic and their payload mappings. The key of the map is the name of the topic. The available field then are:
- bodyGenerator
- The name of the generator providing the body (BLOB) content
- positionGenerator
- The name of the generator providing the position information
- metrics
- A map for mapping generator values to metric entries
Each metric mapping again has a key (which is used a metric name) and the reference to the
generator (field generator
) and a value of the generator (field name
), as each
generator can technically provide a map of values.
In the above example there are three generators: sine1, sine2 and spos. The first two are sine generators with different configurations and the last one is a position generator with no further configuration.
There is only one application configured (example1
), which has two topics (t1/data
and t2/data
). Each topic has two metrics (temp1
and temp2
), which each reference
to the same generator (temp1
⇒ sine1
: value
).
The following generators are available out of the box.
Processes: type = "sine"
Generates: metrics
- value
- A sine curve based on the provided parameters
Name | Default | Description |
---|---|---|
period | 60000 | The period (in ms) for a full cycle of the curve |
amplitude | 100 | The amplitude of the curve |
offset | 0 | The offset of the curve |
shift | The shift in degrees (0-360) of the curve |
Processes: type = "spos"
Generates: position
Generates a position on the map which will move straight east on the equator. Circling the earth every 80 days. Speed, number of satellites, precision and altitude will be sine curves.
To start simulator with an example simulation configuration, run:
export KSIM_SIMULATION_CONFIGURATION=$(curl -s https://raw.githubusercontent.com/eclipse/kapua/develop/simulator-kura/src/test/resources/example1.json)
java -jar target/kapua-simulator-kura-*-app.jar