diff --git a/apps/emqx/i18n/emqx_schema_i18n.conf b/apps/emqx/i18n/emqx_schema_i18n.conf new file mode 100644 index 000000000..4eb5d52f7 --- /dev/null +++ b/apps/emqx/i18n/emqx_schema_i18n.conf @@ -0,0 +1,373 @@ +emqx_schema { + + zones { + desc { + en: """A zone is a set of configs grouped by the zone name. +For flexible configuration mapping, the name can be set to a listener's zone config. +NOTE: A built-in zone named default is auto created and can not be deleted. +""" + zh: """ """ + } + } + + mqtt { + desc { + en: """Global MQTT configuration. +The configs here work as default values which can be overridden in zone configs +""" + zh: """ """ + } + } + + mqtt_idle_timeout { + desc { + en: """Close TCP connections from the clients that have not sent MQTT CONNECT message within this interval.""" + zh: """ """ + } + } + + mqtt_max_packet_size { + desc { + en: """Maximum MQTT packet size allowed.""" + zh: """ """ + } + } + + mqtt_max_clientid_len { + desc { + en: """"Maximum allowed length of MQTT clientId.""" + zh: """ """ + } + } + + mqtt_max_topic_levels { + desc { + en: """Maximum topic levels allowed.""" + zh: """ """ + } + } + + mqtt_max_qos_allowed { + desc { + en: """Maximum QoS allowed.""" + zh: """ """ + } + } + + mqtt_max_topic_alias { + desc { + en: """Maximum Topic Alias, 0 means no topic alias supported.""" + zh: """ """ + } + } + + mqtt_retain_available { + desc { + en: """Support MQTT retained messages.""" + zh: """ """ + } + } + + mqtt_wildcard_subscription { + desc { + en: """Support MQTT Wildcard Subscriptions.""" + zh: """ """ + } + } + + mqtt_shared_subscription { + desc { + en: """Support MQTT Shared Subscriptions.""" + zh: """ """ + } + } + + mqtt_ignore_loop_deliver { + desc { + en: """Ignore loop delivery of messages for MQTT v3.1.1.""" + zh: """ """ + } + } + + mqtt_strict_mode { + desc { + en: """Parse MQTT messages in strict mode. +When set to true, invalid utf8 strings in for example client ID, topic name, etc. will cause the client to be disconnected""" + zh: """ """ + } + } + + mqtt_response_information { + desc { + en: """Specify the response information returned to the client. +This feature is disabled if is set to \"\".""" + zh: """ """ + } + } + + mqtt_server_keepalive { + desc { + en: """'Server Keep Alive' of MQTT 5.0. +If the server returns a 'Server Keep Alive' in the CONNACK packet, the client MUST use that value instead of the value it sent as the 'Keep Alive'.""" + zh: """ """ + } + } + + mqtt_keepalive_backoff { + desc { + en: """The backoff for MQTT keepalive timeout. The broker will close the connection after idling for 'Keepalive * backoff * 2'.""" + zh: """ """ + } + } + + mqtt_max_subscriptions { + desc { + en: """Maximum number of subscriptions allowed.""" + zh: """ """ + } + } + + mqtt_upgrade_qos { + desc { + en: """Force upgrade of QoS level according to subscription.""" + zh: """ """ + } + } + + mqtt_max_inflight { + desc { + en: """Maximum size of the Inflight Window storing QoS1/2 messages delivered but un-acked.""" + zh: """ """ + } + } + + mqtt_retry_interval { + desc { + en: """Retry interval for QoS1/2 message delivering.""" + zh: """ """ + } + } + + mqtt_max_awaiting_rel { + desc { + en: """Maximum QoS2 packets (Client -> Broker) awaiting PUBREL.""" + zh: """ """ + } + } + + mqtt_await_rel_timeout { + desc { + en: """The QoS2 messages (Client -> Broker) will be dropped if awaiting PUBREL timeout.""" + zh: """ """ + } + } + + mqtt_session_expiry_interval { + desc { + en: """Default session expiry interval for MQTT V3.1.1 connections.""" + zh: """ """ + } + } + + mqtt_max_mqueue_len { + desc { + en: """Maximum queue length. Enqueued messages when persistent client disconnected, or inflight window is full.""" + zh: """ """ + } + } + + mqtt_mqueue_priorities { + desc { + en: """Topic priorities. +There's no priority table by default, hence all messages are treated equal. Priority number [1-255] + +**NOTE**: Comma and equal signs are not allowed for priority topic names. +**NOTE**: Messages for topics not in the priority table are treated as either highest or lowest priority depending on the configured value for mqtt.mqueue_default_priority. + +**Examples**: +To configure \"topic/1\" > \"topic/2\": +mqueue_priorities: {\"topic/1\": 10, \"topic/2\": 8} +""" + zh: """ """ + } + } + + mqtt_mqueue_default_priority { + desc { + en: """Default to the highest priority for topics not matching priority table.""" + zh: """ """ + } + } + + mqtt_mqueue_store_qos0 { + desc { + en: """Support enqueue QoS0 messages.""" + zh: """ """ + } + } + + mqtt_use_username_as_clientid { + desc { + en: """Replace client ID with the username.""" + zh: """ """ + } + } + + mqtt_peer_cert_as_username { + desc { + en: """Use the CN, DN or CRT field from the client certificate as a username. +Only works for the TLS connection.""" + zh: """ """ + } + } + + mqtt_peer_cert_as_clientid { + desc { + en: """Use the CN, DN or CRT field from the client certificate as a clientid. +Only works for the TLS connection.""" + zh: """ """ + } + } + + broker { + desc { + en: """"Message broker options.""" + zh: """ """ + } + } + + broker_enable_session_registry { + desc { + en: """Enable session registry""" + zh: """ """ + } + } + + broker_session_locking_strategy { + desc { + en: """Session locking strategy in a cluster. + - `local`: only lock the session on the current node + - `one`: select only one remote node to lock the session + - `quorum`: select some nodes to lock the session + - `all`: lock the session on all the nodes in the cluster +""" + + zh: """ """ + } + } + + broker_shared_subscription_strategy { + desc { + en: """Dispatch strategy for shared subscription. + - `random`: dispatch the message to a random selected subscriber + - `round_robin`: select the subscribers in a round-robin manner + - `sticky`: always use the last selected subscriber to dispatch, until the subscriber disconnects. + - `hash`: select the subscribers by the hash of `clientIds` +""" + + zh: """ """ + } + } + + broker_shared_dispatch_ack_enabled { + desc { + en: """Enable/disable shared dispatch acknowledgement for QoS1 and QoS2 messages. +This should allow messages to be dispatched to a different subscriber in the group in case the picked (based on `shared_subscription_strategy`) subscriber is offline. +""" + + zh: """ """ + } + } + + broker_route_batch_clean { + desc { + en: """Enable batch clean for deleted routes.""" + zh: """ """ + } + } + + broker_perf_route_lock_type { + desc { + en: """Performance tuning for subscribing/unsubscribing a wildcard topic. +Change this parameter only when there are many wildcard topics. + +NOTE: when changing from/to `global` lock, it requires all nodes in the cluster to be stopped before the change. + - `key`: mnesia transactional updates with per-key locks. Recommended for a single-node setup. + - `tab`: mnesia transactional updates with table lock. Recommended for a cluster setup. + - `global`: updates are protected with a global lock. Recommended for large clusters. +""" + zh: """ """ + } + } + + broker_perf_trie_compaction { + desc { + en: """Enable trie path compaction. +Enabling it significantly improves wildcard topic subscribe rate, if wildcard topics have unique prefixes like: 'sensor/{{id}}/+/', where ID is unique per subscriber. +Topic match performance (when publishing) may degrade if messages are mostly published to topics with large number of levels. + +NOTE: This is a cluster-wide configuration. It requires all nodes to be stopped before changing it. +""" + zh: """ """ + } + } + + sys_topics { + desc { + en: """ """ + zh: """ """ + } + } + + sys_msg_interval { + desc { + en: """Time interval of publishing `$SYS` messages.""" + zh: """ """ + } + } + + sys_heartbeat_interval { + desc { + en: """Time interval for publishing following heartbeat messages: +- `$SYS/brokers//uptime` +- `$SYS/brokers//datetime` +""" + zh: """ """ + } + } + + sys_event_messages { + desc { + en: """ """ + zh: """ """ + } + } + + sys_event_client_connected { + desc { + en: """Enable to publish client connected event messages""" + zh: """ """ + } + } + + sys_event_client_disconnected { + desc { + en: """Enable to publish client disconnected event messages.""" + zh: """ """ + } + } + + sys_event_client_subscribed { + desc { + en: """Enable to publish event message that client subscribed a topic successfully.""" + zh: """ """ + } + } + + sys_event_client_unsubscribed { + desc { + en: """Enable to publish event message that client unsubscribed a topic successfully.""" + zh: """ """ + } + } +} diff --git a/apps/emqx/src/emqx_schema.erl b/apps/emqx/src/emqx_schema.erl index 63cb1c825..ec3a54b2a 100644 --- a/apps/emqx/src/emqx_schema.erl +++ b/apps/emqx/src/emqx_schema.erl @@ -26,6 +26,7 @@ -include("emqx_authentication.hrl"). -include("emqx_access_control.hrl"). -include_lib("typerefl/include/types.hrl"). +-include_lib("hocon/include/hoconsc.hrl"). -type duration() :: integer(). -type duration_s() :: integer(). @@ -122,19 +123,12 @@ roots(high) -> {"zones", sc( map("name", ref("zone")), - #{ - desc => - "A zone is a set of configs grouped by the zone name.
\n" - "For flexible configuration mapping, the name\n" - "can be set to a listener's zone config.
\n" - "NOTE: A built-in zone named default is auto created\n" - "and can not be deleted." - } + #{} )}, {"mqtt", sc( ref("mqtt"), - #{} + #{ desc => ?DESC(mqtt)} )}, {?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME, authentication( @@ -171,12 +165,12 @@ roots(medium) -> {"broker", sc( ref("broker"), - #{} + #{desc => ?DESC(broker)} )}, {"sys_topics", sc( ref("sys_topics"), - #{} + #{desc => ?DESC(sys_topics)} )}, {"rate_limit", sc( @@ -374,9 +368,7 @@ fields("mqtt") -> hoconsc:union([infinity, duration()]), #{ default => "15s", - desc => - "Close TCP connections from the clients that have not sent MQTT CONNECT\n" - "message within this interval." + desc => ?DESC(mqtt_idle_timeout) } )}, {"max_packet_size", @@ -384,7 +376,7 @@ fields("mqtt") -> bytesize(), #{ default => "1MB", - desc => "Maximum MQTT packet size allowed." + desc => ?DESC(mqtt_max_packet_size) } )}, {"max_clientid_len", @@ -392,7 +384,7 @@ fields("mqtt") -> range(23, 65535), #{ default => 65535, - desc => "Maximum allowed length of MQTT clientId." + desc => ?DESC(mqtt_max_clientid_len) } )}, {"max_topic_levels", @@ -400,7 +392,7 @@ fields("mqtt") -> range(1, 65535), #{ default => 65535, - desc => "Maximum topic levels allowed." + desc => ?DESC(mqtt_max_topic_levels) } )}, {"max_qos_allowed", @@ -408,7 +400,7 @@ fields("mqtt") -> qos(), #{ default => 2, - desc => "Maximum QoS allowed." + desc => ?DESC(mqtt_max_qos_allowed) } )}, {"max_topic_alias", @@ -416,7 +408,7 @@ fields("mqtt") -> range(0, 65535), #{ default => 65535, - desc => "Maximum Topic Alias, 0 means no topic alias supported." + desc => ?DESC(mqtt_max_topic_alias) } )}, {"retain_available", @@ -424,7 +416,7 @@ fields("mqtt") -> boolean(), #{ default => true, - desc => "Support MQTT retained messages." + desc => ?DESC(mqtt_retain_available) } )}, {"wildcard_subscription", @@ -432,7 +424,7 @@ fields("mqtt") -> boolean(), #{ default => true, - desc => "Support MQTT Wildcard Subscriptions." + desc => ?DESC(mqtt_wildcard_subscription) } )}, {"shared_subscription", @@ -440,7 +432,7 @@ fields("mqtt") -> boolean(), #{ default => true, - desc => "Support MQTT Shared Subscriptions." + desc => ?DESC(mqtt_shared_subscription) } )}, {"ignore_loop_deliver", @@ -448,7 +440,7 @@ fields("mqtt") -> boolean(), #{ default => false, - desc => "Ignore loop delivery of messages for MQTT v3.1.1." + desc => ?DESC(mqtt_ignore_loop_deliver) } )}, {"strict_mode", @@ -456,11 +448,7 @@ fields("mqtt") -> boolean(), #{ default => false, - desc => - "Parse MQTT messages in strict mode. " - "When set to true, invalid utf8 strings in for example " - "client ID, topic name, etc. will cause the client to be " - "disconnected" + desc => ?DESC(mqtt_strict_mode) } )}, {"response_information", @@ -468,9 +456,7 @@ fields("mqtt") -> string(), #{ default => "", - desc => - "Specify the response information returned to the client\n" - "This feature is disabled if is set to \"\"." + desc => ?DESC(mqtt_response_information) } )}, {"server_keepalive", @@ -478,10 +464,7 @@ fields("mqtt") -> hoconsc:union([integer(), disabled]), #{ default => disabled, - desc => - "'Server Keep Alive' of MQTT 5.0.\n" - "If the server returns a 'Server Keep Alive' in the CONNACK packet,\n" - "the client MUST use that value instead of the value it sent as the 'Keep Alive'." + desc => ?DESC(mqtt_server_keepalive) } )}, {"keepalive_backoff", @@ -489,9 +472,7 @@ fields("mqtt") -> float(), #{ default => 0.75, - desc => - "The backoff for MQTT keepalive timeout. The broker will close the connection\n" - "after idling for 'Keepalive * backoff * 2'." + desc => ?DESC(mqtt_keepalive_backoff) } )}, {"max_subscriptions", @@ -499,7 +480,7 @@ fields("mqtt") -> hoconsc:union([range(1, inf), infinity]), #{ default => infinity, - desc => "Maximum number of subscriptions allowed." + desc => ?DESC(mqtt_max_subscriptions) } )}, {"upgrade_qos", @@ -507,7 +488,7 @@ fields("mqtt") -> boolean(), #{ default => false, - desc => "Force upgrade of QoS level according to subscription." + desc => ?DESC(mqtt_upgrade_qos) } )}, {"max_inflight", @@ -515,9 +496,7 @@ fields("mqtt") -> range(1, 65535), #{ default => 32, - desc => - "Maximum size of the Inflight Window storing QoS1/2 " - "messages delivered but un-acked." + desc => ?DESC(mqtt_max_inflight) } )}, {"retry_interval", @@ -525,7 +504,7 @@ fields("mqtt") -> duration(), #{ default => "30s", - desc => "Retry interval for QoS1/2 message delivering." + desc => ?DESC(mqtt_retry_interval) } )}, {"max_awaiting_rel", @@ -533,7 +512,7 @@ fields("mqtt") -> hoconsc:union([integer(), infinity]), #{ default => 100, - desc => "Maximum QoS2 packets (Client -> Broker) awaiting PUBREL." + desc => ?DESC(mqtt_max_awaiting_rel) } )}, {"await_rel_timeout", @@ -541,9 +520,7 @@ fields("mqtt") -> duration(), #{ default => "300s", - desc => - "The QoS2 messages (Client -> Broker) will be dropped " - "if awaiting PUBREL timeout." + desc => ?DESC(mqtt_await_rel_timeout) } )}, {"session_expiry_interval", @@ -551,7 +528,7 @@ fields("mqtt") -> duration(), #{ default => "2h", - desc => "Default session expiry interval for MQTT V3.1.1 connections." + desc => ?DESC(mqtt_session_expiry_interval) } )}, {"max_mqueue_len", @@ -559,9 +536,7 @@ fields("mqtt") -> hoconsc:union([non_neg_integer(), infinity]), #{ default => 1000, - desc => - "Maximum queue length. Enqueued messages when persistent client disconnected,\n" - "or inflight window is full." + desc => ?DESC(mqtt_max_mqueue_len) } )}, {"mqueue_priorities", @@ -569,19 +544,7 @@ fields("mqtt") -> hoconsc:union([map(), disabled]), #{ default => disabled, - desc => - "Topic priorities.
\n" - "There's no priority table by default, hence all messages are treated equal.
\n" - "Priority number [1-255]
\n" - "\n" - "**NOTE**: Comma and equal signs are not allowed for priority topic names.
\n" - "**NOTE**: Messages for topics not in the priority table are treated as\n" - "either highest or lowest priority depending on the configured value for\n" - "mqtt.mqueue_default_priority.\n" - "

\n" - "**Examples**:\n" - "To configure \"topic/1\" > \"topic/2\":
\n" - "mqueue_priorities: {\"topic/1\": 10, \"topic/2\": 8}" + desc => ?DESC(mqtt_mqueue_priorities) } )}, {"mqueue_default_priority", @@ -589,8 +552,7 @@ fields("mqtt") -> hoconsc:enum([highest, lowest]), #{ default => lowest, - desc => - "Default to the highest priority for topics not matching priority table." + desc => ?DESC(mqtt_mqueue_default_priority) } )}, {"mqueue_store_qos0", @@ -598,7 +560,7 @@ fields("mqtt") -> boolean(), #{ default => true, - desc => "Support enqueue QoS0 messages." + desc => ?DESC(mqtt_mqueue_store_qos0) } )}, {"use_username_as_clientid", @@ -606,7 +568,7 @@ fields("mqtt") -> boolean(), #{ default => false, - desc => "Replace client ID with the username." + desc => ?DESC(mqtt_use_username_as_clientid) } )}, {"peer_cert_as_username", @@ -614,9 +576,7 @@ fields("mqtt") -> hoconsc:enum([disabled, cn, dn, crt, pem, md5]), #{ default => disabled, - desc => - "Use the CN, DN or CRT field from the client certificate as a username.\n" - "Only works for the TLS connection." + desc => ?DESC(mqtt_peer_cert_as_username) } )}, {"peer_cert_as_clientid", @@ -624,9 +584,7 @@ fields("mqtt") -> hoconsc:enum([disabled, cn, dn, crt, pem, md5]), #{ default => disabled, - desc => - "Use the CN, DN or CRT field from the client certificate as a clientid.\n" - "Only works for the TLS connection." + desc => ?DESC(mqtt_peer_cert_as_clientid) } )} ]; @@ -1229,7 +1187,7 @@ fields("broker") -> boolean(), #{ default => true, - desc => "Enable session registry" + desc => ?DESC(broker_enable_session_registry) } )}, {"session_locking_strategy", @@ -1237,12 +1195,7 @@ fields("broker") -> hoconsc:enum([local, leader, quorum, all]), #{ default => quorum, - desc => - "Session locking strategy in a cluster.
\n" - " - `local`: only lock the session on the current node\n" - " - `one`: select only one remote node to lock the session\n" - " - `quorum`: select some nodes to lock the session\n" - " - `all`: lock the session on all the nodes in the cluster" + desc => ?DESC(broker_session_locking_strategy) } )}, {"shared_subscription_strategy", @@ -1250,13 +1203,7 @@ fields("broker") -> hoconsc:enum([random, round_robin, sticky, hash_topic, hash_clientid]), #{ default => round_robin, - desc => - "Dispatch strategy for shared subscription.
\n" - " - `random`: dispatch the message to a random selected subscriber\n" - " - `round_robin`: select the subscribers in a round-robin manner\n" - " - `sticky`: always use the last selected subscriber to dispatch,\n" - " until the subscriber disconnects.\n" - " - `hash`: select the subscribers by the hash of `clientIds`" + desc => ?DESC(broker_shared_subscription_strategy) } )}, {"shared_dispatch_ack_enabled", @@ -1264,11 +1211,7 @@ fields("broker") -> boolean(), #{ default => false, - desc => - "Enable/disable shared dispatch acknowledgement for QoS1 and QoS2 messages.
\n" - " This should allow messages to be dispatched to a different subscriber in\n" - " the group in case the picked (based on `shared_subscription_strategy`) subscriber\n" - " is offline." + desc => ?DESC(broker_shared_dispatch_ack_enabled) } )}, {"route_batch_clean", @@ -1276,7 +1219,7 @@ fields("broker") -> boolean(), #{ default => true, - desc => "Enable batch clean for deleted routes." + desc => ?DESC(broker_route_batch_clean) } )}, {"perf", @@ -1292,15 +1235,7 @@ fields("broker_perf") -> hoconsc:enum([key, tab, global]), #{ default => key, - desc => - "Performance tuning for subscribing/unsubscribing a wildcard topic.
\n" - "Change this parameter only when there are many wildcard topics.
\n" - "NOTE: when changing from/to `global` lock, it requires all\n" - "nodes in the cluster to be stopped before the change.\n\n" - " - `key`: mnesia transactional updates with per-key locks. " - "Recommended for a single-node setup.\n" - " - `tab`: mnesia transactional updates with table lock. Recommended for a cluster setup.\n" - " - `global`: updates are protected with a global lock. Recommended for large clusters." + desc => ?DESC(broker_perf_route_lock_type) } )}, {"trie_compaction", @@ -1308,15 +1243,7 @@ fields("broker_perf") -> boolean(), #{ default => true, - desc => - "Enable trie path compaction.
\n" - "Enabling it significantly improves wildcard topic subscribe\n" - "rate, if wildcard topics have unique prefixes like:\n" - "'sensor/{{id}}/+/', where ID is unique per subscriber.
\n" - "Topic match performance (when publishing) may degrade if messages\n" - "are mostly published to topics with large number of levels.
\n" - "NOTE: This is a cluster-wide configuration.\n" - "It requires all nodes to be stopped before changing it." + desc => ?DESC(broker_perf_trie_compaction) } )} ]; @@ -1327,7 +1254,7 @@ fields("sys_topics") -> hoconsc:union([disabled, duration()]), #{ default => "1m", - desc => "Time interval of publishing `$SYS` messages." + desc => ?DESC(sys_msg_interval) } )}, {"sys_heartbeat_interval", @@ -1335,16 +1262,13 @@ fields("sys_topics") -> hoconsc:union([disabled, duration()]), #{ default => "30s", - desc => - "Time interval for publishing following heartbeat messages:
" - " - `$SYS/brokers//uptime`\n" - " - `$SYS/brokers//datetime`" + desc => ?DESC(sys_heartbeat_interval) } )}, {"sys_event_messages", sc( ref("event_names"), - #{} + #{ desc => ?DESC(sys_event_messages) } )} ]; fields("event_names") -> @@ -1354,7 +1278,7 @@ fields("event_names") -> boolean(), #{ default => true, - desc => "Connection complete" + desc => ?DESC(sys_event_client_connected) } )}, {"client_disconnected", @@ -1362,7 +1286,7 @@ fields("event_names") -> boolean(), #{ default => true, - desc => "Disconnect" + desc => ?DESC(sys_event_client_disconnected) } )}, {"client_subscribed", @@ -1370,7 +1294,7 @@ fields("event_names") -> boolean(), #{ default => false, - desc => "Subscribe" + desc => ?DESC(sys_event_client_subscribed) } )}, {"client_unsubscribed", @@ -1378,7 +1302,7 @@ fields("event_names") -> boolean(), #{ default => false, - desc => "Unsubscribe" + desc => ?DESC(sys_event_client_unsubscribed) } )} ];