Merge pull request #7704 from EMQ-YangM/bridge_docs

feat: emqx_bridges i18n support
This commit is contained in:
Xinyu Liu 2022-04-22 13:12:45 +08:00 committed by GitHub
commit a156933841
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 604 additions and 76 deletions

View File

@ -0,0 +1,137 @@
emqx_bridge_api {
desc_param_path_operation_cluster {
desc {
en: """Operations can be one of: enable, disable, start, stop, restart"""
zh: """集群可用操作:启用、禁用、启动、停止、重新启动"""
}
label: {
en: "Cluster Operation"
zh: "集群可用操作"
}
}
desc_param_path_operation_on_node {
desc {
en: """Operations can be one of: start, stop, restart"""
zh: """节点可用操作:启动、停止、重新启动"""
}
label: {
en: "Node Operation "
zh: "节点可用操作"
}
}
desc_param_path_node {
desc {
en: """The bridge Id. Must be of format {type}:{name}"""
zh: """Bridge ID 格式为 {type}:{name}"""
}
label: {
en: "Bridge ID"
zh: "Bridge ID"
}
}
desc_param_path_id {
desc {
en: """The bridge Id. Must be of format {type}:{name}"""
zh: """Bridge ID 格式为 {type}:{name}"""
}
label: {
en: "Bridge ID"
zh: "Bridge ID"
}
}
desc_api1 {
desc {
en: """List all created bridges"""
zh: """列出所有 Birdge """
}
label: {
en: "List All Bridges"
zh: "列出所有 Bridge"
}
}
desc_api2 {
desc {
en: """Create a new bridge by type and name"""
zh: """通过类型和名字创建 Bridge"""
}
label: {
en: "Create Bridge"
zh: "创建 Bridge"
}
}
desc_api3 {
desc {
en: """Get a bridge by Id"""
zh: """通过 ID 获取 Bridge"""
}
label: {
en: "Get Bridge"
zh: "获取 Bridge"
}
}
desc_api4 {
desc {
en: """Update a bridge by Id"""
zh: """通过 ID 更新 Bridge"""
}
label: {
en: "Update Bridge"
zh: "更新 Bridge"
}
}
desc_api5 {
desc {
en: """Delete a bridge by Id"""
zh: """通过 ID 删除 Bridge"""
}
label: {
en: "Delete Bridge"
zh: "删除 Bridge"
}
}
desc_api6 {
desc {
en: """Reset a bridge metrics by Id"""
zh: """通过 ID 重置 Bridge 的计数"""
}
label: {
en: "Reset Bridge Metrics"
zh: "重置 Bridge 计数"
}
}
desc_api7 {
desc {
en: """Enable/Disable/Stop/Restart bridges on all nodes in the cluster."""
zh: """在集群中的所有节点上启用/禁用/停止/重新启动 Bridge。"""
}
label: {
en: "Cluster Bridge Operate"
zh: "集群 Bridge 操作"
}
}
desc_api8 {
desc {
en: """Stop/Restart bridges on a specific node.
NOTE: It's not allowed to disable/enable bridges on a single node."""
zh: """在某个节点上停止/重新启动 Bridge。
NOTE不允许在单节点上启用/禁用 Bridge"""
}
label: {
en: "Node Bridge Operate"
zh: "单节点 Bridge 操作"
}
}
}

View File

