Configuring the Command Router Service
The Command Router service provides an implementation of Eclipse Hono™’s Command Router API.
Protocol Adapters use the Command Router API to supply information that the Command Router service component can use to route command & control messages to the particular protocol adapter instances that the target devices are connected to.
The Command Router component provides an implementation of the Command Router API which uses a remote data grid for storing information about device connections. The data grid can be scaled out independently from the Command Router service components to meet the storage demands at hand.
The Command Router is implemented as a Quarkus application. It can be run either directly from the command line or by means of starting the corresponding Docker image created from it.
The Command Router had originally been implemented as a Spring Boot application. That variant has been removed in Hono 2.0.0.
Service Configuration
The following table provides an overview of the configuration variables and corresponding system properties for configuring the Command Router component.
OS Environment Variable Java System Property |
Mandatory | Default | Description |
---|---|---|---|
HONO_APP_MAXINSTANCES hono.app.maxInstances |
no | #CPU cores | The number of Verticle instances to deploy. If not set, one Verticle per processor core is deployed. |
HONO_COMMANDROUTER_AMQP_BINDADDRESS hono.commandRouter.amqp.bindAddress |
no | 127.0.0.1 |
The IP address of the network interface that the secure AMQP port should be bound to. See Port Configuration below for details. |
HONO_COMMANDROUTER_AMQP_CERTPATH hono.commandRouter.amqp.certPath |
no | - | The absolute path to the PEM file containing the certificate that the server should use for authenticating to clients. This option must be used in conjunction with HONO_COMMANDROUTER_AMQP_KEYPATH .Alternatively, the HONO_COMMANDROUTER_AMQP_KEYSTOREPATH option can be used to configure a key store containing both the key as well as the certificate. |
HONO_COMMANDROUTER_AMQP_INSECUREPORT hono.commandRouter.amqp.insecurePort |
no | - | The insecure port the server should listen on for AMQP 1.0 connections. See Port Configuration below for details. |
HONO_COMMANDROUTER_AMQP_INSECUREPORTBINDADDRESS hono.commandRouter.amqp.insecurePortBindAddress |
no | 127.0.0.1 |
The IP address of the network interface that the insecure AMQP port should be bound to. See Port Configuration below for details. |
HONO_COMMANDROUTER_AMQP_INSECUREPORTENABLED hono.commandRouter.amqp.insecurePortEnabled |
no | false |
If set to true the server will open an insecure port (not secured by TLS) using either the port number set via HONO_COMMANDROUTER_AMQP_INSECUREPORT or the default AMQP port number (5672 ) if not set explicitly.See Port Configuration below for details. |
HONO_COMMANDROUTER_AMQP_KEYPATH hono.commandRouter.amqp.keyPath |
no | - | The absolute path to the (PKCS8) PEM file containing the private key that the server should use for authenticating to clients. This option must be used in conjunction with HONO_COMMANDROUTER_AMQP_CERTPATH . Alternatively, the HONO_COMMANDROUTER_AMQP_KEYSTOREPATH option can be used to configure a key store containing both the key as well as the certificate. |
HONO_COMMANDROUTER_AMQP_KEYSTOREPASSWORD hono.commandRouter.amqp.keyStorePassword |
no | - | The password required to read the contents of the key store. |
HONO_COMMANDROUTER_AMQP_KEYSTOREPATH hono.commandRouter.amqp.keyStorePath |
no | - | The absolute path to the Java key store containing the private key and certificate that the server should use for authenticating to clients. Either this option or the HONO_COMMANDROUTER_AMQP_KEYPATH and HONO_COMMANDROUTER_AMQP_CERTPATH options need to be set in order to enable TLS secured connections with clients. The key store format can be either JKS or PKCS12 indicated by a .jks or .p12 file suffix respectively. |
HONO_COMMANDROUTER_AMQP_NATIVETLSREQUIRED hono.commandRouter.amqp.nativeTlsRequired |
no | false |
The server will probe for OpenSSL on startup if a secure port is configured. By default, the server will fall back to the JVM’s default SSL engine if not available. However, if set to true , the server will fail to start at all in this case. |
HONO_COMMANDROUTER_AMQP_PORT hono.commandRouter.amqp.port |
no | 5671 |
The secure port that the server should listen on for AMQP 1.0 connections. See Port Configuration below for details. |
HONO_COMMANDROUTER_AMQP_RECEIVERLINKCREDIT hono.commandRouter.amqp.receiverLinkCredit |
no | 100 |
The number of credits to flow to a client connecting to the service’s AMQP endpoint. |
HONO_COMMANDROUTER_AMQP_SECUREPROTOCOLS hono.commandRouter.amqp.secureProtocols |
no | TLSv1.3,TLSv1.2 |
A (comma separated) list of secure protocols (in order of preference) that are supported when negotiating TLS sessions. Please refer to the vert.x documentation for a list of supported protocol names. |
HONO_COMMANDROUTER_AMQP_SUPPORTEDCIPHERSUITES hono.commandRouter.amqp.supportedCipherSuites |
no | - | A (comma separated) list of names of cipher suites (in order of preference) that are supported when negotiating TLS sessions. Please refer to JSSE Cipher Suite Names for a list of supported names. |
HONO_COMMANDROUTER_SVC_KUBERNETESBASEDADAPTERINSTANCESTATUSSERVICEENABLED hono.commandRouter.svc.kubernetesBasedAdapterInstanceStatusServiceEnabled |
no | true |
If set to true and the Command Router component runs in a Kubernetes cluster, a Kubernetes based service to identify protocol adapter instances will be used to prevent sending command & control messages to already terminated adapter instances. Needs to be set to false if not all protocol adapters are part of the Kubernetes cluster and namespace that the Command Router component is in. |
The variables only need to be set if the default value does not match your environment.
In addition to the options described in the table above, this component supports the following standard configuration options:
Port Configuration
The Command Router component supports configuration of an AMQP based endpoint that can be configured to listen for connections on
- a secure port only (default) or
- an insecure port only or
- both a secure and an insecure port (dual port configuration)
The server will fail to start if none of the ports is configured properly.
Secure Port Only
The server needs to be configured with a private key and certificate in order to open a TLS secured port.
There are two alternative ways for doing so:
- Setting the
HONO_COMMANDROUTER_AMQP_KEYSTOREPATH
and theHONO_COMMANDROUTER_AMQP_KEYSTOREPASSWORD
variables in order to load the key & certificate from a password protected key store, or - setting the
HONO_COMMANDROUTER_AMQP_KEYPATH
andHONO_COMMANDROUTER_AMQP_CERTPATH
variables in order to load the key and certificate from two separate PEM files in PKCS8 format.
When starting up, the server will bind a TLS secured socket to the default secure AMQP port 5671. The port number can also be set explicitly using the HONO_COMMANDROUTER_AMQP_PORT
variable.
The HONO_COMMANDROUTER_AMQP_BINDADDRESS
variable can be used to specify the network interface that the port should be exposed on. By default the port is bound to the loopback device only, i.e. the port will only be accessible from the local host. Setting this variable to 0.0.0.0
will let the port being bound to all network interfaces (be careful not to expose the port unintentionally to the outside world).
Insecure Port Only
The secure port will mostly be required for production scenarios. However, it might be desirable to expose a non-TLS secured port instead, e.g. for testing purposes. In any case, the non-secure port needs to be explicitly enabled either by
- explicitly setting
HONO_COMMANDROUTER_AMQP_INSECUREPORT
to a valid port number, or by - implicitly configuring the default AMQP port (5672) by simply setting
HONO_COMMANDROUTER_AMQP_INSECUREPORTENABLED
totrue
.
The server issues a warning on the console if HONO_COMMANDROUTER_AMQP_INSECUREPORT
is set to the default secure AMQP port (5671).
The HONO_COMMANDROUTER_AMQP_INSECUREPORTBINDADDRESS
variable can be used to specify the network interface that the port should be exposed on. By default the port is bound to the loopback device only, i.e. the port will only be accessible from the local host. This variable might be used to e.g. expose the non-TLS secured port on a local interface only, thus providing easy access from within the local network, while still requiring encrypted communication when accessed from the outside over public network infrastructure.
Setting this variable to 0.0.0.0
will let the port being bound to all network interfaces (be careful not to expose the port unintentionally to the outside world).
Dual Port
In test setups and some production scenarios Hono server may be configured to open one secure and one insecure port at the same time.
This is achieved by configuring both ports correctly (see above). The server will fail to start if both ports are configured to use the same port number.
Since the secure port may need different visibility in the network setup compared to the secure port, it has its own binding address HONO_COMMANDROUTER_AMQP_INSECUREPORTBINDADDRESS
.
This can be used to narrow the visibility of the insecure port to a local network e.g., while the secure port may be visible worldwide.
Ephemeral Ports
Both the secure as well as the insecure port numbers may be explicitly set to 0
. The Command Router component will then use arbitrary (unused) port numbers determined by the operating system during startup.
Messaging Configuration
The Command Router component uses a connection to an AMQP 1.0 Messaging Network, an Apache Kafka cluster and/or Google Pub/Sub to
- receive command & control messages sent by downstream applications and to forward these commands on a specific address/topic so that they can be received by protocol adapters,
- send delivery failure command response messages in case no consumer exists for a received command (only with Kafka and Google Pub/Sub messaging),
- receive notification messages about changes to tenant/device/credentials data sent from the device registry.
- send an event message for Time until Disconnect Notification indicating the device readiness to receive commands.
Command messages are received on each configured messaging system.
For notification messages, the Kafka connection is used by default, if configured. Otherwise the AMQP messaging network or Google Pub/Sub is used.
AMQP 1.0 Messaging Network Connection Configuration
The connection to the AMQP 1.0 Messaging Network is configured according to the
Hono Client Configuration with HONO_MESSAGING
and HONO_COMMAND
being
used as ${PREFIX}
. The properties for configuring response caching can be ignored.
Kafka based Messaging Configuration
The connection to an Apache Kafka cluster can be configured according to the Hono Kafka Client Configuration.
The following table provides an overview of the prefixes to be used to individually configure the Kafka clients used by
the component. The individual client configuration is optional, a minimal configuration may only contain a common client
configuration consisting of properties prefixed with HONO_KAFKA_COMMONCLIENTCONFIG_
and hono.kafka.commonClientConfig.
respectively.
OS Environment Variable Prefix Java System Property Prefix |
Description |
---|---|
HONO_KAFKA_CLEANUP_ADMINCLIENTCONFIG_ hono.kafka.cleanup.adminClientConfig. |
Configures the Kafka admin client that removes Hono internal topics. |
HONO_KAFKA_COMMAND_CONSUMERCONFIG_ hono.kafka.command.consumerConfig. |
Configures the Kafka consumer that receives command messages. |
HONO_KAFKA_COMMANDINTERNAL_PRODUCERCONFIG_ hono.kafka.commandInternal.producerConfig. |
Configures the Kafka producer that publishes command messages to Hono internal topics. |
HONO_KAFKA_COMMANDRESPONSE_PRODUCERCONFIG_ hono.kafka.commandResponse.producerConfig. |
Configures the Kafka producer that publishes command response messages. |
HONO_KAFKA_NOTIFICATION_CONSUMERCONFIG_ hono.kafka.notification.consumerConfig. |
Configures the Kafka consumer that receives notification messages about changes to tenant/device/credentials data. |
Google Pub/Sub Messaging Configuration
The connection to Google Pub/Sub is configured according to the Google Pub/Sub Messaging Configuration.
Tenant Service Connection Configuration
The Command Router component requires a connection to an implementation of Hono’s Tenant API in order to retrieve information for a tenant.
The connection to the Tenant Service is configured according to the Hono Client Configuration
where the ${PREFIX}
is set to HONO_TENANT
and the additional values for response caching apply.
The adapter caches the responses from the service according to the cache directive included in the response. If the response doesn’t contain a cache directive no data will be cached.
Device Registration Service Connection Configuration
The Command Router component requires a connection to an implementation of Hono’s Device Registration API in order to retrieve registration status assertions for the target devices of incoming command messages.
The connection to the Device Registration Service is configured according to the Hono Client Configuration
where the ${PREFIX}
is set to HONO_REGISTRATION
.
The adapter caches the responses from the service according to the cache directive included in the response. If the response doesn’t contain a cache directive no data will be cached.
Note that the adapter uses a single cache for all responses from the service regardless of the tenant identifier. Consequently, the Device Registration Service client configuration’s responseCacheMinSize and responseCacheMaxSize properties determine the overall number of responses that can be cached.
Data Grid Connection Configuration
The Command Router component requires either an embedded cache or a remote data grid, using the Infinispan Hotrod protocol to store device information.
The following table provides an overview of the configuration variables and corresponding command line options for configuring the common aspects of the service:
OS Environment Variable Java System Property |
Mandatory | Default | Description |
---|---|---|---|
HONO_COMMANDROUTER_CACHE_COMMON_CACHENAME hono.commandRouter.cache.common.cacheName |
no | command-router |
The name of the cache |
HONO_COMMANDROUTER_CACHE_COMMON_CHECKKEY hono.commandRouter.cache.common.checkKey |
no | KEY_CONNECTION_CHECK |
The key used to check the health of the cache. This is only used in case of a remote cache. |
HONO_COMMANDROUTER_CACHE_COMMON_CHECKVALUE hono.commandRouter.cache.common.checkValue |
no | VALUE_CONNECTION_CHECK |
The value used to check the health of the cache. This is only used in case of a remote cache. |
The type of cache (embedded or remote) is determined during startup by means of the HONO_COMMANDROUTER_CACHE_REMOTE_SERVERLIST
configuration variable. If the variable has a non empty value, a remote cache is configured.
Otherwise, an embedded cache is configured.
Remote cache
The following table provides an overview of the configuration variables and corresponding system properties for configuring the connection to the data grid:
OS Environment Variable Java System Property |
Mandatory | Default | Description |
---|---|---|---|
HONO_COMMANDROUTER_CACHE_REMOTE_SERVERLIST hono.commandRouter.cache.remote.serverList |
yes | - | A list of remote servers in the form: host1[:port][;host2[:port]].... . |
HONO_COMMANDROUTER_CACHE_REMOTE_AUTHSERVERNAME hono.commandRouter.cache.remote.authServerName |
yes | - | The server name to indicate in the SASL handshake when authenticating to the server. |
HONO_COMMANDROUTER_CACHE_REMOTE_AUTHREALM hono.commandRouter.cache.remote.authRealm |
yes | - | The authentication realm for the SASL handshake when authenticating to the server. |
HONO_COMMANDROUTER_CACHE_REMOTE_AUTHUSERNAME hono.commandRouter.cache.remote.authUsername |
yes | - | The username to use for authenticating to the server. |
HONO_COMMANDROUTER_CACHE_REMOTE_AUTHPASSWORD hono.commandRouter.cache.remote.authPassword |
yes | - | The password to use for authenticating to the server. |
HONO_COMMANDROUTER_CACHE_REMOTE_SASLMECHANISM hono.commandRouter.cache.remote.saslMechanism |
yes | - | The SASL mechanism to use for authenticating to the server. |
HONO_COMMANDROUTER_CACHE_REMOTE_CLUSTER_[*] hono.commandRouter.cache.remote.cluster.[*] |
no | - | Alternate cluster definition. Example: Property: hono.commandRouter.cache.remote.cluster.siteA , value: hostA1:11222;hostA2:11223 . |
HONO_COMMANDROUTER_CACHE_REMOTE_CONNECTIONPOOL_EXHAUSTEDACTION hono.commandRouter.cache.remote.connectionPool.exhaustedAction |
no | WAIT |
Specifies what happens when asking for a connection from a server’s pool, and that pool is exhausted. Valid values are WAIT , CREATE_NEW and EXCEPTION . |
HONO_COMMANDROUTER_CACHE_REMOTE_CONNECTIONPOOL_MAXACTIVE hono.commandRouter.cache.remote.connectionPool.maxActive |
no | -1 (no limit) |
Maximum number of connections per server. |
HONO_COMMANDROUTER_CACHE_REMOTE_CONNECTIONPOOL_MAXPENDINGREQUESTS hono.commandRouter.cache.remote.connectionPool.maxPendingRequests |
no | -1 (no limit) |
Specifies the maximum number of requests sent over a single connection at one instant. |
HONO_COMMANDROUTER_CACHE_REMOTE_CONNECTIONPOOL_MAXWAIT hono.commandRouter.cache.remote.connectionPool.maxWait |
no | -1 (no limit) |
Time to wait in milliseconds for a connection to become available if exhaustedAction is WAIT . |
HONO_COMMANDROUTER_CACHE_REMOTE_CONNECTIONPOOL_MINEVICTABLEIDLETIME hono.commandRouter.cache.remote.connectionPool.minEvictableIdleTime |
no | -1 (no limit) |
Minimum amount of time that an connection may sit idle in the pool. |
HONO_COMMANDROUTER_CACHE_REMOTE_CONNECTIONPOOL_MINIDLE hono.commandRouter.cache.remote.connectionPool.minIdle |
no | -1 (no limit) |
Minimum number of idle connections (per server) that should always be available. |
HONO_COMMANDROUTER_CACHE_REMOTE_CONNECTTIMEOUT hono.commandRouter.cache.remote.connectTimeout |
no | 60000 |
The timeout for connections in milliseconds. |
HONO_COMMANDROUTER_CACHE_REMOTE_DEFAULTEXECUTORFACTORY_POOLSIZE hono.commandRouter.cache.remote.defaultExecutorFactory.poolSize |
no | 99 |
Size of the thread pool. |
HONO_COMMANDROUTER_CACHE_REMOTE_DEFAULTEXECUTORFACTORY_THREADNAMEPREFIX hono.commandRouter.cache.remote.defaultExecutorFactory.threadnamePrefix |
no | HotRod-client-async-pool |
Prefix for the default executor thread names. |
HONO_COMMANDROUTER_CACHE_REMOTE_DEFAULTEXECUTORFACTORY_THREADNAMESUFFIX hono.commandRouter.cache.remote.defaultExecutorFactory.threadnameSuffix |
no | - | Suffix for the default executor thread names. |
HONO_COMMANDROUTER_CACHE_REMOTE_KEYALIAS hono.commandRouter.cache.remote.keyAlias |
no | - | The alias of the key to use, in case the keyStore contains multiple certificates. |
HONO_COMMANDROUTER_CACHE_REMOTE_KEYSTORECERTIFICATEPASSWORD hono.commandRouter.cache.remote.keyStoreCertificatePassword |
no | - | The certificate password in the keystore. |
HONO_COMMANDROUTER_CACHE_REMOTE_KEYSTOREFILENAME hono.commandRouter.cache.remote.keyStoreFileName |
no | - | The filename of a keystore to use when using client certificate authentication. |
HONO_COMMANDROUTER_CACHE_REMOTE_KEYSTOREPASSWORD hono.commandRouter.cache.remote.keyStorePassword |
no | - | The keystore password. |
HONO_COMMANDROUTER_CACHE_REMOTE_KEYSTORETYPE hono.commandRouter.cache.remote.keyStoreType |
no | JKS |
The keystore type. |
HONO_COMMANDROUTER_CACHE_REMOTE_SASLPROPERTIES_[*] hono.commandRouter.cache.remote.saslProperties.[*] |
no | - | A SASL property (specific to the used SASL mechanism). |
HONO_COMMANDROUTER_CACHE_REMOTE_SOCKETTIMEOUT hono.commandRouter.cache.remote.socketTimeout |
no | 60000 |
The timeout for socket read/writes in milliseconds. |
HONO_COMMANDROUTER_CACHE_REMOTE_SSLCIPHERS hono.commandRouter.cache.remote.sslCiphers |
no | - | A list of ciphers, separated with spaces and in order of preference, that are used during the SSL handshake to negotiate a cryptographic algorithm for key encryption. By default, the SSL protocol (e.g. TLSv1.2) determines which ciphers to use. You should customize the cipher list with caution to avoid vulnerabilities from weak algorithms. For details about cipher lists and possible values, refer to the OpenSSL documentation. |
HONO_COMMANDROUTER_CACHE_REMOTE_SSLPROTOCOL hono.commandRouter.cache.remote.sslProtocol |
no | - | The SSL protocol to use (e.g. TLSv1.2 ). |
HONO_COMMANDROUTER_CACHE_REMOTE_TRUSTSTOREFILENAME hono.commandRouter.cache.remote.trustStoreFileName |
no | - | The path of the trust store. |
HONO_COMMANDROUTER_CACHE_REMOTE_TRUSTSTOREPASSWORD hono.commandRouter.cache.remote.trustStorePassword |
no | - | The password of the trust store. |
HONO_COMMANDROUTER_CACHE_REMOTE_TRUSTSTORETYPE hono.commandRouter.cache.remote.trustStoreType |
no | JKS |
The type of the trust store. Valid values are JKS , JCEKS , PCKS12 and PEM . |
HONO_COMMANDROUTER_CACHE_REMOTE_USESSL hono.commandRouter.cache.remote.useSSL |
no | false |
Enable TLS (implicitly enabled if a trust store is set). |
See also the Infinispan Hotrod client documentation.
Embedded cache
The following table provides an overview of the configuration variables and corresponding system properties for configuring the embedded cache:
OS Environment Variable Java System Property |
Mandatory | Default | Description |
---|---|---|---|
HONO_COMMANDROUTER_CACHE_EMBEDDED_CONFIGURATIONFILE hono.commandRouter.cache.embedded.configurationFile |
yes | - | The absolute path to an Infinispan configuration file. Also see the Infinispan Configuration Schema. |
Authentication Service Connection Configuration
The service requires a connection to an implementation of Hono’s Authentication API in order to authenticate and authorize client requests.
The connection is configured according to the Hono Client Configuration
where the ${PREFIX}
is set to HONO_AUTH
. The properties for configuring the client’s response caching will be ignored because
Hono’s Authentication Service does not allow caching of responses.
In addition to the standard client configuration properties, the following properties are supported:
OS Environment Variable Java System Property |
Mandatory | Default | Description |
---|---|---|---|
HONO_AUTH_JWKSENDPOINTPOLLINGINTERVAL hono.auth.jwksEndpointPollingInterval |
no | PT5M |
The interval at which the JWK set should be retrieved from the Authentication service. The format used is the standard java.time.Duration format. |
HONO_AUTH_JWKSENDPOINTPORT hono.auth.jwksEndpointPort |
no | 8088 |
The port of the Authentication service’s HTTP endpoint to retrieve the JWK set from. |
HONO_AUTH_JWKSENDPOINTTLSENABLED hono.auth.jwksEndpointTlsEnabled |
no | false |
Indicates if TLS should be used to retrieve the JWK set from the Authentication service. |
HONO_AUTH_JWKSENDPOINTURI hono.auth.jwksEndpointUri |
no | /validating-keys |
The URI of the Authentication service’s HTTP endpoint to retrieve the JWK set from. |
HONO_AUTH_VALIDATION_AUDIENCE hono.auth.validation.audience |
no | - | The value to expect to find in a token’s aud claim. If set, the token will not be trusted if the value in the claim does not match the value configured using this property. |
HONO_AUTH_VALIDATION_CERTPATH hono.auth.validation.certPath |
no | - | The absolute path to the PEM file containing the public key that the service should use for validating tokens issued by the Authentication service. Alternatively, a symmetric key can be used for validating tokens by setting the HONO_AUTH_VALIDATION_SHAREDSECRET variable. If none of these variables is set, the service will try to retrieve a JWK set containing the key(s) from the Authentication server. |
HONO_AUTH_VALIDATION_ISSUER hono.auth.validation.issuer |
yes | https://hono.eclipse.org/auth-server |
The value to expect to find in a token’s iss claim. The token will not be trusted if the value in the claim does not match the value configured using this property. |
HONO_AUTH_VALIDATION_SHAREDSECRET hono.auth.validation.sharedSecret |
no | - | A string to derive a symmetric key from which will be used for validating tokens issued by the Authentication service. The key is derived from the string by using the bytes of the String’s UTF8 encoding. When setting the validation key using this variable, the Authentication service must be configured with the same key. Alternatively, an X.509 certificate can be used for validating tokens by setting the HONO_AUTH_VALIDATION_CERTPATH variable. If none of these variables is set, the service will try to retrieve a JWK set containing the key(s) from the Authentication server. |
Metrics Configuration
See Monitoring & Tracing Admin Guide for details on how to configure the reporting of metrics.