From b950042cbfaed60fb906ba00a061d041a03d81a6 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Thu, 20 Jan 2022 16:35:05 +0800 Subject: [PATCH] refactor(api): prometheus swagger spec --- .../src/emqx_dashboard_swagger.erl | 17 +++ .../src/emqx_topic_metrics_api.erl | 1 + .../src/emqx_prometheus_api.erl | 105 ++++++++++++------ .../src/emqx_prometheus_schema.erl | 6 +- 4 files changed, 92 insertions(+), 37 deletions(-) diff --git a/apps/emqx_dashboard/src/emqx_dashboard_swagger.erl b/apps/emqx_dashboard/src/emqx_dashboard_swagger.erl index 1fbdb9eca..802bde288 100644 --- a/apps/emqx_dashboard/src/emqx_dashboard_swagger.erl +++ b/apps/emqx_dashboard/src/emqx_dashboard_swagger.erl @@ -1,3 +1,19 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2021-2022 EMQ Technologies Co., Ltd. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%%-------------------------------------------------------------------- + -module(emqx_dashboard_swagger). -include_lib("typerefl/include/types.hrl"). @@ -313,6 +329,7 @@ responses(Responses, Module) -> response(Status, Bin, {Acc, RefsAcc, Module}) when is_binary(Bin) -> {Acc#{integer_to_binary(Status) => #{description => Bin}}, RefsAcc, Module}; %% Support swagger raw object(file download). +%% TODO: multi type response(i.e. Support both 'application/json' and 'plain/text') response(Status, #{content := _} = Content, {Acc, RefsAcc, Module}) -> {Acc#{integer_to_binary(Status) => Content}, RefsAcc, Module}; response(Status, ?REF(StructName), {Acc, RefsAcc, Module}) -> diff --git a/apps/emqx_modules/src/emqx_topic_metrics_api.erl b/apps/emqx_modules/src/emqx_topic_metrics_api.erl index 24c516f60..76419d4af 100644 --- a/apps/emqx_modules/src/emqx_topic_metrics_api.erl +++ b/apps/emqx_modules/src/emqx_topic_metrics_api.erl @@ -45,6 +45,7 @@ -define(BAD_TOPIC, 'BAD_TOPIC'). -define(BAD_RPC, 'BAD_RPC'). -define(BAD_REQUEST, 'BAD_REQUEST'). + -define(API_TAG_MQTT, [<<"mqtt">>]). diff --git a/apps/emqx_prometheus/src/emqx_prometheus_api.erl b/apps/emqx_prometheus/src/emqx_prometheus_api.erl index c129b1064..4b19c9665 100644 --- a/apps/emqx_prometheus/src/emqx_prometheus_api.erl +++ b/apps/emqx_prometheus/src/emqx_prometheus_api.erl @@ -20,48 +20,56 @@ -include("emqx_prometheus.hrl"). --import(emqx_mgmt_util, [ schema/1]). +-import(hoconsc, [ref/2]). --export([api_spec/0]). +-export([ api_spec/0 + , paths/0 + , schema/1 + ]). -export([ prometheus/2 , stats/2 ]). +-define(API_TAG_PROMETHEUS, [<<"premetheus">>]). +-define(SCHEMA_MODULE, emqx_prometheus_schema). + + api_spec() -> - {[prometheus_api(), prometheus_data_api()], []}. + emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true}). -conf_schema() -> - emqx_mgmt_api_configs:gen_schema(emqx:get_raw_config([prometheus])). +paths() -> + [ "/prometheus" + , "/prometheus/stats" + ]. -prometheus_api() -> - Metadata = #{ - get => #{ - description => <<"Get Prometheus info">>, - responses => #{<<"200">> => schema(conf_schema())} - }, - put => #{ - description => <<"Update Prometheus">>, - 'requestBody' => schema(conf_schema()), - responses => #{<<"200">> => schema(conf_schema())} - } - }, - {"/prometheus", Metadata, prometheus}. - -prometheus_data_api() -> - Metadata = #{ - get => #{ - description => <<"Get Prometheus Data">>, - responses => #{<<"200">> => - #{content => - #{ - 'application/json' => #{schema => #{type => object}}, - 'text/plain' => #{schema => #{type => string}} - }} +schema("/prometheus") -> + #{ 'operationId' => prometheus + , get => + #{ description => <<"Get Prometheus config info">> + , tags => ?API_TAG_PROMETHEUS + , responses => + #{200 => prometheus_config_schema()} } - } - }, - {"/prometheus/stats", Metadata, stats}. + , put => + #{ description => <<"Update Prometheus config">> + , 'requestBody' => prometheus_config_schema() + , responses => + #{200 => prometheus_config_schema()} + } + }; +schema("/prometheus/stats") -> + #{ 'operationId' => stats + , get => + #{ description => <<"Get Prometheus Data">> + , responses => + #{200 => prometheus_data_schema()} + } + }. + +%%-------------------------------------------------------------------- +%% API Handler funcs +%%-------------------------------------------------------------------- prometheus(get, _Params) -> {200, emqx:get_raw_config([<<"prometheus">>], #{})}; @@ -83,6 +91,35 @@ stats(get, #{headers := Headers}) -> end, Data = emqx_prometheus:collect(Type), case Type of - <<"json">> -> {200, Data}; - <<"prometheus">> -> {200, #{<<"content-type">> => <<"text/plain">>}, Data} + <<"json">> -> + {200, Data}; + <<"prometheus">> -> + {200, #{<<"content-type">> => <<"text/plain">>}, Data} end. + +%%-------------------------------------------------------------------- +%% Internal funcs +%%-------------------------------------------------------------------- + +prometheus_config_schema() -> + emqx_dashboard_swagger:schema_with_example( + ref(?SCHEMA_MODULE, "prometheus"), + prometheus_config_example()). + +prometheus_config_example() -> + #{ enable => true + , interval => "15s" + , push_gateway_server => <<"http://127.0.0.1:9091">> + }. + +prometheus_data_schema() -> + #{ description => <<"Get Prometheus Data">> + , content => + #{ 'application/json' => + #{ schema => #{type => object} + , description => <<"Prometheus Data in json">>} + , 'text/plain' => + #{ schema => #{type => string} + , description => <<"Prometheus Data in text/plain">>} + } + }. diff --git a/apps/emqx_prometheus/src/emqx_prometheus_schema.erl b/apps/emqx_prometheus/src/emqx_prometheus_schema.erl index ba05237cc..9d7455bdf 100644 --- a/apps/emqx_prometheus/src/emqx_prometheus_schema.erl +++ b/apps/emqx_prometheus/src/emqx_prometheus_schema.erl @@ -28,9 +28,9 @@ namespace() -> "prometheus". roots() -> ["prometheus"]. fields("prometheus") -> - [ {push_gateway_server, sc(string(), #{})} - , {interval, sc(emqx_schema:duration_ms(), #{default => "15s"})} - , {enable, sc(boolean(), #{default => false})} + [ {push_gateway_server, sc(string(), #{default => "http://127.0.0.1:9091", nullabel => false})} + , {interval, sc(emqx_schema:duration_ms(), #{default => "15s", nullabel => false})} + , {enable, sc(boolean(), #{default => false, nullabel => false})} ]. sc(Type, Meta) -> hoconsc:mk(Type, Meta).