Skip to main content

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: []
FieldDescription
dataList 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.

FieldRequiredDescription
nameYesFriendly name for the connection.
urlYesTransport endpoint URL. The scheme is the transport, such as tcp, ssl, tls, udp, or serial.
protocolYesApplication protocol used over the transport, such as mqtt, stogi, or another supported protocol.
remoteNoRemote authentication/session details, where supported by the protocol.
linksNoList of namespace links attached to this connection.
linkTransformationNoName of a registered ProtocolMessageTransformation, discovered using ServiceLoader.
pluginConnectionNoMarks the connection as a third-party plugin connection. Defaults to false.
costNoArbitrary connection cost. Lower cost is preferred. Defaults to the server implementation default.
groupNameNoOptional 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 caseURLProtocol
MQTT over plain TCPtcp://host:1883/mqtt
MQTT over TLStls://host:8883/mqtt
MQTT over SSLssl://host:8883/mqtt
UDP-based protocoludp://host:port/Protocol-specific
Serial modem connectionserial://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:

FieldRequiredDescription
usernameNoUsername used for authentication.
passwordNoPassword used for authentication.
sessionIdNoExisting authentication session ID, where supported.
tokenGeneratorNoToken generator type, for example JWT.
tokenConfigNoGenerator-specific token configuration.

If authentication is not required, omit remote.

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
FieldRequiredDescription
directionYesDirection of the link. Valid values are pull and push.
remote_namespaceYesRemote namespace or topic filter. MQTT-style + and # wildcards may be used where supported.
local_namespaceYesLocal destination namespace or topic.
selectorNoJMS selector expression. If omitted, all messages match.
include_schemaNoIncludes schema information when forwarding messages, where supported. Defaults to false.
transformerNoTransformation chain applied to messages flowing through the link.
statisticsNoStatistical analysis configuration for data flowing through the link.
namespaceFiltersNoAdditional namespace-specific filtering rules.
qosNoRequested QoS for the link.
linkPropertiesNoUntyped link-specific settings for protocol or handler behaviour.

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:

ValueMeaning
0Deliver at least once.
1Deliver at most once.
2Deliver 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:

TypeDescription
cloudevent-jsonCloudEvent JSON transformation.
cloudevent-nativeCloudEvent native transformation.
cloudevent-envelopeCloudEvent envelope transformation.
jsontoxmlJSON to XML transformation.
xmltojsonXML to JSON transformation.
jsontovalueExtract a value from JSON.
jsonqueryApply a JSON query transformation.
geohashResolve or generate geohash information.
schematojsonConvert schema-based payloads to JSON.
jsonmutateMutate JSON content.
jsonmapperMap JSON fields using configured mapping operations.
jsontoschemaConvert JSON payloads into schema-based payloads.

Example:

transformer:
- type: "jsonquery"
query: "[\"object\",{\"latitude\":[\"divide\",[\"get\",\"payload\",\"decoded\",\"lat\"],10000000]}]"

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"
FieldDescription
statisticNameName of the statistics engine to run.
eventCountNumber of events to process before emitting a statistics event.
ignoreListKeys to ignore when generating statistics.
keyListExplicit 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
FieldRequiredDescription
namespaceYesNamespace to which the filter applies.
depthYesDepth to which the namespace filter applies.
selectorNoSelector expression applied to the namespace.
forcePriorityNoForces this filter to take priority over others. Defaults to false.

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
FieldDescription
topicTopic to publish the Will message to.
payloadPayload published when the Will is triggered.
payloadEncodingPayload encoding. Valid values are string and base64. Defaults to string.
qosMQTT Will QoS. Valid values are 0, 1, and 2. Defaults to 0.
retainRetain flag for the Will message. Defaults to false.
delayIntervalMQTT v5 Will Delay Interval in seconds. Defaults to 0.
messageExpiryIntervalMQTT v5 Message Expiry Interval in seconds. Defaults to 0.
contentTypeMQTT v5 content type.
payloadFormatIndicatorMQTT 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:

  1. the connection endpoint,
  2. the transport scheme in url,
  3. the application protocol in protocol,
  4. the link direction,
  5. the remote and local namespaces,
  6. optional selectors,
  7. optional transformation chains,
  8. optional statistics and namespace filtering,
  9. 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.