Skip to content

python/iqm: allow connecting via TCP, TLS, websockets#476

Merged
ymorin-orange merged 9 commits intoOrange-OpenSource:masterfrom
ymorin-orange:nyma/gh-475
Dec 10, 2025
Merged

python/iqm: allow connecting via TCP, TLS, websockets#476
ymorin-orange merged 9 commits intoOrange-OpenSource:masterfrom
ymorin-orange:nyma/gh-475

Conversation

@ymorin-orange
Copy link
Copy Markdown
Member

@ymorin-orange ymorin-orange commented Nov 25, 2025

Changes

  • applications:
    • interqueuemanager:
      • restore connection throuch TCP
      • add support for TLS connections
      • add support for websockets connections

Close #475

Test

How to test

Note: in the following:

  • lines starting with $ are to be executed on your machine, as a non-root user;
  • lines starting with (docker)$ are to be executed in the Docker container;
  • lines starting with (docker)🐍 $ are to be executed in the Docker container, in the python venv.
  1. Prepare a test environment:
    1. be sure to have unrestricted access to test.mosquitto.org (IPv4 and IPv6)
    2. run an MQTT client that listens on test.mosquitto.org:
      $ mosquitto_sub \
          -h test.mosquitto.org -p 8886 \
          --tls-version tlsv1.3 --capath /etc/ssl/certs/ \
          -i SUyX8BNsbCr633okVYVwVPIX \
          -t 'default/+/v2x/#' \
          -V 5 \
          -F %J
    3. in another terminal, start a container with Python 3.11 and the necessary packages:
      $ docker container run \
          --detach \
          --name iot3 \
          --rm \
          -ti \
          --network host \
          -e http_proxy \
          -e https_proxy \
          -e no_proxy \
          --user $(id -u):$(id -u) \
          --mount type=bind,source=$(pwd),destination=$(pwd) \
          --workdir $(pwd) \
          python:3.11.14-slim-trixie \
          /bin/bash -il
      
      $ docker container exec -u 0:0 iot3 apt update
      $ docker container exec -u 0:0 iot3 apt install -y git build-essential socat
      $ docker container exec -d iot3 socat UNIX-LISTEN:/tmp/mqtt.socket,fork TCP4:test.mosquitto.org:1884
      
      $ docker container attach iot3
      Note: the socat command exposes the MQTT broker from test.mosquitto.org, inside the container, listening on the UNIX socket /tmp/mqtt.socket.
    4. prepare a Python 3.11 environment, with tests dependencies
      and packages' dependencies:
      (docker)$ python3.11 -m venv /tmp/venv
      (docker)$ . /tmp/venv/bin/activate
      (docker)🐍 $ pip --disable-pip-version-check --no-cache-dir install \
                      -r python/requirements-tests.txt \
                      $(sed -r -e '/.*"(.+(==|>=|<=).+)".*/!d; s//\1/; s/ //g;' \
                        python/*/pyproject.toml
                       )
      Note: we install the packages dependencies manually, and do not rely on pip to do so, because our Python packages depend one on the others by git hash, as they are not published on PyPi yet, so installing one of our packages may overwrite another.
  2. create the IQM configuration files:
    • /tmp/iqm-unix.cfg
      (docker)🐍 $ cat >/tmp/iqm-unix.cfg <<_EOF_
      [general]
      instance-id = geo_4afad84c
      prefix = default
      suffix = v2x
      [local]
      socket-path = /tmp/mqtt.socket
      username = rw
      password = readwrite
      _EOF_
      
    • /tmp/iqm-tcp.cfg
      (docker)🐍 $ cat >/tmp/iqm-tcp.cfg <<_EOF_
      [general]
      instance-id = geo_4afad84c
      prefix = default
      suffix = v2x
      [local]
      host = test.mosquitto.org
      port = 1884
      tls = false
      username = rw
      password = readwrite
      _EOF_
      
    • /tmp/iqm-tls.cfg
      (docker)🐍 $ cat >/tmp/iqm-tls.cfg <<_EOF_
      [general]
      instance-id = geo_4afad84c
      prefix = default
      suffix = v2x
      [local]
      host = test.mosquitto.org
      port = 8886
      _EOF_
      
    • /tmp/iqm-wss.cfg
      (docker)🐍 $ cat >/tmp/iqm-wss.cfg <<_EOF_
      [general]
      instance-id = geo_4afad84c
      prefix = default
      suffix = v2x
      [local]
      host = test.mosquitto.org
      port = 8081
      websocket_path = /
      _EOF_
      
  3. Build the Python packages:
    (docker)🐍 $ for pkg in python/*/; do
                    python -m build -w "${pkg}" || break
                 done
  4. Install the Python packages:
    (docker)🐍 $ pip --disable-pip-version-check --no-cache-dir \
                        install --no-deps python/*/dist/*.whl
  5. Test the IQM on various connection protocols::
    1. run the IQM with one of the configuration files above, e.g. with /tmp/iqm-unix.cfg:
      (docker)🐍 $ its-iqm -c /tmp/iqm-unix.cfg
    2. send an MQTT message:
      $ mosquitto_pub \
          -h test.mosquitto.org -p 8886 \
          --tls-version tlsv1.3 --capath /etc/ssl/certs/ \
          -i H15/VGZbiFtxzPVrCrolUXbL \
          -t 'default/inQueue/v2x/cam/0/1/2/3/3/2/1/0' \
          -V 5 \
          -m '["test-me"]'
    3. stop the IQM (with Ctrl-C) and start again at step 2, above, using another configuration file

Expected results

  1. The test environment is ready
  2. The configuration files were all created successfully
  3. The packages were all built successfully
  4. The packages were all installed successfully
  5. The IQM relays messages as expected, whatever the connection means: messages posted on inQueue are copied to outQueue and interQueue

@ymorin-orange ymorin-orange added this to the Sprint 16 milestone Nov 25, 2025
@ymorin-orange ymorin-orange self-assigned this Nov 25, 2025
@ymorin-orange ymorin-orange added the Python Python code label Nov 25, 2025
@ymorin-orange ymorin-orange marked this pull request as ready for review November 27, 2025 06:23
…ker"

The rationale behind 9b2c91c (python/iqm: use only UNIX socket to
connect to local MQTT broker) has proven to become wrong since then: now
that we can spawn multiple IQMs to share the load, it will start to make
sense to have the IQMs running on different machines, and those may no
longer be co-located on the same machine as the broker.

Re-instate the possibility to connect to the local broker via TCP; still
keep the UNIX socket for simpler setups, or for machines beefy enough to
host multiple IQMs.

This reverts commit 9b2c91c.

Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
Either host or socket-path is mandatory, so they should not have a
default value (not even None).

The port is made optional: the default MQTT port, 1883, is used as a
default port.

Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
Iterating over the object yields all sections, even the "DEFAULT"
section, which we ignore; we can however request the list of sections,
which does not include the "DEFAULT" section, which is a bit simpler.

Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
configparser.ConfigParser() only knows about strings, and does not
handle anything else, especialy not None of bool. However, we do
use None in a few places, so we convert the ConfigParser() to a dict
before we use it everywhere.

This means that we no longer have access to the ConfigParser.getbool().

Add a helper that allows easily converting a string-with-a-boolean into
an actual boolean.

Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
If the tls key is not provided, we end up with None, which makes for
automatic TLS setup, which is exactly what we want.

But if the tls key *is* provided, it is a string, not a boolean, as it
comes from a configparser.ConfigParser(), which only handles strings;
when converted to a dict(), there is no type conversion, so we still get
a string.

A non-empty string always tests True, whatever its content. So the
string "False" tests as True, so we end up always using TLS, even when
explicitly instructed not to.

Fix that by using the newly introduced helper, that converts a
boolean-in-a-string into a bool().

Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
Signed-off-by: Yann E. MORIN <yann.morin@orange.com>
@ymorin-orange ymorin-orange merged commit 1e14f9c into Orange-OpenSource:master Dec 10, 2025
113 checks passed
@ymorin-orange ymorin-orange deleted the nyma/gh-475 branch March 10, 2026 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Python Python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

python: restore use of TCP/IP for IQM

2 participants