Skip to content
Draft

Mqtt #1732

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
fc86b6a
Add a shared lib for use between BELY and CDB for MQTT integration an…
iTerminate Oct 2, 2026
5077539
Add scripts to create and deploy mqtt connection configuration
iTerminate Oct 2, 2026
b15f007
Add libs required for mqtt connection.
iTerminate Oct 2, 2026
b3b5498
the shared lib also contains the base mqttEvent.
iTerminate Oct 2, 2026
373eb84
Refactor rename the shared lib to base-cdb-mqtt
iTerminate Oct 2, 2026
719e160
Refactor rename the shared lib to base-cdb-mqtt
iTerminate Oct 2, 2026
fc2a49a
Initial MQTT integration base
iTerminate Oct 2, 2026
0136ccd
Run tests upon changes to the lib.
iTerminate Oct 2, 2026
ed435e4
Run tests in CI upon changes to the lib.
iTerminate Oct 2, 2026
deb9f0e
Merge branch 'master' into mqtt
iTerminate Nov 5, 2026
a0523d9
Add support for adding "specailized" specific change events.
iTerminate Nov 5, 2026
49e325a
Add new property changes events.
iTerminate Nov 5, 2026
6ca76f0
Refactor textOmmitted for clarity
iTerminate Nov 5, 2026
4c17757
Hook property value changes into generation of property value history.
iTerminate Nov 5, 2026
76dbddb
Add appropriate events based on changes that have been populated by p…
iTerminate Nov 5, 2026
688592c
Extend the test framework for the property events.
iTerminate Nov 5, 2026
d2fba9f
Add a base class for all cdb mqtt events.
iTerminate Nov 6, 2026
56aa8e2
Add a mqtt event classes for representing the machien design assigned…
iTerminate Nov 6, 2026
55bfc8b
Add hooks for adding event when changes to the assigned item in the m…
iTerminate Nov 6, 2026
7d097a9
Add unit tests for the new machine design assignment events.
iTerminate Nov 6, 2026
e3a37fa
Refactor to add PropertyValueChange into the new mqtt metadata package.
iTerminate Nov 6, 2026
a842d30
Add a new mqtt model for machine design move events.
iTerminate Nov 6, 2026
1ed3d61
Integrate event after the move update was performed.
iTerminate Nov 6, 2026
6bf3c99
Add unit tests
iTerminate Nov 6, 2026
0486730
Extend the model to expose the item entity type this contains informa…
iTerminate Nov 6, 2026
c7122ed
Add models to support the new machine design represented element chan…
iTerminate Nov 6, 2026
0523b9a
Hook the change into the assigned item history check.
iTerminate Nov 6, 2026
67b1aab
Add unit tests for the new functionality.
iTerminate Nov 6, 2026
064762e
Add a template metadata if a reprented element is updated via template.
iTerminate Nov 6, 2026
c6ceda2
Integrate propagation of item element representation to template mqtt…
iTerminate Nov 6, 2026
890b425
Add tests for represetned item elements
iTerminate Nov 6, 2026
df50326
Add enum for operation to keep the options consistent accross the app…
iTerminate Nov 6, 2026
54dcdf0
Add model to support trash mqtt eventss
iTerminate Nov 6, 2026
e4c036a
Hook the trash events into the standard workflows.
iTerminate Nov 6, 2026
e85d866
Add unit tests for new trash events
iTerminate Nov 6, 2026
5fbb916
Add location change mqtt event model
iTerminate Nov 6, 2026
ecc471b
Add location change mqtt event model
iTerminate Nov 6, 2026
74c9a7b
Hook location change into the location change workflow.
iTerminate Nov 6, 2026
9539199
Add tests for new location change workflow
iTerminate Nov 6, 2026
4facd5b
Add events for assembly element changes.
iTerminate Nov 6, 2026
ed0fadb
Hook assembly change into function where it gets updated.
iTerminate Nov 6, 2026
f7c6b1d
Add tests for updating assembly element mqtt events.
iTerminate Nov 6, 2026
ecacbc2
Resolve issue with delete event not being published
iTerminate Nov 6, 2026
42708e1
Move the detection of assembly changes to top level. Resolve assembly…
iTerminate Nov 6, 2026
0b32383
Add mqtt test framework setup
iTerminate Nov 9, 2026
55a49af
Add test for creating and removing entity. Add property add update test.
iTerminate Nov 9, 2026
bdf9fe0
Add inventory assembly assing/clear plus location update
iTerminate Nov 9, 2026
55d85e6
Add machine design move, update assigned item/represented item.
iTerminate Nov 9, 2026
833eae8
Extend to selenium to test Events not supported by API
iTerminate Nov 9, 2026
80a7c85
Fianlize test framework
iTerminate Nov 9, 2026
315fc92
add new shared functionality.
iTerminate Nov 9, 2026
ef4a89e
Expand the test coverage for machine design assigned update trash res…
iTerminate Nov 9, 2026
6361c3f
Add remaining topics to selenium tests.
iTerminate Nov 9, 2026
43f362c
extend the mqtt tests to basic make test as well
iTerminate Nov 9, 2026
477a0c6
Use the new standardized way for selecting catalog item.
iTerminate Nov 9, 2026
449f592
Add model to support addition of new machines
iTerminate Nov 12, 2026
1ddc425
Hook creation and publication of new models
iTerminate Nov 12, 2026
b10c8c5
Refactor specialized create events and specailized update events for …
iTerminate Nov 12, 2026
221327f
Add tests for machine design add events.
iTerminate Nov 12, 2026
868be4c
Extend the model to support template information when triggered from …
iTerminate Nov 12, 2026
7baf043
Hook into template creation
iTerminate Nov 12, 2026
751a1e8
Add tests for template creation machine events
iTerminate Nov 12, 2026
11d34de
Add model to support add update delete for log entries.
iTerminate Nov 12, 2026
1965f30
Add a shared utility for text diff between property and log text
iTerminate Nov 12, 2026
a78c134
Add new REST endpoints for update and delete log entry
iTerminate Nov 12, 2026
cf05486
Destroy is now called upon sucesful updateOnRemoval.
iTerminate Nov 12, 2026
7125ce9
Add hooks to publish log entry event changes.
iTerminate Nov 12, 2026
db9f9a0
Resolve template xpath
iTerminate Nov 12, 2026
4e800c1
Add tests for the new log entry mqtt events.
iTerminate Nov 12, 2026
d9b6ea0
Refactir to add a standardized way of adding attachments via the cont…
iTerminate Nov 12, 2026
6df8545
Hook in log utility for standard way of adding attachments
iTerminate Nov 12, 2026
8e06df5
Add model to capture log attachment changes
iTerminate Nov 13, 2026
fa5e46d
Attachments get identified by name instead of attachment id to simpli…
iTerminate Nov 13, 2026
5ddc48a
Hook attachment events into the item update cycle.
iTerminate Nov 13, 2026
8ed5a26
Add tests to verify attachment events get fired for mqtt
iTerminate Nov 13, 2026
e43c290
Add documentation for new tests
iTerminate Nov 13, 2026
7729297
Add combined log edit test
iTerminate Nov 13, 2026
ab1d407
Start release notes for 3.20 MQTT release
iTerminate Nov 13, 2026
2031a00
Update claude md to create release notes at the end of a plan.
iTerminate Nov 13, 2026
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
45 changes: 45 additions & 0 deletions .github/workflows/cdb-base-mqtt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: CDB Base MQTT