@ -0,0 +1,163 @@
emqx_bridge_http_schema {
config_enable {
desc {
en: """Enable or disable this bridge"""
zh: """启用/禁用 Bridge"""
}
label: {
en: "Enable Or Disable Bridge"
zh: "启用/禁用 Bridge"
}
}
config_direction {
desc {
en: """The direction of this bridge, MUST be 'egress'"""
zh: """Bridge 的方向, 必须是 egress"""
}
label: {
en: "Bridge Direction"
zh: "Bridge 方向"
}
}
config_url {
desc {
en: """
The URL of the HTTP Bridge.<br>
Template with variables is allowed in the path, but variables cannot be used in the scheme, host,
or port part.<br>
For example, <code> http://localhost:9901/${topic} </code> is allowed, but
<code> http://${host}:9901/message </code> or <code> http://localhost:${port}/message </code>
is not allowed.
"""
zh: """
HTTP Bridge 的 URL。<br>
路径中允许使用带变量的模板,但是 host port 不允许使用变量模板。<br>
例如,<code> http://localhost:9901/${topic} </code> 是允许的,
但是<code> http://${host}:9901/message </code>
或 <code> http://localhost:${port}/message </code>
不允许。
"""
}
label: {
en: "HTTP Bridge"
zh: "HTTP Bridge"
}
}
config_local_topic {
desc {
en: """
The MQTT topic filter to be forwarded to the HTTP server. All MQTT 'PUBLISH' messages with the topic
matching the local_topic will be forwarded.<br/>
NOTE: if this bridge is used as the output of a rule (EMQX rule engine), and also local_topic is
configured, then both the data got from the rule and the MQTT messages that match local_topic
will be forwarded.
"""
zh: """
发送到 'local_topic' 的消息都会转发到 HTTP 服务器。 <br/>
注意:如果这个 Bridge 被用作规则EMQX 规则引擎)的输出,同时也配置了 'local_topic' ,那么这两部分的消息都会被转发到 HTTP 服务器。
"""
}
label: {
en: "Local Topic"
zh: "本地 Topic"
}
}
config_method {
desc {
en: """
The method of the HTTP request. All the available methods are: post, put, get, delete.<br>
Template with variables is allowed.<br>
"""
zh: """
HTTP 请求的方法。 所有可用的方法包括post、put、get、delete。<br>
允许使用带有变量的模板。<br>"""
}
label: {
en: "HTTP Method"
zh: "HTTP 请求方法"
}
}
config_headers {
desc {
en: """
The headers of the HTTP request.<br>
Template with variables is allowed.
"""
zh: """
HTTP 请求的标头。<br>
允许使用带有变量的模板。
"""
}
label: {
en: "HTTP Header"
zh: "HTTP 请求标头"
}
}
config_body {
desc {
en: """
The body of the HTTP request.<br>
Template with variables is allowed.
"""
zh: """
HTTP 请求的正文。<br>
允许使用带有变量的模板。"""
}
label: {
en: "HTTP Body"
zh: "HTTP 请求正文"
}
}
config_request_timeout {
desc {
en: """HTTP request timeout."""
zh: """HTTP 请求超时"""
}
label: {
en: "HTTP Request Timeout"
zh: "HTTP 请求超时"
}
}
desc_type {
desc {
en: """The Bridge Type"""
zh: """Bridge 类型"""
}
label: {
en: "Bridge Type"
zh: "Bridge 类型"
}
}
desc_name {
desc {
en: """Bridge name, used as a human-readable description of the bridge."""
zh: """Bridge 名字Bridge 的可读描述"""
}
label: {
en: "Bridge Name"
zh: "Bridge 名字"
}
}
desc_config {
desc {
en: """Configuration for an HTTP bridge."""
zh: """HTTP Bridge 配置"""
}
label: {
en: "HTTP Bridge Configuration"
zh: "HTTP Bridge 配置"
}
}
}

View File

@ -0,0 +1,36 @@
emqx_bridge_mqtt_schema {
desc_rec {
desc {
en: """Configuration for MQTT bridge."""
zh: """MQTT Bridge 配置"""
}
label: {
en: "MQTT Bridge Configuration"
zh: "MQTT Bridge 配置"
}
}
desc_type {
desc {
en: """The bridge type."""
zh: """Bridge 的类型"""
}
label: {
en: "Bridge Type"
zh: "Bridge 类型"
}
}
desc_name {
desc {
en: """Bridge name, used as a human-readable description of the bridge."""
zh: """Bridge 名字Bridge 的可读描述"""
}
label: {
en: "Bridge Name"
zh: "Bridge 名字"
}
}
}

View File

