diff --git a/apps/endpoint/src/endpoint.app.src b/apps/endpoint/src/endpoint.app.src index e2cf43a..ac0ecb8 100644 --- a/apps/endpoint/src/endpoint.app.src +++ b/apps/endpoint/src/endpoint.app.src @@ -2,8 +2,8 @@ [{description, "Endpoint OTP application"}, {vsn, "0.1.0"}, {registered, [ - endpoint_sup_sup, endpoint_sup, + endpoint_adapter_sup, endpoint_subscription, endpoint_log ]}, diff --git a/apps/endpoint/src/endpoint_adapter_sup.erl b/apps/endpoint/src/endpoint_adapter_sup.erl new file mode 100644 index 0000000..a64f319 --- /dev/null +++ b/apps/endpoint/src/endpoint_adapter_sup.erl @@ -0,0 +1,88 @@ +%%%------------------------------------------------------------------- +%% @doc endpoint top level supervisor. +%% @end +%%%------------------------------------------------------------------- + +-module(endpoint_adapter_sup). + +-behaviour(supervisor). +-include("endpoint.hrl"). + +-export([start_link/0]). +-export([ensured_endpoint_started/1, delete_endpoint/1]). + +-export([init/1]). + +-define(SERVER, ?MODULE). + +start_link() -> + supervisor:start_link({local, ?SERVER}, ?MODULE, []). + +%% sup_flags() = #{strategy => strategy(), % optional +%% intensity => non_neg_integer(), % optional +%% period => pos_integer()} % optional +%% child_spec() = #{id => child_id(), % mandatory +%% start => mfargs(), % mandatory +%% restart => restart(), % optional +%% shutdown => shutdown(), % optional +%% type => worker(), % optional +%% modules => modules()} % optional +init([]) -> + SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, + Endpoints = iot_api_client:get_all_endpoints(), + ChildSpecs = lists:filtermap(fun(EndpointInfo) -> + case endpoint:endpoint_record(EndpointInfo) of + error -> + false; + {ok, Endpoint} -> + case endpoint:is_support(endpoint:get_protocol(Endpoint)) of + true -> + {true, child_spec(Endpoint)}; + false -> + false + end + end + end, Endpoints), + {ok, {SupFlags, ChildSpecs}}. + +-spec ensured_endpoint_started(Endpoint :: #endpoint{}) -> {ok, Pid :: pid()} | {error, Reason :: any()}. +ensured_endpoint_started(Endpoint = #endpoint{}) -> + case supervisor:start_child(?MODULE, child_spec(Endpoint)) of + {ok, Pid} when is_pid(Pid) -> + {ok, Pid}; + {error, {'already_started', Pid}} when is_pid(Pid) -> + {ok, Pid}; + {error, Error} -> + {error, Error} + end. + +-spec delete_endpoint(Id :: integer()) -> ok | {error, Reason :: any()}. +delete_endpoint(Id) when is_integer(Id) -> + Name = endpoint:get_name(Id), + case supervisor:terminate_child(?MODULE, Name) of + ok -> + delete_endpoint_child(Name); + {error, not_found} -> + delete_endpoint_child(Name); + {error, Reason} -> + {error, Reason} + end. + +delete_endpoint_child(Name) -> + case supervisor:delete_child(?MODULE, Name) of + ok -> + ok; + {error, not_found} -> + ok; + {error, Reason} -> + {error, Reason} + end. + +child_spec(Endpoint = #endpoint{id = Id}) -> + Name = endpoint:get_name(Id), + #{id => Name, + start => {endpoint, start_link, [Endpoint]}, + restart => permanent, + shutdown => 2000, + type => worker, + modules => ['endpoint']}. diff --git a/apps/endpoint/src/endpoint_app.erl b/apps/endpoint/src/endpoint_app.erl index 78cc3e4..d86e2a7 100644 --- a/apps/endpoint/src/endpoint_app.erl +++ b/apps/endpoint/src/endpoint_app.erl @@ -9,7 +9,7 @@ -export([start/2, stop/1]). start(_StartType, _StartArgs) -> - endpoint_sup_sup:start_link(). + endpoint_sup:start_link(). stop(_State) -> ok. diff --git a/apps/endpoint/src/endpoint_sup.erl b/apps/endpoint/src/endpoint_sup.erl index cd5c554..8bdfe89 100644 --- a/apps/endpoint/src/endpoint_sup.erl +++ b/apps/endpoint/src/endpoint_sup.erl @@ -9,8 +9,6 @@ -include("endpoint.hrl"). -export([start_link/0]). --export([ensured_endpoint_started/1, delete_endpoint/1]). - -export([init/1]). -define(SERVER, ?MODULE). @@ -28,61 +26,33 @@ start_link() -> %% type => worker(), % optional %% modules => modules()} % optional init([]) -> - SupFlags = #{strategy => one_for_one, intensity => 1000, period => 3600}, - Endpoints = iot_api_client:get_all_endpoints(), - ChildSpecs = lists:filtermap(fun(EndpointInfo) -> - case endpoint:endpoint_record(EndpointInfo) of - error -> - false; - {ok, Endpoint} -> - case endpoint:is_support(endpoint:get_protocol(Endpoint)) of - true -> - {true, child_spec(Endpoint)}; - false -> - false - end - end - end, Endpoints), + SupFlags = #{strategy => one_for_all, intensity => 1000, period => 3600}, + ChildSpecs = [ + #{ + id => endpoint_log, + start => {'endpoint_log', start_link, []}, + restart => permanent, + shutdown => 2000, + type => worker, + modules => ['endpoint_log'] + }, + + #{ + id => endpoint_subscription, + start => {'endpoint_subscription', start_link, []}, + restart => permanent, + shutdown => 2000, + type => worker, + modules => ['endpoint_subscription'] + }, + + #{ + id => 'endpoint_adapter_sup', + start => {'endpoint_adapter_sup', start_link, []}, + restart => permanent, + shutdown => 2000, + type => supervisor, + modules => ['endpoint_adapter_sup'] + } + ], {ok, {SupFlags, ChildSpecs}}. - --spec ensured_endpoint_started(Endpoint :: #endpoint{}) -> {ok, Pid :: pid()} | {error, Reason :: any()}. -ensured_endpoint_started(Endpoint = #endpoint{}) -> - case supervisor:start_child(?MODULE, child_spec(Endpoint)) of - {ok, Pid} when is_pid(Pid) -> - {ok, Pid}; - {error, {'already_started', Pid}} when is_pid(Pid) -> - {ok, Pid}; - {error, Error} -> - {error, Error} - end. - --spec delete_endpoint(Id :: integer()) -> ok | {error, Reason :: any()}. -delete_endpoint(Id) when is_integer(Id) -> - Name = endpoint:get_name(Id), - case supervisor:terminate_child(?MODULE, Name) of - ok -> - delete_endpoint_child(Name); - {error, not_found} -> - delete_endpoint_child(Name); - {error, Reason} -> - {error, Reason} - end. - -delete_endpoint_child(Name) -> - case supervisor:delete_child(?MODULE, Name) of - ok -> - ok; - {error, not_found} -> - ok; - {error, Reason} -> - {error, Reason} - end. - -child_spec(Endpoint = #endpoint{id = Id}) -> - Name = endpoint:get_name(Id), - #{id => Name, - start => {endpoint, start_link, [Endpoint]}, - restart => permanent, - shutdown => 2000, - type => worker, - modules => ['endpoint']}. diff --git a/apps/endpoint/src/endpoint_sup_sup.erl b/apps/endpoint/src/endpoint_sup_sup.erl deleted file mode 100644 index 2d4ee48..0000000 --- a/apps/endpoint/src/endpoint_sup_sup.erl +++ /dev/null @@ -1,58 +0,0 @@ -%%%------------------------------------------------------------------- -%% @doc endpoint top level supervisor. -%% @end -%%%------------------------------------------------------------------- - --module(endpoint_sup_sup). - --behaviour(supervisor). --include("endpoint.hrl"). - --export([start_link/0]). --export([init/1]). - --define(SERVER, ?MODULE). - -start_link() -> - supervisor:start_link({local, ?SERVER}, ?MODULE, []). - -%% sup_flags() = #{strategy => strategy(), % optional -%% intensity => non_neg_integer(), % optional -%% period => pos_integer()} % optional -%% child_spec() = #{id => child_id(), % mandatory -%% start => mfargs(), % mandatory -%% restart => restart(), % optional -%% shutdown => shutdown(), % optional -%% type => worker(), % optional -%% modules => modules()} % optional -init([]) -> - SupFlags = #{strategy => one_for_all, intensity => 1000, period => 3600}, - ChildSpecs = [ - #{ - id => endpoint_log, - start => {'endpoint_log', start_link, []}, - restart => permanent, - shutdown => 2000, - type => worker, - modules => ['endpoint_log'] - }, - - #{ - id => endpoint_subscription, - start => {'endpoint_subscription', start_link, []}, - restart => permanent, - shutdown => 2000, - type => worker, - modules => ['endpoint_subscription'] - }, - - #{ - id => 'endpoint_sup', - start => {'endpoint_sup', start_link, []}, - restart => permanent, - shutdown => 2000, - type => supervisor, - modules => ['endpoint_sup'] - } - ], - {ok, {SupFlags, ChildSpecs}}. diff --git a/apps/iot/src/http/endpoint_handler.erl b/apps/iot/src/http/endpoint_handler.erl index d500bba..25b6f3c 100644 --- a/apps/iot/src/http/endpoint_handler.erl +++ b/apps/iot/src/http/endpoint_handler.erl @@ -36,7 +36,7 @@ handle_request("POST", "/endpoint/start", _, #{<<"id">> := Id}) when is_integer( {ok, EndpointInfo} -> case endpoint:endpoint_record(EndpointInfo) of {ok, Endpoint = #endpoint{title = Title}} -> - case endpoint_sup:ensured_endpoint_started(Endpoint) of + case endpoint_adapter_sup:ensured_endpoint_started(Endpoint) of {ok, Pid} when is_pid(Pid) -> {ok, 200, iot_util:json_data(<<"success">>)}; {error, Reason} -> @@ -53,7 +53,7 @@ handle_request("POST", "/endpoint/stop", _, #{<<"id">> := Id}) when is_integer(I undefined -> {ok, 200, iot_util:json_error(404, <<"endpoint not found">>)}; {ok, _} -> - case endpoint_sup:delete_endpoint(Id) of + case endpoint_adapter_sup:delete_endpoint(Id) of ok -> {ok, 200, iot_util:json_data(<<"success">>)}; {error, Reason} -> @@ -71,7 +71,7 @@ handle_request("POST", "/endpoint/restart", _, #{<<"id">> := Id}) when is_intege {ok, Endpoint = #endpoint{title = Title}} -> case endpoint:get_pid(Id) of undefined -> - case endpoint_sup:ensured_endpoint_started(Endpoint) of + case endpoint_adapter_sup:ensured_endpoint_started(Endpoint) of {ok, Pid} when is_pid(Pid) -> {ok, 200, iot_util:json_data(<<"success">>)}; {error, Reason} -> @@ -79,9 +79,9 @@ handle_request("POST", "/endpoint/restart", _, #{<<"id">> := Id}) when is_intege {ok, 200, iot_util:json_error(404, <<"restart endpoint error">>)} end; Pid when is_pid(Pid) -> - case endpoint_sup:delete_endpoint(Id) of + case endpoint_adapter_sup:delete_endpoint(Id) of ok -> - case endpoint_sup:ensured_endpoint_started(Endpoint) of + case endpoint_adapter_sup:ensured_endpoint_started(Endpoint) of {ok, Pid0} when is_pid(Pid0) -> {ok, 200, iot_util:json_data(<<"success">>)}; {error, Reason} -> diff --git a/rebar.config b/rebar.config index 944dc63..eda5425 100644 --- a/rebar.config +++ b/rebar.config @@ -1,4 +1,4 @@ -{erl_opts, [debug_info, {i, "include"}]}. +{erl_opts, [debug_info, {i, "apps/iot/include"}, {i, "apps/endpoint/include"}]}. {project_app_dirs, ["apps/*"]}.