on:
push:
paths:
- "tools/developer_tools/cdb-base-mqtt/**"
- ".github/workflows/cdb-base-mqtt.yml"
pull_request:
paths:
- "tools/developer_tools/cdb-base-mqtt/**"
- ".github/workflows/cdb-base-mqtt.yml"
workflow_dispatch:

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: tools/developer_tools/cdb-base-mqtt

steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Java 8 and Maven cache
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "8"
cache: maven
cache-dependency-path: tools/developer_tools/cdb-base-mqtt/pom.xml

- name: Run tests
run: mvn --batch-mode --no-transfer-progress verify

- name: Publish test results
if: always()
uses: actions/upload-artifact@v4
with:
name: cdb-base-mqtt-test-results
path: tools/developer_tools/cdb-base-mqtt/target/surefire-reports/
if-no-files-found: warn
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ MariaDB 10.5. Authoritative schema is the set of `create_cdb_tables.sql`, `creat
- **Generated files that look like sources** are common: `cdb.portal.properties`, `web/WEB-INF/glassfish-web.xml`, `web/WEB-INF/web.xml`, `setup/glassfish-resources.xml`, `nbproject/private/private.properties`, and everything under `tools/developer_tools/python-client/packages/api/cdbApi/`. They are produced from `*.template` files (or via openapi-generator) by `dev-config` / `configure-web-portal` / `dist` targets and are in `.gitignore`. Edit the template, regenerate, then commit only the template.
- **`cdb` vs `cdb_dev`**: every db, deploy, undeploy, and backup target has a `-dev` variant that targets a separate database name and Payara domain, so a developer can run both side-by-side. When adding new admin scripts, follow the same pattern (first arg is DB name, defaulting to `cdb`).
- **Single canonical version string**: run `make prepare-release` (`sbin/cdb_prepare_release.py`) to bump `etc/version`, `openapi.yaml`, the web `?v=` cache-busters, the python-client `packages/*/pyproject.toml`/conda recipes, and scaffold `docs/release-notes/<VERSION>.md` together. It also flags any file that drifted out of sync in a prior manual release, and refreshes `uv.lock`.
- **Release notes as a plan milestone**: when planning a feature, include updating `docs/release-notes/<VERSION>.md` as the final milestone. Use the in-progress version (unreleased versions may already have notes; `etc/version` lags until `make prepare-release`), and create the file if it doesn't exist. Match the style of existing notes: `#` headings per area (e.g. `# MQTT`, `# API`, `# Testing`, `# Bug Fixes`), concise user-facing `*` bullets with nested sub-bullets for detail, and no commit hashes or file lists. Only list fixes to previously released behavior under Bug Fixes.
- **Plugins** under `tools/developer_tools/cdb_plugins/plugins/<name>/` extend both the Java portal (deployed via `make deploy-cdb-plugin` → `update_plugin_generated_files.py`) and the Python web service. `pluginTemplates/` is the scaffold.
- **REST changes touch three places**: the Java route, `openapi.yaml`, and (after `generatePyClient.sh`) the regenerated `cdbApi/` package. The Python API tests under `tools/developer_tools/python-client/test/` are the integration check.

Expand Down
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ TOP = .
SUBDIRS = src

.PHONY: support support-mysql dev-config prepare-release release-python-client
.PHONY: mqtt-configuration configure-mqtt mqtt-configuration-dev configure-mqtt-dev
.PHONY: db backup db-dev deploy-web-portal undeploy-web-portal deploy-web-service undeploy-web-service
.PHONY: db-dev backup-dev deploy-web-portal-dev undeploy-web-portal-dev deploy-web-service-dev undeploy-web-service-dev

Expand All @@ -28,6 +29,12 @@ release-python-client:
configuration:
$(TOP)/sbin/cdb_create_configuration.sh

mqtt-configuration:
$(TOP)/sbin/cdb_create_mqtt_configuration.sh cdb

configure-mqtt:
$(TOP)/sbin/cdb_configure_mqtt_service.sh cdb

support:
$(TOP)/sbin/cdb_install_support.sh

Expand Down Expand Up @@ -79,6 +86,12 @@ undeploy-web-service:
configuration-dev:
$(TOP)/sbin/cdb_create_configuration.sh cdb_dev

mqtt-configuration-dev:
$(TOP)/sbin/cdb_create_mqtt_configuration.sh cdb_dev

configure-mqtt-dev:
$(TOP)/sbin/cdb_configure_mqtt_service.sh cdb_dev

db-dev:
$(TOP)/sbin/cdb_create_db.sh cdb_dev

Expand Down
44 changes: 44 additions & 0 deletions docs/release-notes/3.20.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# MQTT

* Added MQTT integration. The portal publishes change events to an MQTT broker so external systems (e.g. BELY) can react to CDB changes.
* Shared `cdb-base-mqtt` library for MQTT connection and event serialization, used by both BELY and CDB.
* Events include the affected entity, the user who triggered the change, and details of what changed.
* Consistent operation names across events (add, update, delete, trash, restore).
* Entity events
* Item add, update, and delete.
* Property events
* Property value add, update, and delete, with the before and after values.
* Log events
* Log entry add, update, and delete, with the before and after text.
* Log attachment add.
* Machine design events
* New machine design, including ones created from a template.
* Assigned item update.
* Move within the machine hierarchy.
* Represented element update, including changes made through a template.
* Trash and restore.
* Inventory events
* Location update.
* Assembly element assignment and clearing.
* Configuration
* `make mqtt-configuration` and `make configure-mqtt` (with `-dev` variants) to create and deploy the MQTT connection configuration.

# API

* Ability to update an existing log entry.
* Ability to delete a log entry.
* Attachments added via the API, utilities, and the portal now use the same workflow.

# Testing

* Added unit tests for all MQTT event models and change detection.
* Added an MQTT test framework that listens to the broker and verifies published events.
* Python API tests for events that can be triggered via the API.
* Selenium tests for events only available in the portal.
* MQTT tests are included in `make test`.
* CI runs the shared MQTT library tests when it changes.
* Documented the new tests in the python client and Selenium READMEs.

# Bug Fixes

* Destroy is now called after a successful `updateOnRemoval`, removing the need for workarounds in the log list views.
170 changes: 170 additions & 0 deletions sbin/cdb_configure_mqtt_service.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#!/bin/bash

# Copyright (c) UChicago Argonne, LLC. All rights reserved.
# See LICENSE file.


#
# Script used for configuring MQTT connector for CDB webapp
# Deploys MQTT Resource Adapter and creates connection pool/resource
#
# Usage:
#
# $0 [CDB_DB_NAME] [mqtt_config_file]
#
# If no config file is specified, defaults to $CDB_INSTALL_DIR/etc/<CDB_DB_NAME>.mqtt.conf
#
# Sample MQTT configuration file contents (mqtt.conf):
# MQTT_HOST=localhost # MQTT broker hostname (default: localhost)
# MQTT_PORT=1883 # MQTT broker port (default: 1883)
# MQTT_USERNAME=admin # MQTT username (optional)
# MQTT_PASSWORD=admin # MQTT password (optional)
# MQTT_CLEAN_SESSION=true # Clean session flag (optional)
# MQTT_QOS=1 # Quality of Service level (optional)
# MQTT_KEEP_ALIVE_INTERVAL=60 # Keep alive interval in seconds (optional)
# MQTT_CONNECTION_TIMEOUT=30 # Connection timeout in seconds (optional)
# MQTT_MAX_INFLIGHT=10 # Maximum number of messages in flight (optional)
# MQTT_AUTOMATIC_RECONNECT=true # Automatic reconnection on disconnect (optional)
# MQTT_FILE_PERSISTANCE=false # Enable file-based message persistence (optional)
# MQTT_PERSISTENCE_DIRECTORY=. # Directory for persistent message storage (optional)
# MQTT_TOPIC_FILTER # MQTT topic filter for subscriptions (optional)

MY_DIR=`dirname $0` && cd $MY_DIR && MY_DIR=`pwd`
if [ -z "${CDB_ROOT_DIR}" ]; then
CDB_ROOT_DIR=$MY_DIR/..
fi
CDB_ENV_FILE=${CDB_ROOT_DIR}/setup.sh
if [ ! -f ${CDB_ENV_FILE} ]; then
echo "Environment file ${CDB_ENV_FILE} does not exist."
exit 2
fi
. ${CDB_ENV_FILE} > /dev/null

# Constants
MQTT_POOL_NAME="cdb/MQTT/pool"
MQTT_RESOURCE_NAME="cdb/MQTT/resource"
MQTT_RAR_NAME="mqtt-rar-0.8.0"
MQTT_CONNECTOR_RAR_DEPLOYMENT_NAME="cdb-mqtt-rar-deployment"
MQTT_RAR_PATH=$CDB_ROOT_DIR/src/lib/${MQTT_RAR_NAME}.rar

# Look for the deployment-specific MQTT configuration file
CDB_DB_NAME=${1:-${CDB_DB_NAME:-cdb}}
if [ ! -z "$2" ]; then
mqttConfigFile=$2
else
mqttConfigFile=$CDB_INSTALL_DIR/etc/${CDB_DB_NAME}.mqtt.conf
fi

if [ -f $mqttConfigFile ]; then
echo "Using MQTT config file: $mqttConfigFile"
. $mqttConfigFile
else
echo "Error: MQTT config file $mqttConfigFile not found."
echo "You can create one using cdb_create_mqtt_configuration.sh ${CDB_DB_NAME}"
exit 1
fi

CDB_HOST_ARCH=$(uname -sm | tr -s '[:upper:][:blank:]' '[:lower:][\-]')
GLASSFISH_DIR=$CDB_SUPPORT_DIR/payara/$CDB_HOST_ARCH

ASADMIN_CMD=$GLASSFISH_DIR/bin/asadmin

# MQTT Configuration defaults
MQTT_HOST=${MQTT_HOST:=localhost}
MQTT_PORT=${MQTT_PORT:=1883}

# Build properties string for connection pool
PROPERTIES="serverURIs=tcp\\://${MQTT_HOST}\\:${MQTT_PORT}"

if [ ! -z "$MQTT_USERNAME" ]; then
PROPERTIES="${PROPERTIES}:userName=${MQTT_USERNAME}"
fi

if [ ! -z "$MQTT_PASSWORD" ]; then
PROPERTIES="${PROPERTIES}:password=${MQTT_PASSWORD}"
fi

if [ ! -z "$MQTT_CLEAN_SESSION" ]; then
PROPERTIES="${PROPERTIES}:cleanSession=${MQTT_CLEAN_SESSION}"
fi

if [ ! -z "$MQTT_KEEP_ALIVE_INTERVAL" ]; then
PROPERTIES="${PROPERTIES}:keepAliveInterval=${MQTT_KEEP_ALIVE_INTERVAL}"
fi

if [ ! -z "$MQTT_CONNECTION_TIMEOUT" ]; then
PROPERTIES="${PROPERTIES}:connectionTimeout=${MQTT_CONNECTION_TIMEOUT}"
fi

if [ ! -z "$MQTT_MAX_INFLIGHT" ]; then
PROPERTIES="${PROPERTIES}:maxInflight=${MQTT_MAX_INFLIGHT}"
fi

if [ ! -z "$MQTT_AUTOMATIC_RECONNECT" ]; then
PROPERTIES="${PROPERTIES}:automaticReconnect=${MQTT_AUTOMATIC_RECONNECT}"
fi

if [ ! -z "$MQTT_FILE_PERSISTANCE" ]; then
PROPERTIES="${PROPERTIES}:filePersistance=${MQTT_FILE_PERSISTANCE}"
fi

if [ ! -z "$MQTT_PERSISTENCE_DIRECTORY" ]; then
PROPERTIES="${PROPERTIES}:persistenceDirectory=${MQTT_PERSISTENCE_DIRECTORY}"
fi

if [ ! -z "$MQTT_QOS" ]; then
PROPERTIES="${PROPERTIES}:qos=${MQTT_QOS}"
fi

if [ ! -z "$MQTT_TOPIC_FILTER" ]; then
PROPERTIES="${PROPERTIES}:topicFilter=${MQTT_TOPIC_FILTER}"
fi

# Deploy MQTT RAR
echo "Deploying MQTT RAR"
if [ -f "$MQTT_RAR_PATH" ]; then
# Check if already deployed and undeploy if needed
$ASADMIN_CMD list-applications | grep -q ${MQTT_CONNECTOR_RAR_DEPLOYMENT_NAME} && {
echo "Undeploying existing MQTT RAR"
# Check if resource exists and delete it
$ASADMIN_CMD list-connector-resources | grep -q ${MQTT_RESOURCE_NAME} && {
echo "Deleting existing MQTT resource"
$ASADMIN_CMD delete-connector-resource ${MQTT_RESOURCE_NAME} || exit 1
}

# Check if connection pool exists and delete it
$ASADMIN_CMD list-connector-connection-pools | grep -q ${MQTT_POOL_NAME} && {
echo "Deleting existing MQTT connection pool"
$ASADMIN_CMD delete-connector-connection-pool ${MQTT_POOL_NAME} || exit 1
}

echo "Undeploying existing MQTT RAR"
$ASADMIN_CMD undeploy ${MQTT_CONNECTOR_RAR_DEPLOYMENT_NAME} || exit 1
}
$ASADMIN_CMD deploy --name ${MQTT_CONNECTOR_RAR_DEPLOYMENT_NAME} $MQTT_RAR_PATH || exit 1
else
echo "Warning: MQTT RAR file not found at $MQTT_RAR_PATH"
exit 1
fi

# Create MQTT connection pool
echo "Creating MQTT connection pool ${MQTT_POOL_NAME}"
$ASADMIN_CMD create-connector-connection-pool \
--raname ${MQTT_CONNECTOR_RAR_DEPLOYMENT_NAME} \
--connectiondefinition fish.payara.cloud.connectors.mqtt.api.MQTTConnectionFactory \
--property "${PROPERTIES}" \
${MQTT_POOL_NAME} || exit 1
# Create MQTT resource
echo "Creating MQTT resource ${MQTT_RESOURCE_NAME}"
$ASADMIN_CMD create-connector-resource \
--poolname ${MQTT_POOL_NAME} \
${MQTT_RESOURCE_NAME} || exit 1

# The connector logs allocation failures with a full stack trace before returning null.
$ASADMIN_CMD set-log-levels fish.payara.cloud.connectors.mqtt.api.outbound.MQTTConnectionFactoryImpl=OFF || exit 1

# Test MQTT connection pool
echo "Testing MQTT connection pool"
$ASADMIN_CMD ping-connection-pool ${MQTT_POOL_NAME} || { echo "Warning: MQTT connection pool ping failed"; exit 1; }

echo "Restart or redeploy CDB."
Loading
Loading