Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
9d0b550
Add basic mqtt mosquitto broker docker compose with test file
nataliakenrick Oct 21, 2025
fa2ad6e
Update README.md
nataliakenrick Oct 21, 2025
f31d97f
remove mosquitto.db file
nataliakenrick Oct 23, 2025
7fb3b4b
Use eclipse-mosquitto:latest in docker file
nataliakenrick Oct 23, 2025
d2e2e2b
restructure so docker-compose is for all of bridgehead
nataliakenrick Oct 23, 2025
14da854
move check_mqtt.sh to mosquitto folder
nataliakenrick Oct 23, 2025
4cb9b69
Merge remote-tracking branch 'origin/Basic-deployment-bundle-stage-on…
nataliakenrick Oct 23, 2025
0200991
Remove mosquitto image from docker compose as this is in the Dockerfi…
nataliakenrick Oct 23, 2025
ea2d408
Merge remote-tracking branch 'origin/Basic-deployment-bundle-stage-on…
nataliakenrick Oct 23, 2025
0237c08
Update bridghead docker compose setup to include core udmi services
nataliakenrick Nov 3, 2025
002bb11
Update mosquitto_ctrl.sh to use env variables for MQTT host and port …
nataliakenrick Nov 3, 2025
482f5b0
Update README, add example outputs
nataliakenrick Nov 5, 2025
82886ed
Fix typo in udmis_output.md
nataliakenrick Nov 10, 2025
0cb1638
Merge branch 'master' into Core-UDMI-Services-Integration-stage-two
nataliakenrick Nov 11, 2025
a1538cd
Remove unused files
nataliakenrick Nov 20, 2025
51a4284
Update README
nataliakenrick Nov 21, 2025
3edd59a
Allow pubber connections from external hosts. Run registrar on startu…
nataliakenrick Nov 21, 2025
5fa88ca
Merge branch 'faucetsdn:master' into Core-UDMI-Services-Integration-s…
nataliakenrick Nov 21, 2025
0f4c257
Merge branch 'Core-UDMI-Services-Integration-stage-two' of https://gi…
nataliakenrick Nov 21, 2025
1d5e65d
update README
nataliakenrick Nov 21, 2025
5ab7eef
remove pubber from compose, update readme
nataliakenrick Nov 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion bin/keygen
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ CA_SRL=$CA_DIR/ca.srl
CA_KEY=$CA_DIR/rsa_private.pem
OPTS_509=/tmp/x509opts.txt

echo "subjectAltName=DNS:${TARGET_HOST}, IP:127.0.0.1, DNS:localhost" > $OPTS_509
if [[ -n "$HOST_IP" ]]; then
echo "subjectAltName=DNS:${TARGET_HOST}, IP:127.0.0.1, IP:${HOST_IP}, DNS:localhost" > $OPTS_509
else
echo "subjectAltName=DNS:${TARGET_HOST}, IP:127.0.0.1, DNS:localhost" > $OPTS_509
fi

x509opts="-days 3650 -extfile $OPTS_509"

if [[ $type == CA ]]; then
Expand Down
65 changes: 52 additions & 13 deletions bridgehead/README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,65 @@
# MQTT Broker Environment Setup
# Core UDMI Services Environment Set Up

This guide provides instructions for deploying and verifying the **Mosquitto MQTT broker** using Docker Compose.
This guide provides instructions for deploying the core UDMI services bundle. This bundle includes:
- Mosquitto broker
- etcd server
- udmis service
- validator service (includes registrar tool)

### Broker access details
## Setting up the Docker environment

- **Broker address**: The host machine's local IP address (e.g., `localhost` or `127.0.0.1`).
- **Port**: `1883`
1. **Install docker engine:** Ensure Docker is installed and running on your system: `https://docs.docker.com/engine/install/`

The configuration is designed for connections without client credentials.
2. **Navigate to project directory:** Open your terminal and change the directory to the project root containing the `docker-compose.yml` file (`bridgehead/`).

### Setting up the docker environment
3. **Get default site model:** In you terminal, run `sudo git clone https://github.com/faucetsdn/udmi_site_model.git`.

1. **Install docker engine:** Ensure Docker is installed and running on your system: `https://docs.docker.com/engine/install/`
4. **Add your host ip:** Open the docker-compose.yml file and locate the line `HOST_IP: <YOUR_IP>` inside the mosquitto service block. Replace `<YOUR_IP>` with your hosts ip address. You can find this by running `sudo hostname -I`. This is required in order tp allow connections to the broker externally from the docker compose environment.

2. **Navigate to project directory:** Open your terminal and change the directory to the project root containing the `docker-compose.yml` file (`bridgehead/`).

