Server-to-Server Messaging
Server-to-server messaging is configured through the Network Connection Manager.
A server connection defines one or more remote endpoints and one or more links between the remote namespace and the local namespace. Each link can pull or push messages, apply selectors, transform payloads, include schema information, apply namespace filters, request a quality of service, and collect statistics.
The YAML configuration uses NetworkConnectionManager.data, where data is a list of connection definitions.
Configuration Model
NetworkConnectionManager:
data:
- name: "remote-maps-node"
url: tcp://node1.example.com:1883/
protocol: mqtt
groupName: "Main data uplink"
cost: 10
pluginConnection: false
linkTransformation: "Schema-To-Json"
remote:
username: "bridge-user"
password: "change-me"
sessionId: null
tokenGenerator: "JWT"
tokenConfig:
expiry: 3600
links:
- direction: pull
remote_namespace: "/+/1/1/GPS_RAW_INT"
local_namespace: "/"
selector: "fixType >= 3"
include_schema: true
qos: 1
transformer:
- type: "jsonquery"
query: "[\"object\",{\"latitude\":[\"divide\",[\"get\",\"payload\",\"decoded\",\"lat\"],10000000]}]"
statistics:
statisticName: "Advanced"
eventCount: 100
ignoreList:
- "modelName"
- "serialNumber"
keyList:
- "temperature"
- "humidity"
namespaceFilters:
- namespace: "/vehicle/+/telemetry"
depth: 3
selector: "state = ACTIVE"
forcePriority: false
linkProperties:
url: "pulsar://localhost:6650"
tenant: "public"
namespace: "default"
Network Connection Manager
The top-level configuration contains a list of connection definitions under data.
NetworkConnectionManager:
data:
- name: "connection-name"
url: tcp://host:1883/
protocol: mqtt
links: []
| Field | Description |
|---|---|
data | List of server connection definitions. Each entry describes a remote endpoint and the links attached to it. |
Endpoint Connection
Each entry in NetworkConnectionManager.data describes one connection to a remote endpoint.
| Field | Required | Description |
|---|---|---|
name | Yes | Friendly name for the connection. |
url | Yes | Transport endpoint URL. The scheme is the transport, such as tcp, ssl, tls, udp, or serial. |
protocol | Yes | Application protocol used over the transport, such as mqtt, stogi, or another supported protocol. |
remote | No | Remote authentication/session details, where supported by the protocol. |
links | No | List of namespace links attached to this connection. |
linkTransformation | No | Name of a registered ProtocolMessageTransformation, discovered using ServiceLoader. |
pluginConnection | No | Marks the connection as a third-party plugin connection. Defaults to false. |
cost | No | Arbitrary connection cost. Lower cost is preferred. Defaults to the server implementation default. |
groupName | No | Optional group name for organising related connections. |
URL Transport Versus Protocol
The url scheme defines the transport, not the application protocol.
The protocol field defines the application protocol that runs over that transport.
url: tcp://10.140.62.132:1883/
protocol: mqtt
Do not use mqtt:// unless mqtt is explicitly supported as a transport scheme by the connection layer.
Common examples:
| Use case | URL | Protocol |
|---|---|---|
| MQTT over plain TCP | tcp://host:1883/ | mqtt |
| MQTT over TLS | tls://host:8883/ | mqtt |
| MQTT over SSL | ssl://host:8883/ | mqtt |
| UDP-based protocol | udp://host:port/ | Protocol-specific |
| Serial modem connection | serial://localhost:0/ | Protocol-specific |
Connection Groups and Cost
Connections can be grouped using groupName.
When multiple connections are in the same group, cost can be used to express preference. Lower cost is preferred. Higher cost is less preferred and can be used for fallback paths.
data:
- name: "Primary Maps Server"
url: tcp://10.140.62.132:1883/
protocol: mqtt
groupName: "maps-server-group"
cost: 5
- name: "Secondary Maps Server"
url: tcp://10.140.50.12:1883/
protocol: mqtt
groupName: "maps-server-group"
cost: 10
In this example, 10.140.62.132 is preferred over 10.140.50.12.
Remote Authentication
Remote authentication is optional and is configured using remote.
remote:
username: "bridge-user"
password: "change-me"
sessionId: null
Depending on the protocol, the following fields may be used:
| Field | Required | Description |
|---|---|---|
username | No | Username used for authentication. |
password | No | Password used for authentication. |
sessionId | No | Existing authentication session ID, where supported. |
tokenGenerator | No | Token generator type, for example JWT. |
tokenConfig | No | Generator-specific token configuration. |
If authentication is not required, omit remote.
Links
A link defines how messages move between the remote namespace and the local namespace.
links:
- direction: pull
remote_namespace: "/+/1/1/GPS_RAW_INT"
local_namespace: "/"
selector: "fixType >= 3"
include_schema: true
qos: 1
| Field | Required | Description |
|---|---|---|
direction | Yes | Direction of the link. Valid values are pull and push. |
remote_namespace | Yes | Remote namespace or topic filter. MQTT-style + and # wildcards may be used where supported. |
local_namespace | Yes | Local destination namespace or topic. |
selector | No | JMS selector expression. If omitted, all messages match. |
include_schema | No | Includes schema information when forwarding messages, where supported. Defaults to false. |
transformer | No | Transformation chain applied to messages flowing through the link. |
statistics | No | Statistical analysis configuration for data flowing through the link. |
namespaceFilters | No | Additional namespace-specific filtering rules. |
qos | No | Requested QoS for the link. |
linkProperties | No | Untyped link-specific settings for protocol or handler behaviour. |
Link Direction
pull means the local server subscribes to or reads from the remote namespace and writes matching messages into the local namespace.
links:
- direction: pull
remote_namespace: "/remote/sensors/#"
local_namespace: "/local/sensors/"
include_schema: true
push means the local server reads from the local namespace and forwards matching messages to the remote namespace.
links:
- direction: push
local_namespace: "/sensors/#"
remote_namespace: "/satellite/#"
include_schema: false
The exact transport behaviour depends on the endpoint protocol implementation.
Quality of Service
The link can request one of the following QoS values:
| Value | Meaning |
|---|---|
0 | Deliver at least once. |
1 | Deliver at most once. |
2 | Deliver exactly once where the protocol supports it. |
Example:
qos: 1
Transformations
A link can define a transformer chain. Each entry must include a type.
Supported transformation types include:
| Type | Description |
|---|---|
cloudevent-json | CloudEvent JSON transformation. |
cloudevent-native | CloudEvent native transformation. |
cloudevent-envelope | CloudEvent envelope transformation. |
jsontoxml | JSON to XML transformation. |
xmltojson | XML to JSON transformation. |
jsontovalue | Extract a value from JSON. |
jsonquery | Apply a JSON query transformation. |
geohash | Resolve or generate geohash information. |
schematojson | Convert schema-based payloads to JSON. |
jsonmutate | Mutate JSON content. |
jsonmapper | Map JSON fields using configured mapping operations. |
jsontoschema | Convert JSON payloads into schema-based payloads. |
Example:
transformer:
- type: "jsonquery"
query: "[\"object\",{\"latitude\":[\"divide\",[\"get\",\"payload\",\"decoded\",\"lat\"],10000000]}]"
Link Transformation
linkTransformation is separate from the per-link transformer chain.
linkTransformation: "Schema-To-Json"
This value must match the name of a registered ProtocolMessageTransformation discovered using ServiceLoader.
Use this for connection-level protocol message transformation. Use transformer for per-link payload transformation chains.
Statistics
Statistics can be collected for events flowing through a link.
statistics:
statisticName: "Advanced"
eventCount: 100
ignoreList:
- "modelName"
- "serialNumber"
keyList:
- "temperature"
- "humidity"
| Field | Description |
|---|---|
statisticName | Name of the statistics engine to run. |
eventCount | Number of events to process before emitting a statistics event. |
ignoreList | Keys to ignore when generating statistics. |
keyList | Explicit keys to process instead of relying on auto-discovery. |
Some older or protocol-specific examples may use names such as analytics, analystics, defaultAnalyser, or comma-separated strings. Prefer the canonical statistics shape shown above unless the specific connection implementation requires otherwise.
Namespace Filters
Namespace filters apply additional filtering rules to selected namespaces.
namespaceFilters:
- namespace: "/vehicle/+/telemetry"
depth: 3
selector: "state = ACTIVE"
forcePriority: false
| Field | Required | Description |
|---|---|---|
namespace | Yes | Namespace to which the filter applies. |
depth | Yes | Depth to which the namespace filter applies. |
selector | No | Selector expression applied to the namespace. |
forcePriority | No | Forces this filter to take priority over others. Defaults to false. |
Link Properties
linkProperties is an untyped map. It is loaded from YAML and allows protocol or handler-specific settings to be supplied on an individual link.
linkProperties:
url: "pulsar://localhost:6650"
tenant: "public"
namespace: "default"
This is useful for protocol-specific behaviour such as ROS 2, IBM MQ, Pulsar, or other plugin-specific configuration.
MQTT Last Will
MQTT Last Will and Testament behaviour is only relevant for MQTT connections.
If supported by the connection implementation, configure it using willConfig.
willConfig:
topic: "system/bridge/client1/status"
payload: "{\"status\":\"offline\"}"
payloadEncoding: "string"
qos: 1
retain: true
delayInterval: 15
messageExpiryInterval: 300
contentType: "application/json"
payloadFormatIndicator: 1
| Field | Description |
|---|---|
topic | Topic to publish the Will message to. |
payload | Payload published when the Will is triggered. |
payloadEncoding | Payload encoding. Valid values are string and base64. Defaults to string. |
qos | MQTT Will QoS. Valid values are 0, 1, and 2. Defaults to 0. |
retain | Retain flag for the Will message. Defaults to false. |
delayInterval | MQTT v5 Will Delay Interval in seconds. Defaults to 0. |
messageExpiryInterval | MQTT v5 Message Expiry Interval in seconds. Defaults to 0. |
contentType | MQTT v5 content type. |
payloadFormatIndicator | MQTT v5 Payload Format Indicator. 0 means unspecified, 1 means UTF-8. Defaults to 0. |
Example: Preferred and Fallback MQTT Servers
This example connects to two MQTT servers over plain TCP. Both connections are in the same group. The server at 10.140.62.132 has a lower cost, so it is preferred over 10.140.50.12.
NetworkConnectionManager:
data:
- name: "Maps Server 10.140.62.132"
url: tcp://10.140.62.132:1883/
protocol: mqtt
groupName: "maps-server-group"
cost: 5
pluginConnection: false
linkTransformation: ""
links:
- direction: pull
remote_namespace: "/#"
local_namespace: "/"
include_schema: true
qos: 2
- name: "Maps Server 10.140.50.12"
url: tcp://10.140.50.12:1883/
protocol: mqtt
groupName: "maps-server-group"
cost: 10
pluginConnection: false
linkTransformation: ""
links:
- direction: pull
remote_namespace: "/#"
local_namespace: "/"
include_schema: true
qos: 0
Example: Push Local Events to a Remote Server
NetworkConnectionManager:
data:
- name: "Remote Analytics Server"
url: tcp://analytics.example.com:1883/
protocol: mqtt
groupName: "Analytics uplink"
cost: 20
pluginConnection: false
linkTransformation: ""
links:
- direction: push
local_namespace: "/events/+/summary"
remote_namespace: "/analytics/inbound"
selector: "priority >= 5"
include_schema: true
qos: 1
transformer:
- type: "cloudevent-json"
linkProperties:
batchSize: 100
flushIntervalMs: 1000
Example: Serial Modem Connection
This example shows the same connection model used for a serial modem transport. The url uses the serial transport scheme and the protocol identifies the modem protocol.
NetworkConnectionManager:
data:
- name: "ST2100 Modem"
url: serial://localhost:0/
protocol: stogi
initialSetup: ""
incomingMessagePollInterval: 1
outgoingMessagePollInterval: 5
sharedSecret: "This is a shared secret to use"
sendHighPriorityMessages: false
modemResponseTimeout: 20000
locationPollInterval: 60
maxBufferSize: 4000
compressionCutoffSize: 128
modemRawResponse: "/outbound/#"
modemStatsTopic: "/modem/stats"
links:
- direction: push
local_namespace: "/sensors/#"
remote_namespace: "/satellite/#"
include_schema: false
serial:
port: ttyV1
baudRate: 9600
dataBits: 8
stopBits: 1
parity: n
flowControl: 0
Notes
The core server-to-server behaviour is defined by:
- the connection endpoint,
- the transport scheme in
url, - the application protocol in
protocol, - the link direction,
- the remote and local namespaces,
- optional selectors,
- optional transformation chains,
- optional statistics and namespace filtering,
- optional protocol-specific properties.
For MQTT over TCP, use url: tcp://host:1883/ and protocol: mqtt.
For MQTT over TLS or SSL, use a TLS/SSL transport URL and keep protocol: mqtt.
The transport and protocol are deliberately separate. This allows the same application protocol to run over different transports.