Current section

Files

Jump to
broen src broen_app.erl
Raw

src/broen_app.erl

%%% ---------------------------------------------------------------------------------
%%% @private
%%% @doc
%%% The main application module
%%% @end
%%% ---------------------------------------------------------------------------------
-module(broen_app).
-behaviour(application).
%% Application callbacks
-export([start/2, stop/1]).
%% Application callbacks
%% ---------------------------------------------------------------------------------
start(_StartType, _StartArgs) ->
broen_core:register_metrics(),
{ok, Pid} = broen_sup:start_link(),
start_cowboy(),
{ok, Pid}.
stop(_State) ->
ok.
%% Internal functions
%% ---------------------------------------------------------------------------------
start_cowboy() ->
Defaults = maps:merge(
#{
keep_dots_in_routing_keys => false,
num_acceptors => 10,
max_connections => 1024},
application:get_env(broen, defaults, #{})),
{ok, Servers} = application:get_env(broen, servers),
lists:foreach(fun (Server) -> start_server(Server, Defaults) end, maps:to_list(Servers)).
start_server({ServerName, #{paths := Paths} = Server}, Defaults) ->
Port = conf(port, [Server, Defaults]),
NumAcceptors = conf(num_acceptors, [Server, Defaults]),
MaxConns = conf(max_connections, [Server, Defaults]),
Routes = make_paths(maps:to_list(Paths), [Server, Defaults]),
Dispatch = cowboy_router:compile([{'_', Routes}]),
CowboyOpts = maps:merge(#{
env => #{dispatch => Dispatch},
stream_handlers => [cowboy_compress_h, cowboy_stream_h]
}, conf_default(cowboy_opts, [Server, Defaults], #{})),
{ok, _} = cowboy:start_clear(
ServerName,
[{num_acceptors, NumAcceptors}, {max_connections, MaxConns}, {port, Port}],
CowboyOpts),
ok.
make_paths([], _) -> [];
make_paths([{Path, Conf}|Rest], Defaults) ->
[compile_route(Path, [Conf | Defaults]) | make_paths(Rest, Defaults)].
compile_route(Path, Conf) ->
HandlerOpts = #{
exchange => exchange_name(Conf),
serializer_mod => conf(serializer_mod, Conf),
auth_mod => conf(auth_mod, Conf),
partial_post_size => conf(max_multipart_size, Conf),
timeout => conf(timeout, Conf),
keep_dots_in_routing_keys => conf(keep_dots_in_routing_keys, Conf)
},
{iolist_to_binary([Path, <<"/[...]">>]), broen_mod, HandlerOpts}.
exchange_name(Confs) ->
case conf(exchange, Confs) of
#{name := Exch} -> Exch;
Exch -> Exch
end.
conf(Key, Envs) ->
case conf_default(Key, Envs, not_found) of
not_found -> throw({configuration_missing, Key});
Res -> Res
end.
conf_default(_, [], Default) -> Default;
conf_default(Key, [HD|Rest], Default) ->
case maps:is_key(Key, HD) of
true -> maps:get(Key, HD);
false -> conf_default(Key, Rest, Default)
end.