3. **Deploy the service:** Execute the following command to build the custom image (if needed) and start the Mosquitto container in detached mode.
5. **Deploy the service:** Execute the following command to build the custom images (if needed) and start the containers in detached mode.
* **First time/after changes:** Run `sudo docker compose up -d --build`
* **Standard run:** Run `sudo docker compose up -d`
6. **Confirm all containers are running:** Run `sudo docker ps` in the terminal, you should see the following containers in any order:
- validator
- udmis
- mosquitto
- etcd

## Tools

The UDMI tools should only be run after the udmis service has completed setup. You can confirm this by comparing your udmis output to the [sample udmis output](sample_outputs/udmis_output.md).

### Registrar

The following commands should be run in the same directory as the Docker Compose (`bridgehead/`).

In your terminal, execute `sudo docker exec validator bin/registrar site_model/ //mqtt/mosquitto`. To confirm a successful execution, take a look at the [sample registrar output](sample_outputs/registrar_output.md)

### Pubber

The pubber tool will only have a successful output after the registrar tool has been executed. This is done by default in compose setup.

4. **Run connectivity check:** Confirm the broker is up and running by executing `sudo docker compose exec mosquitto /usr/local/bin/check_mqtt.sh`. This script performs an internal publish/subscribe self-test. A successful output confirms the broker is fully operational and accepting client connections.
#### Setup if running pubber on separate machine

### Shutting down the docker environment
Pubber requires access to the site model. There are 2 ways to get pubber setup with a working site model.

1. The quickest setup is to copy across the site model from the `bridgehead/` directory after setup as this will already have all the necessary keys. (alternatively, push the changes to your own repository and pull this on the external computer)

2. Manually create the necessary keys: *Note: these instructions are assuming you are using the default udmi_site_model*
- On your external computer, clone the udmi site model and udmi: `sudo git clone https://github.com/faucetsdn/udmi_site_model.git`, `sudo git clone https://github.com/faucetsdn/udmi.git`.
- Export your docker compose host ip (the same one we set in the docker compose): `export HOST_IP=<YOUR_HOST_IP>`
- Generate keys: `sudo udmi/bin/keygen CA/<YOUR_HOST_IP> udmi_site_model/reflector` and `sudo udmi/bin/keygen CERT/<YOUR_HOST_IP> udmi_site_model/reflector`.

#### Run tool

Start pubber container: `sudo docker run -d --rm --name pubber -v $(realpath udmi_site_model):/root/site_model ghcr.io/faucetsdn/udmi:pubber-latest /bin/bash -c "tail -f /dev/null"`

Run pubber: `sudo docker exec pubber bin/pubber site_model/ //mqtt/<YOUR_HOST_IP> AHU-1 123456`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update this as pubber container will not be there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a separate command; it will create a standalone pubber container for testing, but it isn't part of the Docker Compose. This container can be run on the same machine as the Docker Compose, or on an external machine. Would still like me to remove it/improve the documentation so this is clear?


Pubber is running successfully if there are no obvious error messages or retries. An **unsuccessful** run will retry multiple times, will see messages like `Attempt #10 failed`.

A successful run will not end on its own, you can press `Ctrl` + `C` on your keyboard to exit.
## Shutting down the docker environment

To gracefully stop and remove the container, run: `sudo docker compose down`

73 changes: 69 additions & 4 deletions bridgehead/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,73 @@ services:
context: ./mosquitto
container_name: mosquitto
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
- ./udmi_site_model:/site_model
- ./var/mosquitto:/etc/mosquitto
- ./var/mosquitto/data:/mosquitto/data
- ./var/mosquitto/log:/var/log/mosquitto/
ports:
- 1883:1883
- "8883:8883"
restart: always
networks:
- udminet
environment:
HOST_IP: <YOUR_IP>

etcd:
image: quay.io/coreos/etcd:v3.5.13
container_name: etcd
volumes:
- ./var/etcd:/var/etcd
ports:
- "2379:2379"
networks:
- udminet
restart: always
command: ["etcd", "-listen-client-urls=http://0.0.0.0:2379", "-advertise-client-urls=http://etcd:2379", "--data-dir", "/var/etcd"]

udmis:
build:
context: ./udmis
container_name: udmis
volumes:
- ./udmi_site_model:/root/site_model
- ./var/tmp:/tmp
- ./var/etcd:/root/udmi/var/etcd
- ./var/mosquitto/log:/var/log/mosquitto
- ./var/mosquitto/certs:/etc/mosquitto/certs
depends_on:
etcd:
condition: service_started
mosquitto:
condition: service_started
restart: always
networks:
- udminet
environment:
ETCD_CLUSTER: etcd
MQTT_HOST: mosquitto
MQTT_PORT: 8883