@ -0,0 +1,219 @@
emqx_bridge_schema {
desc_enable {
desc {
en: """Enable or disable this bridge"""
zh: """启用/禁用 Bridge"""
}
label: {
en: "Enable Or Disable Bridge"
zh: "启用/禁用 Bridge"
}
}
desc_connector {
desc {
en: """
The connector ID to be used for this bridge. Connector IDs must be of format:
<code>{type}:{name}</code>.<br>
In config files, you can find the corresponding config entry for a connector by such path:
'connectors.{type}.{name}'.<br>
"""
zh: """Bridge 使用的 Connector 的 ID。Connector ID 的格式必须为:<code>{type}:{name}</code>.<br>
在配置文件中,您可以通过以下路径找到 Connector 的相应配置条目:'connector.{type}.{name}'。<br>"""
}
label: {
en: "Connector ID"
zh: "Connector ID"
}
}
desc_metrics {
desc {
en: """The metrics of the bridge"""
zh: """Bridge 的计数"""
}
label: {
en: "Bridge Metrics"
zh: "Bridge 计数"
}
}
desc_node_metrics {
desc {
en: """The metrics of the bridge for each node"""
zh: """每个节点的 Bridge 计数"""
}
label: {
en: "Each Node Bridge Metircs"
zh: "每个节点的 Bridge 计数"
}
}
desc_status {
desc {
en: """The status of the bridge"""
zh: """Bridge 的状态"""
}
label: {
en: "Bridge Status"
zh: "Bridge 状态"
}
}
desc_node_status {
desc {
en: """The status of the bridge for each node"""
zh: """每个节点的 Bridge 状态"""
}
label: {
en: "Node Bridge Status"
zh: "每个节点的 Bridge 状态"
}
}
bridges_http {
desc {
en: """HTTP bridges to an HTTP server."""
zh: """转发消息到 HTTP 服务器的 HTTP Bridge"""
}
label: {
en: "HTTP Bridge"
zh: "HTTP Bridge"
}
}
bridges_name {
desc {
en: """MQTT bridges to/from another MQTT broker"""
zh: """桥接到另一个 MQTT Broker 的 MQTT Bridge"""
}
label: {
en: "MQTT Bridge"
zh: "MQTT Bridge"
}
}
metric_matched {
desc {
en: """Count of this bridge is queried"""
zh: """Bridge 执行操作的次数"""
}
label: {
en: "Bridge Matched"
zh: "Bridge 执行操作的次数"
}
}
metric_success {
desc {
en: """Count of query success"""
zh: """Bridge 执行操作成功的次数"""
}
label: {
en: "Bridge Success"
zh: "Bridge 执行操作成功的次数"
}
}
metric_failed {
desc {
en: """Count of query failed"""
zh: """Bridge 执行操作失败的次数"""
}
label: {
en: "Bridge Failed"
zh: "Bridge 执行操作失败的次数"
}
}
metric_rate {
desc {
en: """The rate of matched, times/second"""
zh: """执行操作的速率,次/秒"""
}
label: {
en: "Rate"
zh: "速率"
}
}
metric_rate_max {
desc {
en: """The max rate of matched, times/second"""
zh: """执行操作的最大速率,次/秒"""
}
label: {
en: "Max Rate Of Matched"
zh: "执行操作的最大速率"
}
}
metric_rate_last5m {
desc {
en: """The average rate of matched in the last 5 minutes, times/second"""
zh: """5 分钟平均速率,次/秒"""
}
label: {
en: "Last 5 Minutes Rate"
zh: "5 分钟平均速率"
}
}
desc_bridges {
desc {
en: """Configuration for MQTT bridges."""
zh: """MQTT Bridge 配置"""
}
label: {
en: "MQTT Bridge Configuration"
zh: "MQTT Bridge 配置"
}
}
desc_metrics {
desc {
en: """Bridge metrics."""
zh: """Bridge 计数"""
}
label: {
en: "Bridge Metrics"
zh: "Bridge 计数"
}
}
desc_node_metrics {
desc {
en: """Node metrics."""
zh: """节点的计数器"""
}
label: {
en: "Node Metrics"
zh: "节点的计数器"
}
}
desc_node_status {
desc {
en: """Node status."""
zh: """节点的状态"""
}
label: {
en: "Node Status"
zh: "节点的状态"
}
}
desc_node_name {
desc {
en: """The node name."""
zh: """节点的名字"""
}
label: {
en: "Node Name"
zh: "节点名字"
}
}
}

View File

