feat: update to openapi 3.0.0
This commit is contained in:
parent
ed1cf33b9d
commit
92ae5663a6
|
@ -71,144 +71,152 @@ apis() ->
|
|||
, subscribe_api()].
|
||||
|
||||
schemas() ->
|
||||
ClientDef = #{
|
||||
<<"node">> => #{
|
||||
type => <<"string">>,
|
||||
Client = #{
|
||||
client => #{
|
||||
type => object,
|
||||
properties => #{
|
||||
node => #{
|
||||
type => string,
|
||||
description => <<"Name of the node to which the client is connected">>},
|
||||
<<"clientid">> => #{
|
||||
type => <<"string">>,
|
||||
clientid => #{
|
||||
type => string,
|
||||
description => <<"Client identifier">>},
|
||||
<<"username">> => #{
|
||||
type => <<"string">>,
|
||||
username => #{
|
||||
type => string,
|
||||
description => <<"User name of client when connecting">>},
|
||||
<<"proto_name">> => #{
|
||||
type => <<"string">>,
|
||||
proto_name => #{
|
||||
type => string,
|
||||
description => <<"Client protocol name">>},
|
||||
<<"proto_ver">> => #{
|
||||
type => <<"integer">>,
|
||||
proto_ver => #{
|
||||
type => integer,
|
||||
description => <<"Protocol version used by the client">>},
|
||||
<<"ip_address">> => #{
|
||||
type => <<"string">>,
|
||||
ip_address => #{
|
||||
type => string,
|
||||
description => <<"Client's IP address">>},
|
||||
<<"is_bridge">> => #{
|
||||
type => <<"boolean">>,
|
||||
is_bridge => #{
|
||||
type => boolean,
|
||||
description => <<"Indicates whether the client is connectedvia bridge">>},
|
||||
<<"connected_at">> => #{
|
||||
type => <<"string">>,
|
||||
connected_at => #{
|
||||
type => string,
|
||||
description => <<"Client connection time">>},
|
||||
<<"disconnected_at">> => #{
|
||||
type => <<"string">>,
|
||||
disconnected_at => #{
|
||||
type => string,
|
||||
description => <<"Client offline time, This field is only valid and returned when connected is false">>},
|
||||
<<"connected">> => #{
|
||||
type => <<"boolean">>,
|
||||
connected => #{
|
||||
type => boolean,
|
||||
description => <<"Whether the client is connected">>},
|
||||
<<"will_msg">> => #{
|
||||
type => <<"string">>,
|
||||
will_msg => #{
|
||||
type => string,
|
||||
description => <<"Client will message">>},
|
||||
<<"zone">> => #{
|
||||
type => <<"string">>,
|
||||
zone => #{
|
||||
type => string,
|
||||
description => <<"Indicate the configuration group used by the client">>},
|
||||
<<"keepalive">> => #{
|
||||
type => <<"integer">>,
|
||||
keepalive => #{
|
||||
type => integer,
|
||||
description => <<"keepalive time, with the unit of second">>},
|
||||
<<"clean_start">> => #{
|
||||
type => <<"boolean">>,
|
||||
clean_start => #{
|
||||
type => boolean,
|
||||
description => <<"Indicate whether the client is using a brand new session">>},
|
||||
<<"expiry_interval">> => #{
|
||||
type => <<"integer">>,
|
||||
expiry_interval => #{
|
||||
type => integer,
|
||||
description => <<"Session expiration interval, with the unit of second">>},
|
||||
<<"created_at">> => #{
|
||||
type => <<"string">>,
|
||||
created_at => #{
|
||||
type => string,
|
||||
description => <<"Session creation time">>},
|
||||
<<"subscriptions_cnt">> => #{
|
||||
type => <<"integer">>,
|
||||
subscriptions_cnt => #{
|
||||
type => integer,
|
||||
description => <<"Number of subscriptions established by this client.">>},
|
||||
<<"subscriptions_max">> => #{
|
||||
type => <<"integer">>,
|
||||
subscriptions_max => #{
|
||||
type => integer,
|
||||
description => <<"v4 api name [max_subscriptions] Maximum number of subscriptions allowed by this client">>},
|
||||
<<"inflight_cnt">> => #{
|
||||
type => <<"integer">>,
|
||||
inflight_cnt => #{
|
||||
type => integer,
|
||||
description => <<"Current length of inflight">>},
|
||||
<<"inflight_max">> => #{
|
||||
type => <<"integer">>,
|
||||
inflight_max => #{
|
||||
type => integer,
|
||||
description => <<"v4 api name [max_inflight]. Maximum length of inflight">>},
|
||||
<<"mqueue_len">> => #{
|
||||
type => <<"integer">>,
|
||||
mqueue_len => #{
|
||||
type => integer,
|
||||
description => <<"Current length of message queue">>},
|
||||
<<"mqueue_max">> => #{
|
||||
type => <<"integer">>,
|
||||
mqueue_max => #{
|
||||
type => integer,
|
||||
description => <<"v4 api name [max_mqueue]. Maximum length of message queue">>},
|
||||
<<"mqueue_dropped">> => #{
|
||||
type => <<"integer">>,
|
||||
mqueue_dropped => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages dropped by the message queue due to exceeding the length">>},
|
||||
<<"awaiting_rel_cnt">> => #{
|
||||
type => <<"integer">>,
|
||||
awaiting_rel_cnt => #{
|
||||
type => integer,
|
||||
description => <<"v4 api name [awaiting_rel] Number of awaiting PUBREC packet">>},
|
||||
<<"awaiting_rel_max">> => #{
|
||||
type => <<"integer">>,
|
||||
awaiting_rel_max => #{
|
||||
type => integer,
|
||||
description => <<"v4 api name [max_awaiting_rel]. Maximum allowed number of awaiting PUBREC packet">>},
|
||||
<<"recv_oct">> => #{
|
||||
type => <<"integer">>,
|
||||
recv_oct => #{
|
||||
type => integer,
|
||||
description => <<"Number of bytes received by EMQ X Broker (the same below)">>},
|
||||
<<"recv_cnt">> => #{
|
||||
type => <<"integer">>,
|
||||
recv_cnt => #{
|
||||
type => integer,
|
||||
description => <<"Number of TCP packets received">>},
|
||||
<<"recv_pkt">> => #{
|
||||
type => <<"integer">>,
|
||||
recv_pkt => #{
|
||||
type => integer,
|
||||
description => <<"Number of MQTT packets received">>},
|
||||
<<"recv_msg">> => #{
|
||||
type => <<"integer">>,
|
||||
recv_msg => #{
|
||||
type => integer,
|
||||
description => <<"Number of PUBLISH packets received">>},
|
||||
<<"send_oct">> => #{
|
||||
type => <<"integer">>,
|
||||
send_oct => #{
|
||||
type => integer,
|
||||
description => <<"Number of bytes sent">>},
|
||||
<<"send_cnt">> => #{
|
||||
type => <<"integer">>,
|
||||
send_cnt => #{
|
||||
type => integer,
|
||||
description => <<"Number of TCP packets sent">>},
|
||||
<<"send_pkt">> => #{
|
||||
type => <<"integer">>,
|
||||
send_pkt => #{
|
||||
type => integer,
|
||||
description => <<"Number of MQTT packets sent">>},
|
||||
<<"send_msg">> => #{
|
||||
type => <<"integer">>,
|
||||
send_msg => #{
|
||||
type => integer,
|
||||
description => <<"Number of PUBLISH packets sent">>},
|
||||
<<"mailbox_len">> => #{
|
||||
type => <<"integer">>,
|
||||
mailbox_len => #{
|
||||
type => integer,
|
||||
description => <<"Process mailbox size">>},
|
||||
<<"heap_size">> => #{
|
||||
type => <<"integer">>,
|
||||
heap_size => #{
|
||||
type => integer,
|
||||
description => <<"Process heap size with the unit of byte">>
|
||||
},
|
||||
<<"reductions">> => #{
|
||||
type => <<"integer">>,
|
||||
description => <<"Erlang reduction">>}},
|
||||
ACLCacheDefinitionProperties = #{
|
||||
<<"topic">> => #{
|
||||
type => <<"string">>,
|
||||
reductions => #{
|
||||
type => integer,
|
||||
description => <<"Erlang reduction">>}
|
||||
}
|
||||
}
|
||||
},
|
||||
AclCache = #{
|
||||
acl_cache => #{
|
||||
type => object,
|
||||
properties => #{
|
||||
topic => #{
|
||||
type => string,
|
||||
description => <<"Topic name">>},
|
||||
<<"access">> => #{
|
||||
type => <<"string">>,
|
||||
access => #{
|
||||
type => string,
|
||||
enum => [<<"subscribe">>, <<"publish">>],
|
||||
description => <<"Access type">>},
|
||||
<<"result">> => #{
|
||||
type => <<"string">>,
|
||||
result => #{
|
||||
type => string,
|
||||
enum => [<<"allow">>, <<"deny">>],
|
||||
default => <<"allow">>,
|
||||
description => <<"Allow or deny">>},
|
||||
<<"updated_time">> => #{
|
||||
type => <<"integer">>,
|
||||
description => <<"Update time">>}},
|
||||
[{<<"client">>, ClientDef}, {<<"acl_cache">>, ACLCacheDefinitionProperties}].
|
||||
updated_time => #{
|
||||
type => integer,
|
||||
description => <<"Update time">>}
|
||||
}
|
||||
}
|
||||
},
|
||||
[Client, AclCache].
|
||||
|
||||
clients_api() ->
|
||||
Metadata = #{
|
||||
get => #{
|
||||
description => "List clients",
|
||||
responses => #{
|
||||
<<"200">> => #{
|
||||
description => <<"List clients 200 OK">>,
|
||||
schema => #{
|
||||
type => array,
|
||||
items => minirest:ref(<<"client">>)}}}}},
|
||||
<<"200">> => emqx_mgmt_util:response_array_schema(<<"List clients 200 OK">>, <<"client">>)}}},
|
||||
{"/clients", Metadata, clients}.
|
||||
|
||||
client_api() ->
|
||||
|
@ -218,25 +226,23 @@ client_api() ->
|
|||
parameters => [#{
|
||||
name => clientid,
|
||||
in => path,
|
||||
type => string,
|
||||
schema => #{type => string},
|
||||
required => true,
|
||||
default => 123456}],
|
||||
example => 123456}],
|
||||
responses => #{
|
||||
<<"404">> => emqx_mgmt_util:not_found_schema(<<"Client id not found">>),
|
||||
<<"200">> => #{
|
||||
description => <<"Get clients 200 OK">>,
|
||||
schema => minirest:ref(<<"client">>)}}},
|
||||
<<"200">> => emqx_mgmt_util:response_schema(<<"List clients 200 OK">>, <<"client">>)}},
|
||||
delete => #{
|
||||
description => "Kick out client by client ID",
|
||||
parameters => [#{
|
||||
name => clientid,
|
||||
in => path,
|
||||
type => string,
|
||||
schema => #{type => string},
|
||||
required => true,
|
||||
default => 123456}],
|
||||
example => 123456}],
|
||||
responses => #{
|
||||
<<"404">> => emqx_mgmt_util:not_found_schema(<<"Client id not found">>),
|
||||
<<"200">> => #{description => <<"Kick out clients OK">>}}}},
|
||||
<<"200">> => emqx_mgmt_util:response_schema(<<"List clients 200 OK">>, <<"client">>)}}},
|
||||
{"/clients/:clientid", Metadata, client}.
|
||||
|
||||
clients_acl_cache_api() ->
|
||||
|
@ -246,26 +252,23 @@ clients_acl_cache_api() ->
|
|||
parameters => [#{
|
||||
name => clientid,
|
||||
in => path,
|
||||
type => string,
|
||||
schema => #{type => string},
|
||||
required => true,
|
||||
default => 123456}],
|
||||
example => 123456}],
|
||||
responses => #{
|
||||
<<"404">> => emqx_mgmt_util:not_found_schema(<<"Client id not found">>),
|
||||
<<"200">> => #{
|
||||
description => <<"List 200 OK">>,
|
||||
schema => minirest:ref(<<"acl_cache">>)}}},
|
||||
<<"200">> => emqx_mgmt_util:response_schema(<<"List clients 200 OK">>, <<"acl_cache">>)}},
|
||||
delete => #{
|
||||
description => "Clean client acl cache",
|
||||
parameters => [#{
|
||||
name => clientid,
|
||||
in => path,
|
||||
type => string,
|
||||
schema => #{type => string},
|
||||
required => true,
|
||||
default => 123456}],
|
||||
example => 123456}],
|
||||
responses => #{
|
||||
<<"404">> => emqx_mgmt_util:not_found_schema(<<"client id not found">>),
|
||||
<<"200">> => #{
|
||||
description => <<"Clean acl cache 200 OK">>}}}},
|
||||
<<"404">> => emqx_mgmt_util:not_found_schema(<<"Client id not found">>),
|
||||
<<"200">> => emqx_mgmt_util:response_schema(<<"Delete clients 200 OK">>)}}},
|
||||
{"/clients/:clientid/acl_cache", Metadata, acl_cache}.
|
||||
|
||||
subscribe_api() ->
|
||||
|
@ -276,51 +279,47 @@ subscribe_api() ->
|
|||
#{
|
||||
name => clientid,
|
||||
in => path,
|
||||
type => string,
|
||||
schema => #{type => string},
|
||||
required => true,
|
||||
default => 123456
|
||||
},
|
||||
#{
|
||||
name => topic_data,
|
||||
in => body,
|
||||
schema => #{
|
||||
example => 123456
|
||||
}
|
||||
],
|
||||
'requestBody' => emqx_mgmt_util:request_body_schema(#{
|
||||
type => object,
|
||||
properties => #{
|
||||
<<"topic">> => #{
|
||||
type => <<"string">>,
|
||||
type => string,
|
||||
example => <<"topic_1">>,
|
||||
description => <<"Topic">>},
|
||||
<<"qos">> => #{
|
||||
type => <<"integer">>,
|
||||
type => integer,
|
||||
enum => [0, 1, 2],
|
||||
example => 0,
|
||||
description => <<"QOS">>}}}
|
||||
}
|
||||
],
|
||||
description => <<"QoS">>}}}),
|
||||
responses => #{
|
||||
<<"404">> => emqx_mgmt_util:not_found_schema(<<"Client id not found">>),
|
||||
<<"200">> => #{description => <<"subscribe ok">>}}},
|
||||
<<"200">> => emqx_mgmt_util:response_schema(<<"subscribe ok">>)}},
|
||||
delete => #{
|
||||
description => "unsubscribe",
|
||||
parameters => [
|
||||
#{
|
||||
name => clientid,
|
||||
in => path,
|
||||
type => string,
|
||||
schema => #{type => string},
|
||||
required => true,
|
||||
default => 123456
|
||||
example => 123456
|
||||
},
|
||||
#{
|
||||
name => topic,
|
||||
in => query,
|
||||
type => string,
|
||||
schema => #{type => string},
|
||||
required => true,
|
||||
default => <<"topic_1">>
|
||||
example => <<"topic_1">>
|
||||
}
|
||||
],
|
||||
responses => #{
|
||||
<<"404">> => emqx_mgmt_util:not_found_schema(<<"Client id not found">>),
|
||||
<<"200">> => #{description => <<"unsubscribe ok">>}}}},
|
||||
<<"200">> => emqx_mgmt_util:response_schema(<<"unsubscribe ok">>)}}},
|
||||
{"/clients/:clientid/subscribe", Metadata, subscribe}.
|
||||
|
||||
%%%==============================================================================================
|
||||
|
|
|
@ -26,263 +26,266 @@ api_spec() ->
|
|||
{[metrics_api()], [metrics_schema()]}.
|
||||
|
||||
metrics_schema() ->
|
||||
DefinitionName = <<"metrics">>,
|
||||
DefinitionProperties = #{
|
||||
<<"actions.failure">> => #{
|
||||
type => <<"integer">>,
|
||||
#{
|
||||
metrics => #{
|
||||
type => object,
|
||||
properties => #{
|
||||
'actions.failure' => #{
|
||||
type => integer,
|
||||
description => <<"Number of failure executions of the rule engine action">>},
|
||||
<<"actions.success">> => #{
|
||||
type => <<"integer">>,
|
||||
'actions.success' => #{
|
||||
type => integer,
|
||||
description => <<"Number of successful executions of the rule engine action">>},
|
||||
<<"bytes.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'bytes.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of bytes received by EMQ X Broker">>},
|
||||
<<"bytes.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'bytes.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of bytes sent by EMQ X Broker on this connection">>},
|
||||
<<"client.authenticate">> => #{
|
||||
type => <<"integer">>,
|
||||
'client.authenticate' => #{
|
||||
type => integer,
|
||||
description => <<"Number of client authentications">>},
|
||||
<<"client.auth.anonymous">> => #{
|
||||
type => <<"integer">>,
|
||||
'client.auth.anonymous' => #{
|
||||
type => integer,
|
||||
description => <<"Number of clients who log in anonymously">>},
|
||||
<<"client.connect">> => #{
|
||||
type => <<"integer">>,
|
||||
'client.connect' => #{
|
||||
type => integer,
|
||||
description => <<"Number of client connections">>},
|
||||
<<"client.connack">> => #{
|
||||
type => <<"integer">>,
|
||||
'client.connack' => #{
|
||||
type => integer,
|
||||
description => <<"Number of CONNACK packet sent">>},
|
||||
<<"client.connected">> => #{
|
||||
type => <<"integer">>,
|
||||
'client.connected' => #{
|
||||
type => integer,
|
||||
description => <<"Number of successful client connections">>},
|
||||
<<"client.disconnected">> => #{
|
||||
type => <<"integer">>,
|
||||
'client.disconnected' => #{
|
||||
type => integer,
|
||||
description => <<"Number of client disconnects">>},
|
||||
<<"client.check_acl">> => #{
|
||||
type => <<"integer">>,
|
||||
'client.check_acl' => #{
|
||||
type => integer,
|
||||
description => <<"Number of ACL rule checks">>},
|
||||
<<"client.subscribe">> => #{
|
||||
type => <<"integer">>,
|
||||
'client.subscribe' => #{
|
||||
type => integer,
|
||||
description => <<"Number of client subscriptions">>},
|
||||
<<"client.unsubscribe">> => #{
|
||||
type => <<"integer">>,
|
||||
'client.unsubscribe' => #{
|
||||
type => integer,
|
||||
description => <<"Number of client unsubscriptions">>},
|
||||
<<"delivery.dropped.too_large">> => #{
|
||||
type => <<"integer">>,
|
||||
'delivery.dropped.too_large' => #{
|
||||
type => integer,
|
||||
description => <<"The number of messages that were dropped because the length exceeded the limit when sending">>},
|
||||
<<"delivery.dropped.queue_full">> => #{
|
||||
type => <<"integer">>,
|
||||
'delivery.dropped.queue_full' => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages with a non-zero QoS that were dropped because the message queue was full when sending">>},
|
||||
<<"delivery.dropped.qos0_msg">> => #{
|
||||
type => <<"integer">>,
|
||||
'delivery.dropped.qos0_msg' => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages with QoS 0 that were dropped because the message queue was full when sending">>},
|
||||
<<"delivery.dropped.expired">> => #{
|
||||
type => <<"integer">>,
|
||||
'delivery.dropped.expired' => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages dropped due to message expiration on sending">>},
|
||||
<<"delivery.dropped.no_local">> => #{
|
||||
type => <<"integer">>,
|
||||
'delivery.dropped.no_local' => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages that were dropped due to the No Local subscription option when sending">>},
|
||||
<<"delivery.dropped">> => #{
|
||||
type => <<"integer">>,
|
||||
'delivery.dropped' => #{
|
||||
type => integer,
|
||||
description => <<"Total number of discarded messages when sending">>},
|
||||
<<"messages.delayed">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.delayed' => #{
|
||||
type => integer,
|
||||
description => <<"Number of delay- published messages stored by EMQ X Broker">>},
|
||||
<<"messages.delivered">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.delivered' => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages forwarded to the subscription process internally by EMQ X Broker">>},
|
||||
<<"messages.dropped">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.dropped' => #{
|
||||
type => integer,
|
||||
description => <<"Total number of messages dropped by EMQ X Broker before forwarding to the subscription process">>},
|
||||
<<"messages.dropped.expired">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.dropped.expired' => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages dropped due to message expiration when receiving">>},
|
||||
<<"messages.dropped.no_subscribers">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.dropped.no_subscribers' => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages dropped due to no subscribers">>},
|
||||
<<"messages.forward">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.forward' => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages forwarded to other nodes">>},
|
||||
<<"messages.publish">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.publish' => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages published in addition to system messages">>},
|
||||
<<"messages.qos0.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.qos0.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of QoS 0 messages received from clients">>},
|
||||
<<"messages.qos1.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.qos1.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of QoS 1 messages received from clients">>},
|
||||
<<"messages.qos2.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.qos2.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of QoS 2 messages received from clients">>},
|
||||
<<"messages.qos0.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.qos0.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of QoS 0 messages sent to clients">>},
|
||||
<<"messages.qos1.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.qos1.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of QoS 1 messages sent to clients">>},
|
||||
<<"messages.qos2.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.qos2.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of QoS 2 messages sent to clients">>},
|
||||
<<"messages.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages received from the client, equal to the sum of messages.qos0.received,messages.qos1.received and messages.qos2.received">>},
|
||||
<<"messages.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages sent to the client, equal to the sum of messages.qos0.sent,messages.qos1.sent and messages.qos2.sent">>},
|
||||
<<"messages.retained">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.retained' => #{
|
||||
type => integer,
|
||||
description => <<"Number of retained messages stored by EMQ X Broker">>},
|
||||
<<"messages.acked">> => #{
|
||||
type => <<"integer">>,
|
||||
'messages.acked' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBACK and PUBREC packet">>},
|
||||
<<"packets.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received packet">>},
|
||||
<<"packets.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sent packet">>},
|
||||
<<"packets.connect.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.connect.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received CONNECT packet">>},
|
||||
<<"packets.connack.auth_error">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.connack.auth_error' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received CONNECT packet with failed authentication">>},
|
||||
<<"packets.connack.error">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.connack.error' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received CONNECT packet with unsuccessful connections">>},
|
||||
<<"packets.connack.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.connack.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sent CONNACK packet">>},
|
||||
<<"packets.publish.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.publish.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBLISH packet">>},
|
||||
<<"packets.publish.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.publish.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sent PUBLISH packet">>},
|
||||
<<"packets.publish.inuse">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.publish.inuse' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBLISH packet with occupied identifiers">>},
|
||||
<<"packets.publish.auth_error">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.publish.auth_error' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBLISH packets with failed the ACL check">>},
|
||||
<<"packets.publish.error">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.publish.error' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBLISH packet that cannot be published">>},
|
||||
<<"packets.publish.dropped">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.publish.dropped' => #{
|
||||
type => integer,
|
||||
description => <<"Number of messages discarded due to the receiving limit">>},
|
||||
<<"packets.puback.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.puback.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBACK packet">>},
|
||||
<<"packets.puback.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.puback.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sent PUBACK packet">>},
|
||||
<<"packets.puback.inuse">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.puback.inuse' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBACK packet with occupied identifiers">>},
|
||||
<<"packets.puback.missed">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.puback.missed' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received packet with identifiers.">>},
|
||||
<<"packets.pubrec.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pubrec.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBREC packet">>},
|
||||
<<"packets.pubrec.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pubrec.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sent PUBREC packet">>},
|
||||
<<"packets.pubrec.inuse">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pubrec.inuse' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBREC packet with occupied identifiers">>},
|
||||
<<"packets.pubrec.missed">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pubrec.missed' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBREC packet with unknown identifiers">>},
|
||||
<<"packets.pubrel.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pubrel.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBREL packet">>},
|
||||
<<"packets.pubrel.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pubrel.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sent PUBREL packet">>},
|
||||
<<"packets.pubrel.missed">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pubrel.missed' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBREC packet with unknown identifiers">>},
|
||||
<<"packets.pubcomp.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pubcomp.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBCOMP packet">>},
|
||||
<<"packets.pubcomp.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pubcomp.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sent PUBCOMP packet">>},
|
||||
<<"packets.pubcomp.inuse">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pubcomp.inuse' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PUBCOMP packet with occupied identifiers">>},
|
||||
<<"packets.pubcomp.missed">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pubcomp.missed' => #{
|
||||
type => integer,
|
||||
description => <<"Number of missed PUBCOMP packet">>},
|
||||
<<"packets.subscribe.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.subscribe.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received SUBSCRIBE packet">>},
|
||||
<<"packets.subscribe.error">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.subscribe.error' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received SUBSCRIBE packet with failed subscriptions">>},
|
||||
<<"packets.subscribe.auth_error">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.subscribe.auth_error' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received SUBACK packet with failed ACL check">>},
|
||||
<<"packets.suback.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.suback.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sent SUBACK packet">>},
|
||||
<<"packets.unsubscribe.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.unsubscribe.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received UNSUBSCRIBE packet">>},
|
||||
<<"packets.unsubscribe.error">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.unsubscribe.error' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received UNSUBSCRIBE packet with failed unsubscriptions">>},
|
||||
<<"packets.unsuback.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.unsuback.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sent UNSUBACK packet">>},
|
||||
<<"packets.pingreq.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pingreq.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received PINGREQ packet">>},
|
||||
<<"packets.pingresp.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.pingresp.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sent PUBRESP packet">>},
|
||||
<<"packets.disconnect.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.disconnect.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received DISCONNECT packet">>},
|
||||
<<"packets.disconnect.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.disconnect.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sent DISCONNECT packet">>},
|
||||
<<"packets.auth.received">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.auth.received' => #{
|
||||
type => integer,
|
||||
description => <<"Number of received AUTH packet">>},
|
||||
<<"packets.auth.sent">> => #{
|
||||
type => <<"integer">>,
|
||||
'packets.auth.sent' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sent AUTH packet">>},
|
||||
<<"rules.matched">> => #{
|
||||
type => <<"integer">>,
|
||||
'rules.matched' => #{
|
||||
type => integer,
|
||||
description => <<"Number of rule matched">>},
|
||||
<<"session.created">> => #{
|
||||
type => <<"integer">>,
|
||||
'session.created' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sessions created">>},
|
||||
<<"session.discarded">> => #{
|
||||
type => <<"integer">>,
|
||||
'session.discarded' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sessions dropped because Clean Session or Clean Start is true">>},
|
||||
<<"session.resumed">> => #{
|
||||
type => <<"integer">>,
|
||||
'session.resumed' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sessions resumed because Clean Session or Clean Start is false">>},
|
||||
<<"session.takeovered">> => #{
|
||||
type => <<"integer">>,
|
||||
'session.takeovered' => #{
|
||||
type => integer,
|
||||
description => <<"Number of sessions takeovered because Clean Session or Clean Start is false">>},
|
||||
<<"session.terminated">> => #{
|
||||
type => <<"integer">>,
|
||||
description => <<"Number of terminated sessions">>}},
|
||||
{DefinitionName, DefinitionProperties}.
|
||||
'session.terminated' => #{
|
||||
type => integer,
|
||||
description => <<"Number of terminated sessions">>}
|
||||
}
|
||||
}
|
||||
}.
|
||||
|
||||
metrics_api() ->
|
||||
Metadata = #{
|
||||
get => #{
|
||||
description => "EMQ X metrics",
|
||||
responses => #{
|
||||
<<"200">> => #{
|
||||
schema => cowboy_swagger:schema(<<"metrics">>)}}}},
|
||||
<<"200">> => emqx_mgmt_util:response_schema(<<"List all metrics">>, <<"metrics">>)}}},
|
||||
{"/metrics", Metadata, list}.
|
||||
|
||||
%%%==============================================================================================
|
||||
|
|
|
@ -41,71 +41,71 @@ schemas() ->
|
|||
[node_schema()].
|
||||
|
||||
node_schema() ->
|
||||
DefinitionName = <<"node">>,
|
||||
DefinitionProperties = #{
|
||||
<<"node">> => #{
|
||||
type => <<"string">>,
|
||||
#{
|
||||
node => #{
|
||||
type => object,
|
||||
properties => #{
|
||||
node => #{
|
||||
type => string,
|
||||
description => <<"Node name">>},
|
||||
<<"connections">> => #{
|
||||
type => <<"integer">>,
|
||||
connections => #{
|
||||
type => integer,
|
||||
description => <<"Number of clients currently connected to this node">>},
|
||||
<<"load1">> => #{
|
||||
type => <<"string">>,
|
||||
load1 => #{
|
||||
type => string,
|
||||
description => <<"CPU average load in 1 minute">>},
|
||||
<<"load5">> => #{
|
||||
type => <<"string">>,
|
||||
load5 => #{
|
||||
type => string,
|
||||
description => <<"CPU average load in 5 minute">>},
|
||||
<<"load15">> => #{
|
||||
type => <<"string">>,
|
||||
load15 => #{
|
||||
type => string,
|
||||
description => <<"CPU average load in 15 minute">>},
|
||||
<<"max_fds">> => #{
|
||||
type => <<"integer">>,
|
||||
max_fds => #{
|
||||
type => integer,
|
||||
description => <<"Maximum file descriptor limit for the operating system">>},
|
||||
<<"memory_total">> => #{
|
||||
type => <<"string">>,
|
||||
memory_total => #{
|
||||
type => string,
|
||||
description => <<"VM allocated system memory">>},
|
||||
<<"memory_used">> => #{
|
||||
type => <<"string">>,
|
||||
memory_used => #{
|
||||
type => string,
|
||||
description => <<"VM occupied system memory">>},
|
||||
<<"node_status">> => #{
|
||||
type => <<"string">>,
|
||||
node_status => #{
|
||||
type => string,
|
||||
description => <<"Node status">>},
|
||||
<<"otp_release">> => #{
|
||||
type => <<"string">>,
|
||||
otp_release => #{
|
||||
type => string,
|
||||
description => <<"Erlang/OTP version used by EMQ X Broker">>},
|
||||
<<"process_available">> => #{
|
||||
type => <<"integer">>,
|
||||
process_available => #{
|
||||
type => integer,
|
||||
description => <<"Number of available processes">>},
|
||||
<<"process_used">> => #{
|
||||
type => <<"integer">>,
|
||||
process_used => #{
|
||||
type => integer,
|
||||
description => <<"Number of used processes">>},
|
||||
<<"uptime">> => #{
|
||||
type => <<"string">>,
|
||||
uptime => #{
|
||||
type => string,
|
||||
description => <<"EMQ X Broker runtime">>},
|
||||
<<"version">> => #{
|
||||
type => <<"string">>,
|
||||
version => #{
|
||||
type => string,
|
||||
description => <<"EMQ X Broker version">>},
|
||||
<<"sys_path">> => #{
|
||||
type => <<"string">>,
|
||||
sys_path => #{
|
||||
type => string,
|
||||
description => <<"EMQ X system file location">>},
|
||||
<<"log_path">> => #{
|
||||
type => <<"string">>,
|
||||
log_path => #{
|
||||
type => string,
|
||||
description => <<"EMQ X log file location">>},
|
||||
<<"config_path">> => #{
|
||||
type => <<"string">>,
|
||||
config_path => #{
|
||||
type => string,
|
||||
description => <<"EMQ X config file location">>}
|
||||
},
|
||||
{DefinitionName, DefinitionProperties}.
|
||||
}
|
||||
}
|
||||
}.
|
||||
|
||||
nodes_api() ->
|
||||
Metadata = #{
|
||||
get => #{
|
||||
description => "List EMQ X nodes",
|
||||
responses => #{
|
||||
<<"200">> => #{description => <<"List EMQ X Nodes">>,
|
||||
schema => #{
|
||||
type => array,
|
||||
items => cowboy_swagger:schema(<<"node">>)}}}}},
|
||||
<<"200">> => emqx_mgmt_util:response_array_schema(<<"List EMQ X Nodes">>, <<"node">>)}}},
|
||||
{"/nodes", Metadata, nodes}.
|
||||
|
||||
node_api() ->
|
||||
|
@ -116,15 +116,12 @@ node_api() ->
|
|||
name => node_name,
|
||||
in => path,
|
||||
description => "node name",
|
||||
type => string,
|
||||
schema => #{type => string},
|
||||
required => true,
|
||||
default => node()}],
|
||||
example => node()}],
|
||||
responses => #{
|
||||
<<"400">> =>
|
||||
emqx_mgmt_util:not_found_schema(<<"Node error">>, [<<"SOURCE_ERROR">>]),
|
||||
<<"200">> => #{
|
||||
description => <<"Get EMQ X Nodes info by name">>,
|
||||
schema => cowboy_swagger:schema(<<"node">>)}}}},
|
||||
<<"400">> => emqx_mgmt_util:not_found_schema(<<"Node error">>, [<<"SOURCE_ERROR">>]),
|
||||
<<"200">> => emqx_mgmt_util:response_schema(<<"Get EMQ X Nodes info by name">>, <<"node">>)}}},
|
||||
{"/nodes/:node_name", Metadata, node}.
|
||||
|
||||
node_metrics_api() ->
|
||||
|
@ -135,15 +132,12 @@ node_metrics_api() ->
|
|||
name => node_name,
|
||||
in => path,
|
||||
description => "node name",
|
||||
type => string,
|
||||
schema => #{type => string},
|
||||
required => true,
|
||||
default => node()}],
|
||||
example => node()}],
|
||||
responses => #{
|
||||
<<"400">> =>
|
||||
emqx_mgmt_util:not_found_schema(<<"Node error">>, [<<"SOURCE_ERROR">>]),
|
||||
<<"200">> => #{
|
||||
description => <<"Get EMQ X Node Metrics">>,
|
||||
schema => cowboy_swagger:schema(<<"metrics">>)}}}},
|
||||
<<"400">> => emqx_mgmt_util:not_found_schema(<<"Node error">>, [<<"SOURCE_ERROR">>]),
|
||||
<<"200">> => emqx_mgmt_util:response_schema(<<"Get EMQ X Node Metrics">>, <<"metrics">>)}}},
|
||||
{"/nodes/:node_name/metrics", Metadata, node_metrics}.
|
||||
|
||||
node_stats_api() ->
|
||||
|
@ -154,15 +148,12 @@ node_stats_api() ->
|
|||
name => node_name,
|
||||
in => path,
|
||||
description => "node name",
|
||||
type => string,
|
||||
schema => #{type => string},
|
||||
required => true,
|
||||
default => node()}],
|
||||
example => node()}],
|
||||
responses => #{
|
||||
<<"400">> =>
|
||||
emqx_mgmt_util:not_found_schema(<<"Node error">>, [<<"SOURCE_ERROR">>]),
|
||||
<<"200">> => #{
|
||||
description => <<"Get EMQ X Node Stats">>,
|
||||
schema => cowboy_swagger:schema(<<"stats">>)}}}},
|
||||
<<"400">> => emqx_mgmt_util:not_found_schema(<<"Node error">>, [<<"SOURCE_ERROR">>]),
|
||||
<<"200">> => emqx_mgmt_util:response_schema(<<"Get EMQ X Node Stats">>, <<"stats">>)}}},
|
||||
{"/nodes/:node_name/stats", Metadata, node_metrics}.
|
||||
|
||||
%%%==============================================================================================
|
||||
|
|
|
@ -27,85 +27,83 @@
|
|||
api_spec() ->
|
||||
{
|
||||
[publish_api(), publish_batch_api()],
|
||||
[request_message_schema(), mqtt_message_schema()]
|
||||
[message_schema()]
|
||||
}.
|
||||
|
||||
publish_api() ->
|
||||
MeteData = #{
|
||||
post => #{
|
||||
description => "publish",
|
||||
parameters => [#{
|
||||
name => message,
|
||||
in => body,
|
||||
required => true,
|
||||
schema => minirest:ref(<<"request_message">>)
|
||||
}],
|
||||
'requestBody' => #{
|
||||
content => #{
|
||||
'application/json' => #{
|
||||
schema => #{
|
||||
type => object,
|
||||
properties => maps:with([id], message_properties())}}}},
|
||||
responses => #{
|
||||
<<"200">> => #{
|
||||
description => <<"publish ok">>,
|
||||
schema => minirest:ref(<<"message">>)}}}},
|
||||
<<"200">> => emqx_mgmt_util:response_schema(<<"publish ok">>, <<"message">>)}}},
|
||||
{"/publish", MeteData, publish}.
|
||||
|
||||
publish_batch_api() ->
|
||||
MeteData = #{
|
||||
post => #{
|
||||
description => "publish",
|
||||
parameters => [#{
|
||||
name => message,
|
||||
in => body,
|
||||
required => true,
|
||||
schema =>#{
|
||||
type => array,
|
||||
items => minirest:ref(<<"request_message">>)}
|
||||
}],
|
||||
responses => #{
|
||||
<<"200">> => #{
|
||||
description => <<"publish result">>,
|
||||
'requestBody' => #{
|
||||
content => #{
|
||||
'application/json' => #{
|
||||
schema => #{
|
||||
type => array,
|
||||
items => minirest:ref(<<"message">>)}}}}},
|
||||
items => #{
|
||||
type => object,
|
||||
properties => maps:with([id], message_properties())}}}}},
|
||||
responses => #{
|
||||
<<"200">> => emqx_mgmt_util:response_array_schema(<<"publish ok">>, <<"message">>)}}},
|
||||
{"/publish_batch", MeteData, publish_batch}.
|
||||
|
||||
request_message_schema() ->
|
||||
{<<"request_message">>, maps:without([<<"id">>], message_def())}.
|
||||
|
||||
mqtt_message_schema() ->
|
||||
{<<"message">>, message_def()}.
|
||||
|
||||
message_def() ->
|
||||
message_schema() ->
|
||||
#{
|
||||
<<"id">> => #{
|
||||
type => <<"string">>,
|
||||
message => #{
|
||||
type => object,
|
||||
properties => message_properties()
|
||||
}
|
||||
}.
|
||||
|
||||
message_properties() ->
|
||||
#{
|
||||
id => #{
|
||||
type => string,
|
||||
description => <<"Message ID">>},
|
||||
<<"topic">> => #{
|
||||
type => <<"string">>,
|
||||
topic => #{
|
||||
type => string,
|
||||
description => <<"Topic">>},
|
||||
<<"qos">> => #{
|
||||
type => <<"integer">>,
|
||||
qos => #{
|
||||
type => integer,
|
||||
enum => [0, 1, 2],
|
||||
description => <<"Qos">>},
|
||||
<<"payload">> => #{
|
||||
type => <<"string">>,
|
||||
payload => #{
|
||||
type => string,
|
||||
description => <<"Topic">>},
|
||||
<<"from">> => #{
|
||||
type => <<"string">>,
|
||||
from => #{
|
||||
type => string,
|
||||
description => <<"Message from">>},
|
||||
<<"flag">> => #{
|
||||
flag => #{
|
||||
type => <<"object">>,
|
||||
description => <<"Message flag">>,
|
||||
properties => #{
|
||||
<<"sys">> => #{
|
||||
type => <<"boolean">>,
|
||||
sys => #{
|
||||
type => boolean,
|
||||
default => false,
|
||||
description => <<"System message flag, nullable, default false">>},
|
||||
<<"dup">> => #{
|
||||
type => <<"boolean">>,
|
||||
dup => #{
|
||||
type => boolean,
|
||||
default => false,
|
||||
description => <<"Dup message flag, nullable, default false">>},
|
||||
<<"retain">> => #{
|
||||
type => <<"boolean">>,
|
||||
retain => #{
|
||||
type => boolean,
|
||||
default => false,
|
||||
description => <<"Retain message flag, nullable, default false">>}}}
|
||||
description => <<"Retain message flag, nullable, default false">>}
|
||||
}
|
||||
}
|
||||
}.
|
||||
|
||||
publish(post, Request) ->
|
||||
|
|
|
@ -22,81 +22,84 @@
|
|||
-export([list/2]).
|
||||
|
||||
api_spec() ->
|
||||
{stats_api(), stats_schema()}.
|
||||
{[stats_api()], [stats_schema()]}.
|
||||
|
||||
stats_schema() ->
|
||||
DefinitionName = <<"stats">>,
|
||||
DefinitionProperties = #{
|
||||
<<"connections.count">> => #{
|
||||
type => <<"integer">>,
|
||||
#{
|
||||
stats => #{
|
||||
type => object,
|
||||
properties => #{
|
||||
'connections.count' => #{
|
||||
type => integer,
|
||||
description => <<"Number of current connections">>},
|
||||
<<"connections.max">> => #{
|
||||
type => <<"integer">>,
|
||||
'connections.max' => #{
|
||||
type => integer,
|
||||
description => <<"Historical maximum number of connections">>},
|
||||
<<"channels.count">> => #{
|
||||
type => <<"integer">>,
|
||||
'channels.count' => #{
|
||||
type => integer,
|
||||
description => <<"sessions.count">>},
|
||||
<<"channels.max">> => #{
|
||||
type => <<"integer">>,
|
||||
'channels.max' => #{
|
||||
type => integer,
|
||||
description => <<"session.max">>},
|
||||
<<"sessions.count">> => #{
|
||||
type => <<"integer">>,
|
||||
'sessions.count' => #{
|
||||
type => integer,
|
||||
description => <<"Number of current sessions">>},
|
||||
<<"sessions.max">> => #{
|
||||
type => <<"integer">>,
|
||||
'sessions.max' => #{
|
||||
type => integer,
|
||||
description => <<"Historical maximum number of sessions">>},
|
||||
<<"topics.count">> => #{
|
||||
type => <<"integer">>,
|
||||
'topics.count' => #{
|
||||
type => integer,
|
||||
description => <<"Number of current topics">>},
|
||||
<<"topics.max">> => #{
|
||||
type => <<"integer">>,
|
||||
'topics.max' => #{
|
||||
type => integer,
|
||||
description => <<"Historical maximum number of topics">>},
|
||||
<<"suboptions.count">> => #{
|
||||
type => <<"integer">>,
|
||||
'suboptions.count' => #{
|
||||
type => integer,
|
||||
description => <<"subscriptions.count">>},
|
||||
<<"suboptions.max">> => #{
|
||||
type => <<"integer">>,
|
||||
'suboptions.max' => #{
|
||||
type => integer,
|
||||
description => <<"subscriptions.max">>},
|
||||
<<"subscribers.count">> => #{
|
||||
type => <<"integer">>,
|
||||
'subscribers.count' => #{
|
||||
type => integer,
|
||||
description => <<"Number of current subscribers">>},
|
||||
<<"subscribers.max">> => #{
|
||||
type => <<"integer">>,
|
||||
'subscribers.max' => #{
|
||||
type => integer,
|
||||
description => <<"Historical maximum number of subscribers">>},
|
||||
<<"subscriptions.count">> => #{
|
||||
type => <<"integer">>,
|
||||
'subscriptions.count' => #{
|
||||
type => integer,
|
||||
description => <<"Number of current subscriptions, including shared subscriptions">>},
|
||||
<<"subscriptions.max">> => #{
|
||||
type => <<"integer">>,
|
||||
'subscriptions.max' => #{
|
||||
type => integer,
|
||||
description => <<"Historical maximum number of subscriptions">>},
|
||||
<<"subscriptions.shared.count">> => #{
|
||||
type => <<"integer">>,
|
||||
'subscriptions.shared.count' => #{
|
||||
type => integer,
|
||||
description => <<"Number of current shared subscriptions">>},
|
||||
<<"subscriptions.shared.max">> => #{
|
||||
type => <<"integer">>,
|
||||
'subscriptions.shared.max' => #{
|
||||
type => integer,
|
||||
description => <<"Historical maximum number of shared subscriptions">>},
|
||||
<<"routes.count">> => #{
|
||||
type => <<"integer">>,
|
||||
'routes.count' => #{
|
||||
type => integer,
|
||||
description => <<"Number of current routes">>},
|
||||
<<"routes.max">> => #{
|
||||
type => <<"integer">>,
|
||||
'routes.max' => #{
|
||||
type => integer,
|
||||
description => <<"Historical maximum number of routes">>},
|
||||
<<"retained.count">> => #{
|
||||
type => <<"integer">>,
|
||||
'retained.count' => #{
|
||||
type => integer,
|
||||
description => <<"Number of currently retained messages">>},
|
||||
<<"retained.max">> => #{
|
||||
type => <<"integer">>,
|
||||
description => <<"Historical maximum number of retained messages">>}},
|
||||
[{DefinitionName, DefinitionProperties}].
|
||||
'retained.max' => #{
|
||||
type => integer,
|
||||
description => <<"Historical maximum number of retained messages">>}
|
||||
}
|
||||
}
|
||||
}.
|
||||
|
||||
stats_api() ->
|
||||
Metadata = #{
|
||||
get => #{
|
||||
description => "EMQ X stats",
|
||||
responses => #{
|
||||
<<"200">> => #{
|
||||
schema => cowboy_swagger:schema(<<"stats">>)}}}},
|
||||
[{"/stats", Metadata, list}].
|
||||
<<"200">> => emqx_mgmt_util:response_schema(<<"List stats ok">>, <<"stats">>)}}},
|
||||
{"/stats", Metadata, list}.
|
||||
|
||||
%%%==============================================================================================
|
||||
%% api apply
|
||||
|
|
|
@ -44,14 +44,16 @@ start_listener({Proto, Port, Options}) ->
|
|||
Authorization = {?MODULE, authorize_appid},
|
||||
RanchOptions = ranch_opts(Port, Options),
|
||||
GlobalSpec = #{
|
||||
swagger => "2.0",
|
||||
openapi => "3.0.0",
|
||||
info => #{title => "EMQ X API", version => "5.0.0"},
|
||||
basePath => ?BASE_PATH,
|
||||
securityDefinitions => #{
|
||||
servers => [#{url => ?BASE_PATH}],
|
||||
components => #{
|
||||
schemas => #{},
|
||||
securitySchemes => #{
|
||||
application => #{
|
||||
type => apiKey,
|
||||
name => "authorization",
|
||||
in => header}}},
|
||||
in => header}}}},
|
||||
Minirest = #{
|
||||
protocol => Proto,
|
||||
base_path => ?BASE_PATH,
|
||||
|
|
|
@ -24,7 +24,12 @@
|
|||
, batch_operation/3
|
||||
]).
|
||||
|
||||
-export([ not_found_schema/1
|
||||
-export([ request_body_schema/1
|
||||
, request_body_array_schema/1
|
||||
, response_schema/1
|
||||
, response_schema/2
|
||||
, response_array_schema/2
|
||||
, not_found_schema/1
|
||||
, not_found_schema/2
|
||||
, batch_response_schema/1]).
|
||||
|
||||
|
@ -84,24 +89,46 @@ urldecode(S) ->
|
|||
|
||||
%%%==============================================================================================
|
||||
%% schema util
|
||||
|
||||
request_body_array_schema(Schema) when is_map(Schema) ->
|
||||
json_content_schema("", #{type => array, items => Schema});
|
||||
request_body_array_schema(Ref) when is_binary(Ref) ->
|
||||
json_content_schema("", #{type => array, items => minirest:ref(Ref)}).
|
||||
|
||||
request_body_schema(Schema) when is_map(Schema) ->
|
||||
json_content_schema("", Schema);
|
||||
request_body_schema(Ref) when is_binary(Ref) ->
|
||||
json_content_schema("", minirest:ref(Ref)).
|
||||
|
||||
response_array_schema(Description, Schema) when is_map(Schema) ->
|
||||
json_content_schema(Description, #{type => array, items => Schema});
|
||||
response_array_schema(Description, Ref) when is_binary(Ref) ->
|
||||
json_content_schema(Description, #{type => array, items => minirest:ref(Ref)}).
|
||||
|
||||
response_schema(Description) ->
|
||||
json_content_schema(Description).
|
||||
|
||||
response_schema(Description, Schema) when is_map(Schema) ->
|
||||
json_content_schema(Description, Schema);
|
||||
response_schema(Description, Ref) when is_binary(Ref) ->
|
||||
json_content_schema(Description, minirest:ref(Ref)).
|
||||
|
||||
not_found_schema(Description) ->
|
||||
not_found_schema(Description, ["RESOURCE_NOT_FOUND"]).
|
||||
|
||||
not_found_schema(Description, Enum) ->
|
||||
#{
|
||||
description => Description,
|
||||
schema => #{
|
||||
Schema = #{
|
||||
type => object,
|
||||
properties => #{
|
||||
code => #{
|
||||
type => string,
|
||||
enum => Enum},
|
||||
reason => #{
|
||||
type => string}}}
|
||||
}.
|
||||
type => string}}},
|
||||
json_content_schema(Description, Schema).
|
||||
|
||||
batch_response_schema(DefName) ->
|
||||
#{
|
||||
batch_response_schema(DefName) when is_binary(DefName) ->
|
||||
Schema = #{
|
||||
type => object,
|
||||
properties => #{
|
||||
success => #{
|
||||
|
@ -119,13 +146,23 @@ batch_response_schema(DefName) ->
|
|||
#{
|
||||
data => minirest:ref(DefName),
|
||||
reason => #{
|
||||
type => <<"string">>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.
|
||||
type => <<"string">>}}}}}},
|
||||
json_content_schema("", Schema).
|
||||
|
||||
json_content_schema(Description, Schema) ->
|
||||
Content =
|
||||
#{content => #{
|
||||
'application/json' => #{
|
||||
schema => Schema}}},
|
||||
case Description of
|
||||
"" ->
|
||||
Content;
|
||||
_ ->
|
||||
maps:merge(#{description => Description}, Content)
|
||||
end.
|
||||
|
||||
json_content_schema(Description) ->
|
||||
#{description => Description}.
|
||||
|
||||
%%%==============================================================================================
|
||||
batch_operation(Module, Function, ArgsList) ->
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
, {ekka, {git, "https://github.com/emqx/ekka", {tag, "0.10.3"}}}
|
||||
, {gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "2.5.1"}}}
|
||||
, {cuttlefish, {git, "https://github.com/emqx/cuttlefish", {tag, "v4.0.1"}}} % TODO: delete when all apps moved to hocon
|
||||
, {minirest, {git, "https://github.com/emqx/minirest", {tag, "1.1.1"}}}
|
||||
, {minirest, {git, "https://github.com/emqx/minirest", {tag, "1.1.2"}}}
|
||||
, {ecpool, {git, "https://github.com/emqx/ecpool", {tag, "0.5.1"}}}
|
||||
, {replayq, {git, "https://github.com/emqx/replayq", {tag, "0.3.2"}}}
|
||||
, {pbkdf2, {git, "https://github.com/emqx/erlang-pbkdf2.git", {tag, "2.0.4"}}}
|
||||
|
|
Loading…
Reference in New Issue