Contents ======== * `Contents <#contents>`__ * `ZeroMQ Broker Overview <#zeromq-broker-overview>`__ * `Security <#security>`__ * `IPC Mode <#ipc-mode>`__ * `TCP Mode <#tcp-mode>`__ * `Performance Implications <#performance-implications>`__ * `Steps to Independently Build and Deploy the ZeroMQ Broker Service <#steps-to-independently-build-and-deploy-the-zeromq-broker-service>`__ * `Steps to Independently Build the ZeroMQ Broker Service <#steps-to-independently-build-the-zeromq-broker-service>`__ * `Steps to Independently Deploy the ZeroMQ Broker Service <#steps-to-independently-deploy-the-zeromq-broker-service>`__ * `Deploy the ZeroMQ Broker Service without the Config Manager Agent Dependency <#deploy-the-zeromq-broker-service-without-the-config-manager-agent-dependency>`__ * `Deploy the ZeroMQ Broker Service with the Config Manager Agent Dependency <#deploy-the-zeromq-broker-service-with-the-config-manager-agent-dependency>`__ * `Configuration <#configuration>`__ * `Application or Service Configuration <#application-or-service-configuration>`__ * `Interface Configuration <#interface-configuration>`__ * `Docker <#docker>`__ * `Connecting the EII Services to the ZeroMQ Broker <#connecting-the-eii-services-to-the-zeromq-broker>`__ * `Bare Metal <#bare-metal>`__ * `Compilation <#compilation>`__ * `Usage <#usage>`__ * `Running Unit Tests <#running-unit-tests>`__ ZeroMQ Broker Overview ---------------------- Using the ZeroMQ broker or broker you can proxy the data coming over the Message Bus ZeroMQ protocol plug-in for publishers and subscribers. Traditionally, each Message Bus ZeroMQ publisher has its own IPC socket or TCP (host, port) combination. The ZeroMQ broker enables subscribers to connect to a single central subscriber TCP or IPC socket to receive incoming messages from the broker, and publishers to connect to the proxy's publisher TCP or IPC socket to transmit published messages. The ZeroMQ broker builds from the functionality provided by the ZeroMQ ``zmq_proxy()`` API, which uses two separate sockets and hands messages off from one socket to the other. The following diagram shows a high-level flow of how the ZeroMQ Broker functions. .. code-block:: +-----------+ +-----------+ +-----------+ | Publisher | | Publisher | | Publisher | +-----------+ +-----------+ +-----------+ | ZMQ_PUB | | ZMQ_PUB | | ZMQ_PUB | +-----------+ +-----------+ +-----------+ connect connect connect | | | +----------------+-----------------+ | bind +----------------+ | ZMQ_XSUB | +----------------+ | proxy | +----------------+ | ZMQ_XPUB | +----------------+ bind | +---------------+-------------------+ | | | connect connect connect +------------+ +------------+ +------------+ | ZMQ_SUB | | ZMQ_SUB | | ZMQ_SUB | +------------+ +------------+ +------------+ | Subscriber | | Subscriber | | Subscriber | +------------+ +------------+ +------------+ As shown in the diagram, the broker uses two ZeroMQ sockets: #. A socket for publishers to connect that is the ``ZMQ_XSUB`` socket that is referred to as the **frontend** socket. #. A socket for the subscribers to connect to that is the ``ZMQ_XPUB`` socket that is referred to as the **backend** socket. The broker binds to the TCP (host, port) or the IPC socket file (based on its configuration) for each of its sockets. Messages are sent from publishers to the **frontend** socket and then relayed to the **backend** socket that forwards the messages to the subscribers. Security ^^^^^^^^ The security for the broker depends on whether the broker is using TCP or IPC for its respective sockets. .. note:: The broker can be used with the **frontend** being a TCP socket and the **backend** being an IPC socket and vice versa. The following sections cover the security for the TCP and the IPC modes. IPC Mode ~~~~~~~~ When the broker is using an IPC socket for either the **frontend** or **backend** sockets, the ability to send or receive messages is handled by the Linux file permissions. The messages sent over the IPC sockets are not encrypted. TCP Mode ~~~~~~~~ For TCP connections, ZeroMQ broker offers mechanisms for both encryption and authentication. This is accomplished via elliptical curve keys generated when EII is provisioned. These keys provide the encryption and authentication via the ZAP protocol and a list of allowed clients authentication is handled. The EII Message Bus handles all the encryption and authentication for publishers and subscribers when they connect to the broker. The necessary keys for message decryption and deciding whether a specific publisher or subscriber is permitted to connect are held by the broker via setup of the broker's messaging interfaces. See the configuration section for more details on listing out allowed clients and configuring the security for the ZeroMQ broker. .. **Important Security Implication**\ : For TCP connections, the broker manages a single list of all the publishers and subscribers that are allowed to connect. If a given subscriber can connect, then all the data coming through that broker instance is available to that subscriber to receive. Essentially what this means, is that the broker does not do authentication on a per topic/stream basis, only on a connection basis. Performance Implications ^^^^^^^^^^^^^^^^^^^^^^^^ When using the ZeroMQ broker, it is important to understand the implications on the performance of the networking in the EII platform. By using the broker, an extra network hop is incurred for all messages sent over the Message Bus ZeroMQ protocol plugin. This will increase the latency for the messages sent from the publishers connecting to the broker to the subscribers connecting to the broker. .. **Important Note:** Having the broker running in an EII deployment does not make every message from publishers go through the broker. Each publisher must be configured to connect to the broker. Publishers that are not configured to connect to the broker will still bind to their respective IPC socket or TCP (host, port) combination. Steps to Independently Build and Deploy the ZeroMQ Broker Service ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. note:: For running 2 or more microservices, we recommend that you try the use case-driven approach for building and deploying. For more information, refer to the `Readme `_. Steps to Independently Build the ZeroMQ Broker Service ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. note:: When switching between independent deployment of the service with and without the dependency for the config manager agent service, you can run into issues with ``docker-compose build`` for the Certificates folder existence. As a workaround, run the ``sudo rm -rf Certificates`` command to proceed with ``docker-compose build``. To build the ZeroMQ broker service independently, complete the following steps: #. The downloaded source code should have a directory named ZmqBroker: .. code-block:: sh cd IEdgeInsights/ZmqBroker #. Copy the IEdgeInsights/build/.env file using the following command in the current folder .. code-block:: sh cp ../build/.env . .. **Note**\ : Update the ``HOST_IP`` and ``ETCD_HOST`` variables in the ``.env`` file with your system IP. .. code-block:: sh # Source the .env using the following command: set -a && source .env && set +a #. Independently build .. code-block:: sh docker-compose build Steps to Independently Deploy the ZeroMQ Broker Service ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can deploy the ZeroMQ broker service in any of the following ways: * Without Config Manager Agent Dependency * With the Config Manager Agent Dependency Deploy the ZeroMQ Broker Service without the Config Manager Agent Dependency """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Run the following commands to deploy the ZeroMQ Broker service without the Config Manager Agent dependency: .. code-block:: sh # Enter the ZmqBroker directory cd IEdgeInsights/ZmqBroker .. Copy the IEdgeInsights/build/.env file using the following command in the current folder, if not already present. .. code-block:: sh cp ../build/.env . **Note:** Ensure that ``docker ps`` is clean and ``docker network ls`` doesn't have EII bridge network. .. code-block:: Update .env file for following: 1. HOST_IP and ETCD_HOST variables with your system IP. 2. `READ_CONFIG_FROM_FILE_ENV` value to `true` and `DEV_MODE` value to `true`. Source the .env using the following command: set -a && source .env && set +a .. code-block:: sh # Run the service docker-compose -f docker-compose.yml -f docker-compose-dev.override.yml up -d .. note:: The ZmqBroker container restarts automatically when its config is modified in the ``config.json`` file. To update the ``config.json`` file using the ``vi`` or the ``vim`` editor, append the ``set backupcopy=yes`` in ``~/.vimrc``. This allows the changes made on the host machine ``config.json`` file to reflect in the container mount point. Deploy the ZeroMQ Broker Service with the Config Manager Agent Dependency """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Complete the following steps to deploy the ZeroMQ broker service with the Config Manager Agent dependency. .. note:: Ensure that the Config Manager Agent image present in the system. If not, build the Config Manager Agent locally when independently deploying the service with Config Manager Agent dependency. .. code-block:: sh # Enter the ZmqBroker directory cd IEdgeInsights/ZmqBroker .. Copy the IEdgeInsights/build/.env file using the following command in the current folder, if not already present. .. code-block:: sh cp ../build/.env . **Note:** Ensure that ``docker ps`` is clean and ``docker network ls`` does not have EII bridge network. .. code-block:: Update .env file for following: 1. HOST_IP and ETCD_HOST variables with your system IP. 2. `READ_CONFIG_FROM_FILE_ENV` value is set to `false`. .. Copy the docker-compose.yml from IEdgeInsights/ConfigMgrAgent as docker-compose.override.yml in IEdgeInsights/ZmqBroker. .. code-block:: sh cp ../ConfigMgrAgent/docker-compose.yml docker-compose.override.yml .. Copy the builder.py with standalone mode changes from IEdgeInsights/build directory .. code-block:: sh cp ../build/builder.py . Run the following command to run the builder.py in the standalone mode. This will generate the ``eii_config.json`` file and update the ``docker-compose.override.yml`` file. .. code-block:: sh python3 builder.py -s true .. Building the service (This step is optional for building the service if not already done in the ``Independently buildable`` step above) .. code-block:: sh docker-compose build For running the service in PROD mode, run the below command: **NOTE**\ : Make sure to update ``DEV_MODE`` to ``false`` in .env while running in PROD mode and source the .env using the command ``set -a && source .env && set +a``. .. code-block:: sh docker-compose up -d For running the service in DEV mode, run the below command: **NOTE**\ : Make sure to update ``DEV_MODE`` to ``true`` in .env while running in DEV mode and source the .env using the command ``set -a && source .env && set +a``. .. code-block:: sh docker-compose -f docker-compose.yml -f docker-compose-dev.override.yml -f docker-compose.override.yml up -d Configuration ^^^^^^^^^^^^^ .. note:: The JSON schema for the configuration properties of the ZeroMQ Broker can be found in the ``schema.json`` file. The configuration of the ZeroMQ Broker is predominantly accomplished from the EII Configuration Manager APIs. However, it can also be configured via JSON files, as described in the `Usage <#usage>`__ section. The configuration via JSON files are only for development or debugging purposes. This section will focus on the production configuration of the broker. The configuration of the broker falls into two main areas: #. **Application/Service Configuration** - Configuration of the runtime behavior. #. **Interface Configuration** - Configuration of the networking interfaces that is the frontend and the backend sockets. Aside from the interface and the service configuration, there are two properties that are set via environmental variables: ``AppName`` and ``DEV_MODE``. The ``AppName`` variable determines how the service queries its configuration using the Configuration Manager APIs. For docker-compose, this is set in the ``environment`` section of the ``docker-compose.yml`` file under the ``ia_zmq_broker`` section. The default value for this is ``ZmqBroker``. The ``DEV_MODE`` variable sets whether the broker will attempt to use certificates with the Configuration Manager APIs and over any TCP connections. This is also obtained from the ``environment`` section of the ``docker-compose.yml`` file. .. **Important Note**\ : There are some other configuration properties in the ``environment`` section of the ``docker-compose.yml`` file. These are provided to the service from the ``build/.env`` file. For more information, refee to the EII User Guide. The following sections cover the various configuration properties that the broker supports for interfaces and application configuration. Application or Service Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The broker supports two configuration parameters; one for the Linux scheduler policy and the other for the scheduler priority. These two properties are applied to the main thread which is running the ZeroMQ proxy. The configuration values must be specified in the config.json before running the ``builder.py`` script or eii_config.json after using the ``builder.py`` script. The following table specifies the details for these parameters. Note that neither of these are required in the configuration and should only be set if the user knows they need to have a certain scheduling policy and priority for the broker. .. list-table:: :header-rows: 1 * - Key - Type - Description * - ``sched_policy`` - ``string`` - Scheduling policy to set for the main thread. Must be: ``SCHED_OTHER``\ , ``SCHED_IDLE``\ , ``SCHED_BATCH``\ , ``SCHED_FIFO``\ , or ``SCHED_RR``. * - ``sched_priority`` - ``integer`` - Sets the priority for the thread. Must be between ``0`` and ``99``. Only valid for ``SCHED_FIFO`` and ``SCHED_RR`` policies. An example of applying these two settings to the ZeroMQ Broker's configuration is shown as follows. In this example, the configuration is an excerpt from the, ``IEdgeInsights/build/provision/config/eii_config.json``\ , generated while using the ``builder.py`` script. .. code-block:: javascript { // ... omitted ... "/ZmqBroker/config": { "sched_policy": "SCHED_FIFO", "sched_priority": 42 } // ... omitted ... } .. note:: There will also be an ``/ZmqBroker/interfaces`` section associated with the broker, but that is covered in the next section. The configuration shown in the example sets the Linux scheduler policy to ``SCHED_FIFO`` and its priority to ``42``. This can also be left entirely empty, and the broker thread will default to the Linux default thread scheduling policy or priority. Interface Configuration ~~~~~~~~~~~~~~~~~~~~~~~ The configuration of the networking interfaces for the ZeroMQ Broker is divided into two sections * Subscribers - This section subscribes to the messages coming from publishers and sets the configuration for the **frontend**. * Publishers - section determines the configuration for the **backend** socket. The Configuration Manager API assumes that the ``Subscribers`` and the ``Publishers`` section is a list. However, since the ZeroMQ broker does not use multiple publisher and subscriber sockets, the lists must only contain one element. The single JSON object that is expected to be in the ``Subscribers`` and the ``Publishers`` sections is essentially the same. The following example shows the interfaces configuration for a broker instance with TCP sockets for both the **frontend** and **backend**. .. code-block:: javascript { "Subscribers": [ { "Name": "frontend", "Type": "zmq_tcp", "EndPoint": "0.0.0.0:60514", "Topics": ["*"], "PublisherAppName": "*", "AllowedClients": ["*"] } ], "Publishers": [ { "Name": "backend", "Type": "zmq_tcp", "EndPoint": "0.0.0.0:60515", "Topics": ["*"], "AllowedClients": ["*"] } ] } The ``Name`` and ``Topics`` fields differ, which is the main difference to note. The string ``frontend`` must be used as the value for the ``Name`` key in the ``Subscribers`` section. There can be just one value of ``*`` in the ``Topics`` list. The same guidelines apply to the object called ``Publishers``. Notably, the word ``*`` appears in the phrase ``AllowedClients``.You can modify this to a list of the app names of the services that are permitted to connect if you only want to allow specific services to connect to the broker. As a result, the broker can use the defined names ``frontend`` and ``backend`` to query specific configuration items. The ``AllowedClients`` list should be changed to only include the app names of the services that are authorized to connect if the deployment needs to restrict the services that can connect to the broker. For IPC sockets, the configuration is very similar, except that the ``EndPoint`` and the ``Type`` values are different, as shown in the following example: .. code-block:: javascript { "Subscribers": [ { "Name": "frontend", "Type": "zmq_ipc", "EndPoint": { "SocketDir": "/tmp/socks", "SocketFile": "frontend-socket" }, "PublisherAppName": "*", "Topics": ["*"], "AllowedClients": ["*"] } ], "Publishers": [ { "Name": "backend", "Type": "zmq_ipc", "EndPoint": { "SocketDir": "/tmp/socks", "SocketFile": "backend-socket" }, "Topics": ["*"], "AllowedClients": ["*"] } ] } In this example, note that the ``Type`` value is ``zmq_ipc`` and the ``EndPoint`` is a JSON object that defines the socket directory and file to use for the sockets. .. **Important Notes** There are two important notes to be aware of with the configurations presented earlier: * Although the configurations above showcase using IPC and TCP for both the frontend and backend sockets, they can be used in any combination. For example, the broker can use an IPC socket for the frontend and TCP for the backend. * When using IPC sockets, the name of the ``SocketFile`` must also be specified for all subscribers or publishers that will be connecting to that socket. Docker ^^^^^^ The ZeroMQ broker is integrated into the EII docker-compose ecosystem. To build and use the Docker container, follow the defined building or provisioning instructions for EII . If you are using a YAML file with the ``builder.py`` script, then ensure to add ``ZmqBroker`` under the ``AppName`` section of the YAML file. This will include the broker into the resulting ``docker-compose.yml`` file and also include the broker's configuration in the ``eii_config.json`` which is used while provisioning. Connecting the EII Services to the ZeroMQ Broker ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To connect the EII services, such as the EdgeVideoAnalyticsMicroservice or Visualizer services, you must edit the interfaces configuration of the services to tell them the broker instance to connect to. Namely, you need to add two keys to the ``Publishers`` configuration to have two additional keys: #. ``BrokerAppName`` - This specifies the AppName of the targeted broker instance. #. ``brokered`` - This tells the Message Bus that the given publisher instance is brokered. As an example, following is the changes in the interfaces configuration for enabling the ``EdgeVideoAnalyticsMicroservice`` and ``Visualizer`` to communicate via ZmqBroker. .. note:: \ : Though the example shows EdgeVideoAnalyticsMicroservice and Visualizer using the ZmqBroker, it is not recommended for video streaming use cases due to the extra hop added to the video frames that will affect performance. Changes to EdgeVideoAnalyticsMicroservice/eii/config.json which is a publisher. The following adds the ``BrokerAppName`` and the ``brokered`` keys to the default publisher's configuration. .. code-block:: javascript "interfaces": { "Publishers": [ { "Name": "default", "Topics": [ "edge_video_analytics_results" ], "Type": "zmq_tcp", "EndPoint": "ia_zmq_broker:60514", "brokered": true "BrokerAppName": "ZmqBroker", "AllowedClients": [ "*", ], } ] } For the subscriber that is Multimodal Data Visualization Streaming and Multimodal Data Visualization, there won't be much changed other than changing the endpoint to point to ZmqBroker along with PublisherAppName. .. code-block:: javascript "interfaces": { "Subscribers": [ { "Name": "default", "Type": "zmq_tcp", "EndPoint": "ia_zmq_broker:60515", "PublisherAppName": "ZmqBroker", "Topics": [ "edge_video_analytics_results" ], "zmq_recv_hwm": 50 } ] } Bare Metal ^^^^^^^^^^ .. **Important Note**\ : Running the broker using bare-metal is not recommended for production environments. This way of running the broker is meant purely for development and debugging purposes. Compilation ~~~~~~~~~~~ The ZeroMQ Broker is written in C++ and as such utilizes the CMake build system for building the binary for the broker. The ZeroMQ Broker has the following dependencies: * CMake 3.15+ * IntelSafeString * EII Utils * libzmq * EII ConfigMgr * MessageBus (only required for unit tests) Before building the ZeroMQ Broker, you must install these libraries on the target system. This can be done using the ``common/eii_libs_installer.sh`` script. After the dependencies for the broker are installed on your system, complete the following steps to build the ZeroMQ Broker. #. To create the build directory, run the following command: .. code-block:: sh mkdir build/ #. Change directories into the newly created ``build/`` directory .. code-block:: sh cd build/ #. Run the CMake command to set up the build environment (see subsections). a. To compile without the unit tests run the following command: .. code-block:: sh cmake .. b. To compile the unit tests, run the following command. Note that it is recommended to build in the Debug mode. .. code-block:: sh cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_TESTS=ON .. #. To build the ZeroMQ broker binary, run the following command: .. code-block:: sh make Usage ~~~~~ After building the ZeroMQ broker you will have a binary named, "zmq-broker". Use this binary to run the ZeroMQ broker. The ZeroMQ broker can be configured from the EII Configuration Manager as well as from environmental variables and JSON configuration files. To use the configuration obtained via the EII Configuration Manager, simply start the binary with no parameters; however, ensure to set the ``AppName`` and the ``DEV_MODE`` environmental variables. As mentioned at the beginning of the `Bare Metal <#bare-metal>`__ section, this way of running the broker should only be done in development environments. As such, it is assumed that the ``DEV_MODE`` environmental variable will be set to ``true`` and no security is used with the Configuration Manager or over Message Bus ZeroMQ TCP connections. Additionally, for running in this way, the ``ia_etcd`` container must be running. .. code-block:: sh # Set DEV_MODE environmental variable to "true" export DEV_MODE=true # Set the AppName environmental variable to "ZmqBroker" export AppName=ZmqBroker # Run the broker ./zmq-broker The broker also supports receiving its configuration through JSON configuration files and environmental variables. To set the log level, Linux scheduler policy and priority set the following environmental variables. Refer to the details in the [Configuration] (#configuration) section. .. note:: \ : None of the following environmental variables are required to run the broker. * ``C_LOG_LEVEL`` - Log level (will default to ``ERROR`` log level) * ``SCHED_POLCIY`` - Scheduler policy * ``SCHED_PRIORITY`` - Scheduler priority When using JSON files, the broker will expect two positional command line arguments. The first will be the configuration of the **frontend** socket and the second will be for the **backend** configuration. .. **REMINDER:** The **frontend** refers to the configuration for socket which publishers shall connect to, and the **backend** refers to the configuration for the socket which subscribers shall connect to. The contents of the JSON is analogous to the JSON configuration files used in the Message Bus (see the IEdgeInsights/common/libs/EIIMessageBus/README.md for more information). The contents of the JSON files depends on whether if the given socket is supposed to use TCP or IPC. For **IPC** configurations, the frontend and the backend configurations need to look respectively as follows: **Frontend:** .. code-block:: javascript { // Which ZeroMQ protocol to use (TCP vs. IPC) "type": "zmq_ipc", // Socket directory to create the socket file in "socket_dir": "/tmp", // Specifies the IPC endpoint config (i.e. socket directory and file) "": { // IPC socket file to bind to for the frontend socket "socket_file": "frontend-sock" } } .. note:: \ : This example configuration is stored in ``examples/ipc_frontend_example.json`` file and can be used with the ``examples/configs/ipc_publisher_brokered.json`` Message Bus configuration file. The following table desribes the purpose of each key in the JSON configuration file. .. list-table:: :header-rows: 1 * - Key - Description * - ``type`` - Specifies the ZeroMQ protocol to use, must be either ``zmq_ipc`` or ``zmq_tcp``. * - ``socket_dir`` - Specifies the directory in which to create all of the IPC socket files. * - ``""`` - Gives the IPC socket file configuration for the frontend IPC socket. * - ``socket_file`` - This key specifies the name of the socket file to bind to. For the ``socket_file`` key, when connecting a publisher, the publisher's configuration must also use this same ``socket_file`` key in the configuration for it. Otherwise, it will fail to connect because it will attempt to bind/connect to its topic name (see the Message Bus's documentation for more details). **Backend:** .. code-block:: javascript { // Which ZeroMQ protocol to use (TCP vs. IPC) "type": "zmq_ipc", // Socket directory to create the socket file in "socket_dir": "/tmp", // Specifies the IPC endpoint config (i.e. socket directory and file) "": { // IPC socket file to bind to for the backend socket "socket_file": "backend-sock" } } .. note:: \ : This example configuration is stored in the ``examples/ipc_backend_example.json`` file and can be used with the ``examples/configs/ipc_subscriber_brokered.json`` Message Bus configuration file. The configuration for the backend socket is the same as for the frontend. For **TCP** configurations, the frontend and the backend configurations need to look respectively as follows: **Frontend:** .. code-block:: javascript { // Which ZeroMQ protocol to use (TCP vs. IPC) "type": "zmq_tcp", // List of curve public keys for publishers allowed to connect to the // frontend socket "allowed_clients": ["4J4?(I13cwJgqi+T5nxg:Dyr5)l&reK]cxxTfa9V"], // Specifies the configuration for the frontend socket "": { // TCP host "host": "0.0.0.0", // TCP port "port": 5568, // Server secret key to use for encryption / authentication "server_secret_key": "H[J1%f:#?0Y1cpULj]*!u3N#9" } } .. note:: This example configuration is stored in the ``examples/tcp_frontend_example.json`` file and can be used with the ``examples/configs/tcp_publisher_brokered_with_security.json`` Message Bus configuration file. The following table describes the purpose of each key in the JSON configuration file. .. list-table:: :header-rows: 1 * - Key - Description * - ``type`` - Specifies the ZeroMQ protocol to use, must be either ``zmq_ipc`` or ``zmq_tcp``. * - ``host`` - TCP host. * - ``port`` - TCP port. * - ``allowed_clients`` - Specifies the list of public keys for the publishers that are allowed to connect. * - ``""`` - Gives security configuration for the frontend TCP socket. * - ``server_secret_key`` - Secret key for the frontend socket for encryption / authentication. .. **Important Note**\ : When using JSON files for the configuration of the ZeroMQ Broker, the JSON file is the configuration used by the Message Bus, rather than the normal EII interface configurations. This is why the JSON configuration differs from the configuration given via the ``eii_config.json``. The JSON shown earlier for the frontend, and the following backend configuration, represent how the configuration manager alters that configuration to be in these forms. **Backend:** .. code-block:: javascript { // Which ZeroMQ protocol to use (TCP vs. IPC) "type": "zmq_tcp", // List of curve public keys for subscribers allowed to connect to the // backend socket "allowed_clients": ["y-G]27SC}{!mC4(]}=c=KH1M{x)Kd/{i%o]j7YT3"], // Specifies the configuration for the frontend socket "zmq_tcp_publish": { // TCP host "host": "0.0.0.0", // TCP port (note that this is a different port from the frontend) "port": 5569 // Server secret key to use for encryption / authentication "server_secret_key": "qydUsM#PP4r