@ -18,6 +18,7 @@
-behaviour(minirest_api).
-include_lib("typerefl/include/types.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-include_lib("emqx/include/logger.hrl").
-import(hoconsc, [mk/2, array/1, enum/1]).
@ -96,7 +97,7 @@ param_path_operation_cluster() ->
#{ in => path
, required => true
, example => <<"start">>
, desc => <<"Operations can be one of: enable, disable, start, stop, restart">>
, desc => ?DESC("desc_param_path_operation_cluster")
})}.
param_path_operation_on_node() ->
@ -104,7 +105,7 @@ param_path_operation_on_node() ->
#{ in => path
, required => true
, example => <<"start">>
, desc => <<"Operations can be one of: start, stop, restart">>
, desc => ?DESC("desc_param_path_operation_on_node")
})}.
param_path_node() ->
@ -112,7 +113,7 @@ param_path_node() ->
#{ in => path
, required => true
, example => <<"emqx@127.0.0.1">>
, desc => <<"The bridge Id. Must be of format {type}:{name}">>
, desc => ?DESC("desc_param_path_node")
})}.
param_path_id() ->
@ -120,7 +121,7 @@ param_path_id() ->
#{ in => path
, required => true
, example => <<"http:my_http_bridge">>
, desc => <<"The bridge Id. Must be of format {type}:{name}">>
, desc => ?DESC("desc_param_path_id")
})}.
bridge_info_array_example(Method) ->
@ -227,7 +228,7 @@ schema("/bridges") ->
get => #{
tags => [<<"bridges">>],
summary => <<"List Bridges">>,
description => <<"List all created bridges">>,
description => ?DESC("desc_api1"),
responses => #{
200 => emqx_dashboard_swagger:schema_with_example(
array(emqx_bridge_schema:get_response()),
@ -237,7 +238,7 @@ schema("/bridges") ->
post => #{
tags => [<<"bridges">>],
summary => <<"Create Bridge">>,
description => <<"Create a new bridge by type and name">>,
description => ?DESC("desc_api2"),
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
emqx_bridge_schema:post_request(),
bridge_info_examples(post)),
@ -254,7 +255,7 @@ schema("/bridges/:id") ->
get => #{
tags => [<<"bridges">>],
summary => <<"Get Bridge">>,
description => <<"Get a bridge by Id">>,
description => ?DESC("desc_api3"),
parameters => [param_path_id()],
responses => #{
200 => get_response_body_schema(),
@ -264,7 +265,7 @@ schema("/bridges/:id") ->
put => #{
tags => [<<"bridges">>],
summary => <<"Update Bridge">>,
description => <<"Update a bridge by Id">>,
description => ?DESC("desc_api4"),
parameters => [param_path_id()],
'requestBody' => emqx_dashboard_swagger:schema_with_examples(
emqx_bridge_schema:put_request(),
@ -278,7 +279,7 @@ schema("/bridges/:id") ->
delete => #{
tags => [<<"bridges">>],
summary => <<"Delete Bridge">>,
description => <<"Delete a bridge by Id">>,
description => ?DESC("desc_api5"),
parameters => [param_path_id()],
responses => #{
204 => <<"Bridge deleted">>,
@ -293,7 +294,7 @@ schema("/bridges/:id/reset_metrics") ->
put => #{
tags => [<<"bridges">>],
summary => <<"Reset Bridge Metrics">>,
description => <<"Reset a bridge metrics by Id">>,
description => ?DESC("desc_api6"),
parameters => [param_path_id()],
responses => #{
200 => <<"Reset success">>,
@ -307,8 +308,7 @@ schema("/bridges/:id/operation/:operation") ->
post => #{
tags => [<<"bridges">>],
summary => <<"Enable/Disable/Stop/Restart Bridge">>,
description => <<"Enable/Disable/Stop/Restart bridges on all nodes"
" in the cluster.">>,
description => ?DESC("desc_api7"),
parameters => [
param_path_id(),
param_path_operation_cluster()
@ -326,8 +326,7 @@ schema("/nodes/:node/bridges/:id/operation/:operation") ->
post => #{
tags => [<<"bridges">>],
summary => <<"Stop/Restart Bridge">>,
description => <<"Stop/Restart bridges on a specific node.\n"
"NOTE: It's not allowed to disable/enable bridges on a single node.">>,
description => ?DESC("desc_api8"),
parameters => [
param_path_node(),
param_path_id(),

View File

@ -1,6 +1,7 @@
-module(emqx_bridge_http_schema).
-include_lib("typerefl/include/types.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-import(hoconsc, [mk/2, enum/1]).
@ -16,30 +17,14 @@ fields("config") ->
basic_config() ++
[ {url, mk(binary(),
#{ required => true
, desc =>"
The URL of the HTTP Bridge.<br>
Template with variables is allowed in the path, but variables cannot be used in the scheme, host,
or port part.<br>
For example, <code> http://localhost:9901/${topic} </code> is allowed, but
<code> http://${host}:9901/message </code> or <code> http://localhost:${port}/message </code>
is not allowed.
"
, desc => ?DESC("config_url")
})}
, {local_topic, mk(binary(),
#{ desc =>"
The MQTT topic filter to be forwarded to the HTTP server. All MQTT 'PUBLISH' messages with the topic
matching the local_topic will be forwarded.<br/>
NOTE: if this bridge is used as the output of a rule (EMQX rule engine), and also local_topic is
configured, then both the data got from the rule and the MQTT messages that match local_topic
will be forwarded.
"
#{ desc => ?DESC("config_local_topic")
})}
, {method, mk(method(),
#{ default => post
, desc =>"
The method of the HTTP request. All the available methods are: post, put, get, delete.<br>
Template with variables is allowed.<br>
"
, desc => ?DESC("config_method")
})}
, {headers, mk(map(),
#{ default => #{
@ -48,22 +33,16 @@ Template with variables is allowed.<br>
<<"connection">> => <<"keep-alive">>,
<<"content-type">> => <<"application/json">>,
<<"keep-alive">> => <<"timeout=5">>}
, desc =>"
The headers of the HTTP request.<br>
Template with variables is allowed.
"
, desc => ?DESC("config_headers")
})
}
, {body, mk(binary(),
#{ default => <<"${payload}">>
, desc =>"
The body of the HTTP request.<br>
Template with variables is allowed.
"
, desc => ?DESC("config_body")
})}
, {request_timeout, mk(emqx_schema:duration_ms(),
#{ default => <<"15s">>
, desc => "HTTP request timeout."
, desc => ?DESC("config_request_timeout")
})}
];
@ -79,7 +58,7 @@ fields("get") ->
emqx_bridge_schema:metrics_status_fields() ++ fields("post").
desc("config") ->
"Configuration for an HTTP bridge.";
?DESC("desc_config");
desc(Method) when Method =:= "get"; Method =:= "put"; Method =:= "post" ->
["Configuration for HTTP bridge using `", string:to_upper(Method), "` method."];
desc(_) ->
@ -88,12 +67,12 @@ desc(_) ->
basic_config() ->
[ {enable,
mk(boolean(),
#{ desc => "Enable or disable this bridge"
#{ desc => ?DESC("config_enable")
, default => true
})}
, {direction,
mk(egress,
#{ desc => "The direction of this bridge, MUST be 'egress'"
#{ desc => ?DESC("config_direction")
, default => egress
})}
]
@ -104,13 +83,13 @@ basic_config() ->
type_field() ->
{type, mk(http,
#{ required => true
, desc => "The Bridge Type"
, desc => ?DESC("desc_type")
})}.
name_field() ->
{name, mk(binary(),
#{ required => true
, desc => "Bridge name, used as a human-readable description of the bridge."
, desc => ?DESC("desc_name")
})}.
method() ->