validator:
build:
context: ./validator
container_name: validator
volumes:
- ./udmi_site_model:/root/site_model
- ./var/mosquitto/log:/var/log/mosquitto
- ./var/mosquitto/certs:/etc/mosquitto/certs
- ./var/tmp:/usr/local/bin/udmis
depends_on:
udmis:
condition: service_started
restart: always
networks:
- udminet

networks:
udminet:
name: udminet
driver: bridge
ipam:
config:
- subnet: 192.168.99.0/24
13 changes: 11 additions & 2 deletions bridgehead/mosquitto/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
FROM ghcr.io/faucetsdn/udmi:udmis-latest AS udmi
FROM eclipse-mosquitto:latest

COPY check_mqtt.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/check_mqtt.sh
RUN apk add --no-cache bash jq sudo git mosquitto mosquitto-clients openssl sed

COPY --from=udmi /root/udmi/bin /root/udmi/bin
COPY --from=udmi /root/udmi/etc /root/udmi/etc

COPY mosquitto_startup.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/mosquitto_startup.sh

CMD ["/usr/local/bin/mosquitto_startup.sh"]

28 changes: 0 additions & 28 deletions bridgehead/mosquitto/check_mqtt.sh

This file was deleted.

7 changes: 0 additions & 7 deletions bridgehead/mosquitto/config/mosquitto.conf

This file was deleted.

38 changes: 38 additions & 0 deletions bridgehead/mosquitto/mosquitto_startup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/sh
UDMI_ROOT=/root/udmi

function fail {
echo error: $*
false
}

echo "persistence true
persistence_file mosquitto.db
persistence_location /mosquitto/data/

include_dir /etc/mosquitto/conf.d" > /etc/mosquitto/mosquitto.conf

cd $UDMI_ROOT

site_model=$(realpath /site_model)
site_config=$site_model/cloud_iot_config.json
registry_id=$(jq -r .registry_id $site_config)

source $UDMI_ROOT/etc/mosquitto_ctrl.sh
mkdir -p $CERT_DIR

if [[ -n "$HOST_IP" ]]; then
sed -i -e "s|IP:127.0.0.1,|IP:127.0.0.1, IP:${HOST_IP},|" bin/keygen
fi

bin/setup_ca $site_model mosquitto
bin/start_mosquitto

$MOSQUITTO_CTRL deleteClient $SERV_USER
$MOSQUITTO_CTRL createClient $SERV_USER -p $SERV_PASS
$MOSQUITTO_CTRL addClientRole $SERV_USER service

echo Starting initializing site $site_model | tee -a $UDMIS_LOG
bin/mosquctl_site $site_model

sleep infinity
131 changes: 131 additions & 0 deletions bridgehead/sample_outputs/registrar_output.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
### Sample registrar service output for bridgehead docker setup

The registrar should only be run after the udmis service has been setup successfully (see the [sample udmis output](sample_outputs/udmis_output.md))

The registrar has been run successfully if you see no errors and can spot the lines:


```
Processed AHU-22 (3/4) in 0.029s (add)
Processed SNS-4 (4/4) in 0.029s (add)
Processed AHU-1 (2/4) in 0.102s (add)
Processed GAT-123 (1/4) in 0.164s (add)
```

Sample output after running `sudo docker exec validator bin/registrar site_model/ //mqtt/mosquitto`:

```
starting run at 2025-11-05T10:12:02+00:00
java -cp /root/validator/build/libs/validator-1.0-SNAPSHOT-all.jar com.google.daq.mqtt.util.Dispatcher registrar site_model/ //mqtt/mosquitto
Writing reconciled configuration file to /root/out/registrar_conf.json
Using reflector iot client
Instantiating reflector client //mqtt/mosquitto/ ZZ-TRI-FECTA
10:12:03.559 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - Loaded key /root/site_model/reflector/rsa_private.pkcs8 as sha256 42a8a8f1287aa775
10:12:03.569 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - ZZ-TRI-FECTA token expiration sec 3600
10:12:03.585 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - Using hash-key username/password /r/UDMI-REFLECT/d/ZZ-TRI-FECTA 42a8a8f1
10:12:03.686 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - CA cert file: /root/site_model/reflector/ca.crt
10:12:03.686 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - Device cert file: /root/site_model/reflector/rsa_private.crt
10:12:03.686 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - Private key file: /root/site_model/reflector/rsa_private.pem
10:12:03.686 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - Password sha256 0049165a
10:12:03.703 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - ZZ-TRI-FECTA creating client /r/UDMI-REFLECT/d/ZZ-TRI-FECTA on ssl://mosquitto:8883
10:12:03.917 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - ZZ-TRI-FECTA creating new auth token for audience mosquitto
10:12:03.917 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - Using hash-key username/password /r/UDMI-REFLECT/d/ZZ-TRI-FECTA 42a8a8f1
10:12:03.917 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - ZZ-TRI-FECTA connecting to mqtt server ssl://mosquitto:8883
10:12:04.069 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - Subscribing with qos 1 to topic /r/UDMI-REFLECT/d/ZZ-TRI-FECTA/config
10:12:04.071 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - Subscribing with qos 1 to topic /r/UDMI-REFLECT/d/ZZ-TRI-FECTA/errors
10:12:04.072 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - Subscribing with qos 0 to topic /r/UDMI-REFLECT/d/ZZ-TRI-FECTA/commands/#
10:12:04.073 [main] INFO c.g.bos.iot.core.proxy.MqttPublisher - ZZ-TRI-FECTA done with setup connection
Starting initial UDMI setup process
Sending UDMI reflector state to ZZ-TRI-FECTA: {
"version" : "unknown",
"udmi" : {
"setup" : {
"udmi_version" : "unknown",
"functions_ver" : 18,
"udmi_commit" : "unknown",
"udmi_timever" : "unknown",
"msg_source" : "debug",
"tool_name" : "registrar",
"transaction_id" : "RC:92f139.00000001"
}
},
"timestamp" : "2025-11-05T10:12:03Z"
}
Received UDMI reflector initial config: {
"last_state" : "2025-11-05T10:12:03Z",
"reply" : {
"udmi_version" : "unknown",
"functions_ver" : 18,
"udmi_commit" : "unknown",
"udmi_timever" : "unknown",
"msg_source" : "debug",
"tool_name" : "registrar",
"transaction_id" : "RC:92f139.00000001"
},
"setup" : {
"hostname" : "5b24b7e56992",
"functions_min" : 18,
"functions_max" : 18,
"udmi_version" : "1.5.4-21-g61e7dba5",
"udmi_commit" : "61e7dba58",
"udmi_ref" : "ghcr.io/faucetsdn/udmi:udmis-g61e7dba5",
"udmi_timever" : "2025-11-04T13:20:19Z",
"built_at" : "2025-11-04T13:30:00Z",
"built_by" : "runner@runnervmf2e7y"
}
}
Subscribed to /r/UDMI-REFLECT/d/ZZ-TRI-FECTA
Instantiated iot provider mqtt as IotReflectorClient
Working with project mosquitto registry us-central1/ZZ-TRI-FECTA
Loading site_defaults.json
Initializing 4 local devices...
Starting initialize settings for 4 devices...
Waiting 61s for 4 tasks to complete...
Fetching devices from registry ZZ-TRI-FECTA...
2025-11-05T10:12:04Z Fetched 0 devices.
Fetched 0 device models from cloud registry
Processing 4 new devices...
Waiting for device processing...
Waiting 61s for 4 tasks to complete...
Processed AHU-22 (3/4) in 0.029s (add)
Processed SNS-4 (4/4) in 0.029s (add)
Processed AHU-1 (2/4) in 0.102s (add)
Processed GAT-123 (1/4) in 0.164s (add)
Processed 4 (skipped 0) devices in 0.823s, 0.205s/d
Updating 0 existing devices...
Waiting for device processing...
Processed 0 (skipped 0) devices in 0.000s, 0.000s/d
Updated 0 device metadata files.
Finished processing 4/4 devices.
Binding devices to gateways: [GAT-123]
Waiting for device binding...
Waiting for tasks to complete...
Already bound to GAT-123: []
Binding [AHU-22, SNS-4] to GAT-123 (1/1)
Finished binding gateways in 0.151
Starting writing normalized for 4 devices...
Waiting 61s for 4 tasks to complete...
Writing normalized /root/site_model/devices/AHU-22/out/metadata_norm.json
Writing normalized /root/site_model/devices/GAT-123/out/metadata_norm.json
Writing normalized /root/site_model/devices/AHU-1/out/metadata_norm.json
Writing normalized /root/site_model/devices/SNS-4/out/metadata_norm.json
Starting previewing model for 4 devices...
Waiting 61s for 4 tasks to complete...
Starting validating expected for 4 devices...
Waiting 61s for 4 tasks to complete...
Starting validate samples for 4 devices...
Waiting 61s for 4 tasks to complete...
Starting validating keys for 4 devices...
Waiting 61s for 4 tasks to complete...
Starting process externals for 4 devices...
Waiting 61s for 4 tasks to complete...
Updating errors site_model/devices/AHU-1/out/errors.map

Summary:
Device envelope: 1
Device status: 4
Device validation: 1
Out of 4 total.
Registration summary available in /root/site_model/out/registration_summary.json
Registration summary available in /root/site_model/out/registration_summary.csv
```
Loading