View File

@ -1,6 +1,7 @@
-module(emqx_bridge_mqtt_schema).
-include_lib("typerefl/include/types.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-import(hoconsc, [mk/2]).
@ -42,7 +43,7 @@ fields("get_egress") ->
emqx_bridge_schema:metrics_status_fields() ++ fields("post_egress").
desc(Rec) when Rec =:= "ingress"; Rec =:= "egress" ->
"Configuration for MQTT bridge.";
?DESC("desc_rec");
desc(_) ->
undefined.
@ -50,11 +51,11 @@ desc(_) ->
type_field() ->
{type, mk(mqtt,
#{ required => true
, desc => "The bridge type."
, desc => ?DESC("desc_type")
})}.
name_field() ->
{name, mk(binary(),
#{ required => true
, desc => "Bridge name, used as a human-readable description of the bridge."
, desc => ?DESC("desc_name")
})}.

View File

@ -1,6 +1,7 @@
-module(emqx_bridge_schema).
-include_lib("typerefl/include/types.hrl").
-include_lib("hocon/include/hoconsc.hrl").
-import(hoconsc, [mk/2, ref/2]).
@ -43,31 +44,24 @@ http_schema(Method) ->
common_bridge_fields() ->
[ {enable,
mk(boolean(),
#{ desc => "Enable or disable this bridge"
#{ desc => ?DESC("desc_enable")
, default => true
})}
, {connector,
mk(binary(),
#{ required => true
, example => <<"mqtt:my_mqtt_connector">>
, desc =>"""
The connector ID to be used for this bridge. Connector IDs must be of format:
<code>{type}:{name}</code>.<br>
In config files, you can find the corresponding config entry for a connector by such path:
'connectors.{type}.{name}'.<br>
"""
, desc => ?DESC("desc_connector")
})}
].
metrics_status_fields() ->
[ {"metrics", mk(ref(?MODULE, "metrics"), #{desc => "The metrics of the bridge"})}
[ {"metrics", mk(ref(?MODULE, "metrics"), #{desc => ?DESC("desc_metrics")})}
, {"node_metrics", mk(hoconsc:array(ref(?MODULE, "node_metrics")),
#{ desc => "The metrics of the bridge for each node"
})}
, {"status", mk(status(), #{desc => "The status of the bridge"})}
#{ desc => ?DESC("desc_node_metrics")})}
, {"status", mk(status(), #{desc => ?DESC("desc_status")})}
, {"node_status", mk(hoconsc:array(ref(?MODULE, "node_status")),
#{ desc => "The status of the bridge for each node"
})}
#{ desc => ?DESC("desc_node_status")})}
].
direction_field(Dir, Desc) ->
@ -87,20 +81,20 @@ roots() -> [bridges].
fields(bridges) ->
[{http, mk(hoconsc:map(name, ref(emqx_bridge_http_schema, "config")),
#{desc => "HTTP bridges to an HTTP server."})}]
#{desc => ?DESC("bridges_http")})}]
++ [{T, mk(hoconsc:map(name, hoconsc:union([ ref(schema_mod(T), "ingress")
, ref(schema_mod(T), "egress")
])),
#{desc => "MQTT bridges to/from another MQTT broker"})} || T <- ?CONN_TYPES];
#{desc => ?DESC("bridges_name")})} || T <- ?CONN_TYPES];
fields("metrics") ->
[ {"matched", mk(integer(), #{desc => "Count of this bridge is queried"})}
, {"success", mk(integer(), #{desc => "Count of query success"})}
, {"failed", mk(integer(), #{desc => "Count of query failed"})}
, {"rate", mk(float(), #{desc => "The rate of matched, times/second"})}
, {"rate_max", mk(float(), #{desc => "The max rate of matched, times/second"})}
[ {"matched", mk(integer(), #{desc => ?DESC("metric_matched")})}
, {"success", mk(integer(), #{desc => ?DESC("metric_success")})}
, {"failed", mk(integer(), #{desc => ?DESC("metric_failed")})}
, {"rate", mk(float(), #{desc => ?DESC("metric_rate")})}
, {"rate_max", mk(float(), #{desc => ?DESC("metric_rate_max")})}
, {"rate_last5m", mk(float(),
#{desc => "The average rate of matched in the last 5 minutes, times/second"})}
#{desc => ?DESC("metric_rate_last5m")})}
];
fields("node_metrics") ->
@ -114,13 +108,13 @@ fields("node_status") ->
].
desc(bridges) ->
"Configuration for MQTT bridges.";
?DESC("desc_bridges");
desc("metrics") ->
"Bridge metrics.";
?DESC("desc_metrics");
desc("node_metrics") ->
"Node metrics.";
?DESC("desc_node_metrics");
desc("node_status") ->
"Node status.";
?DESC("desc_node_status");
desc(_) ->
undefined.
@ -128,7 +122,7 @@ status() ->
hoconsc:enum([connected, disconnected, connecting]).
node_name() ->
{"node", mk(binary(), #{desc => "The node name.", example => "emqx@127.0.0.1"})}.
{"node", mk(binary(), #{desc => ?DESC("desc_node_name"), example => "emqx@127.0.0.1"})}.
schema_mod(Type) ->
list_to_atom(lists:concat(["emqx_bridge_", Type, "_schema"])).