Skip to content

Commit

Permalink
CAPI-23 Add specs to shut up dialyzer and add some minor code refacto…
Browse files Browse the repository at this point in the history
…ring
  • Loading branch information
galaxie committed Aug 29, 2016
1 parent f63d505 commit 97dfb92
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
-export([populate_request/3]).
-export([validate_response/4]).


-spec request_params(OperationID :: atom()) -> [Param :: atom()].
{{#apiInfo}}{{#apis}}
{{#operations}}{{#operation}}
request_params('{{operationId}}') ->
Expand All @@ -17,6 +17,11 @@ request_params('{{operationId}}') ->
request_params(_) ->
error(unknown_operation).

-spec request_param_info(OperationID :: atom(), Name :: atom()) -> #{
source => qs_val | binding | header | body,
rules => [any()]
}.

{{#apiInfo}}{{#apis}}
{{#operations}}{{#operation}}{{#allParams}}
request_param_info('{{operationId}}', {{^isBodyParam}}'{{baseName}}'{{/isBodyParam}}{{#isBodyParam}}'{{dataType}}'{{/isBodyParam}}) ->
Expand Down Expand Up @@ -50,6 +55,9 @@ request_param_info('{{operationId}}', {{^isBodyParam}}'{{baseName}}'{{/isBodyPar
request_param_info(OperationID, Name) ->
error({unknown_param, OperationID, Name}).

-spec populate_request(OperationID :: atom(), Req :: cowboy_req:req(), ValidatorState :: jesse_state:state())
-> {ok, Model :: #{}, Req :: cowboy_req:req()} | {error, Reason :: any(), Req :: cowboy_req:req()}.

populate_request(OperationID, Req, ValidatorState) ->
Params = request_params(OperationID),
populate_request_params(OperationID, Params, Req, ValidatorState, #{}).
Expand All @@ -74,7 +82,12 @@ populate_request_param(OperationID, Name, Req0, ValidatorState) ->
{error, Reason, Req}
end.


-spec validate_response(
OperationID :: atom(),
Code :: integer(),
Body :: binary(),
ValidatorState :: jesse_state:state()
) -> ok | no_return().
{{#apiInfo}}{{#apis}}
{{#operations}}{{#operation}}
{{#responses}}
Expand All @@ -86,12 +99,6 @@ validate_response('{{operationId}}', {{code}}, Body, ValidatorState) ->
validate_response(_OperationID, _Code, _Body, _ValidatorState) ->
ok.

validate_response_body(undefined, _, Body, _) ->
case Body of
#{} -> ok;
_ -> throw(invalid_response)
end;

validate_response_body('list', ReturnBaseType, Body, ValidatorState) ->
[
validate(schema, ReturnBaseType, Item, ValidatorState)
Expand Down Expand Up @@ -220,7 +227,7 @@ validate( Rule = {pattern, Pattern}, Name, Value, _ValidatorState) ->
validate( Rule = schema, Name, Value, ValidatorState) ->
Definition = list_to_binary("#/definitions/" ++ {{packageName}}_utils:to_list(Name)),
try
validate_with_schema(Value, Definition, ValidatorState),
_ = validate_with_schema(Value, Definition, ValidatorState),
ok
catch
throw:[{schema_invalid, _, Error} | _] ->
Expand All @@ -243,9 +250,13 @@ validate(Rule, Name, Value, _ValidatorState) ->
io:format("Skipping unknown validation: ~p~n", [{Rule, Name, Value}]),
ok.

-spec validation_error(Rule :: any(), Name :: any()) -> no_return().

validation_error(ViolatedRule, Name) ->
validation_error(ViolatedRule, Name, #{}).

-spec validation_error(Rule :: any(), Name :: any(), Info :: #{}) -> no_return().

validation_error(ViolatedRule, Name, Info) ->
throw({wrong_param, Name, ViolatedRule, Info}).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

-export([authorize_api_key/5]).

-spec authorize_api_key(
From :: header | qs_val,
KeyParam :: iodata() | atom(),
OperationID :: atom(),
Req ::cowboy_req:req(),
LogicHandler :: atom())
-> {true, Context :: #{binary() => any()}, Req ::cowboy_req:req()} |
{false, AuthHeader :: binary(), Req ::cowboy_req:req()}.

authorize_api_key(From, KeyParam, OperationID, Req0, LogicHandler) ->
{ApiKey, Req} = get_api_key(From, KeyParam, Req0),
case ApiKey of
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@

{{#authMethods}}
{{#isApiKey}}
-spec authorize_api_key(ApiKey :: binary(), OperationID :: atom()) -> {true, #{}}.

authorize_api_key(_, _) -> {true, #{}}.
{{/isApiKey}}
{{/authMethods}}

-spec handle_request(OperationID :: atom(), Req :: cowboy_req:req(), Context :: #{})
-> {Code :: integer(), Headers :: [], Body :: binary()}.

handle_request(OperationID, Req, Context) ->
io:format(user, "Got request to process: ~p~n", [{OperationID, Req, Context}]),
{501, [], <<"Not Implemented">>}.
Message = io_lib:format("Got not implemented request to process: ~p~n", [{OperationID, Req, Context}]),
error_logger:info_msg(Message),
{501, [], <<"">>}.
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,23 @@
-export([handle_request_json/2]).

-record(state, {
operation_id,
logic_handler,
validator_state,
context=#{}
operation_id :: atom(),
logic_handler :: atom(),
validator_state :: jesse_state:state(),
context=#{} :: #{}
}).

-type init_opts() :: [any()].

-spec init(TransportName :: atom(), Req :: cowboy_req:req(), Opts :: init_opts())
-> {upgrade, protocol, cowboy_rest, Req :: cowboy_req:req(), Opts :: init_opts()}.

init(_Transport, Req, Opts) ->
{upgrade, protocol, cowboy_rest, Req, Opts}.

-spec rest_init(Req :: cowboy_req:req(), Opts :: init_opts())
-> {ok, Req :: cowboy_req:req(), State :: #state{}}.

rest_init(Req0, [Operations, LogicHandler, ValidatorState]) ->
{Method, Req} = cowboy_req:method(Req0),
OperationID = maps:get(Method, Operations, undefined),
Expand All @@ -42,13 +50,18 @@ rest_init(Req0, [Operations, LogicHandler, ValidatorState]) ->
},
{ok, Req, State}.

-spec allowed_methods(Req :: cowboy_req:req(), State :: #state{})
-> {Value :: any(), Req :: cowboy_req:req(), State :: #state{}}.

{{#operations}}{{#operation}}
allowed_methods(Req, State = #state{operation_id = '{{operationId}}'}) ->
{[<<"{{httpMethod}}">>], Req, State};
{{/operation}}{{/operations}}
allowed_methods(Req, State) ->
{[], Req, State}.

-spec is_authorized(Req :: cowboy_req:req(), State :: #state{})
-> {Value :: any(), Req :: cowboy_req:req(), State :: #state{}}.
{{#operations}}{{#operation}}
is_authorized(Req0, State = #state{operation_id = '{{operationId}}' = OperationID, logic_handler = LogicHandler}) ->
{{#authMethods}}
Expand All @@ -64,11 +77,15 @@ is_authorized(Req0, State = #state{operation_id = '{{operationId}}' = OperationI
is_authorized(Req, State) ->
{{false, <<"">>}, Req, State}.

-spec content_types_accepted(Req :: cowboy_req:req(), State :: #state{})
-> {Value :: any(), Req :: cowboy_req:req(), State :: #state{}}.
content_types_accepted(Req, State) ->
{[
{<<"application/json">>, handle_request_json}
], Req, State}.

-spec valid_content_headers(Req :: cowboy_req:req(), State :: #state{})
-> {Value :: any(), Req :: cowboy_req:req(), State :: #state{}}.
{{#operations}}{{#operation}}
valid_content_headers(Req0, State = #state{operation_id = '{{operationId}}'}) ->
Headers = [{{#headerParams}}"{{baseName}}"{{#hasMore}},{{/hasMore}}{{/headerParams}}],
Expand All @@ -78,36 +95,55 @@ valid_content_headers(Req0, State = #state{operation_id = '{{operationId}}'}) ->
valid_content_headers(Req, State) ->
{false, Req, State}.

-spec content_types_provided(Req :: cowboy_req:req(), State :: #state{})
-> {Value :: any(), Req :: cowboy_req:req(), State :: #state{}}.

content_types_provided(Req, State) ->
{[
{<<"application/json">>, handle_request_json}
], Req, State}.

-spec malformed_request(Req :: cowboy_req:req(), State :: #state{})
-> {Value :: any(), Req :: cowboy_req:req(), State :: #state{}}.

malformed_request(Req, State) ->
{false, Req, State}.

-spec allow_missing_post(Req :: cowboy_req:req(), State :: #state{})
-> {Value :: any(), Req :: cowboy_req:req(), State :: #state{}}.

allow_missing_post(Req, State) ->
{false, Req, State}.

-spec delete_resource(Req :: cowboy_req:req(), State :: #state{})
-> {Value :: any(), Req :: cowboy_req:req(), State :: #state{}}.

delete_resource(Req, State) ->
handle_request_json(Req, State).

-spec known_content_type(Req :: cowboy_req:req(), State :: #state{})
-> {Value :: any(), Req :: cowboy_req:req(), State :: #state{}}.

known_content_type(Req, State) ->
{true, Req, State}.

-spec valid_entity_length(Req :: cowboy_req:req(), State :: #state{})
-> {Value :: any(), Req :: cowboy_req:req(), State :: #state{}}.

valid_entity_length(Req, State) ->
%% @TODO check the length
{true, Req, State}.

%%%%

-type handle_response() ::
{ok, {Status :: cowboy:http_status(), Headers :: cowboy:http_headers(), Body :: iodata()}, Req :: cowboy_req:req()} |
{error, Reason :: any(), Req :: cowboy_req:req()}.
-type handler_response() ::
{ok, {Status :: cowboy:http_status(), Headers :: cowboy:http_headers(), Body :: binary()}} |
{error, Reason :: any()}.

-spec process_response(Response :: handler_response(), cowboy_req:req(), #state{}) -> {halt, cowboy_req:req(), #state{}}.

-spec handle_request(Response :: handle_response(), #state{}, cowboy_req:req()) -> {halt, cowboy_req:req(), #state{}}.

handle_request(Response, Req0, State = #state{operation_id = OperationID}) ->
process_response(Response, Req0, State = #state{operation_id = OperationID}) ->
case Response of
{ok, {Code, Headers, Body}} ->
{ok, Req} = cowboy_req:reply(Code, Headers, Body, Req0),
Expand Down Expand Up @@ -138,21 +174,18 @@ handle_request_json(
{{packageName}}_api:validate_response(OperationID, Code, Body , ValidatorState),
PreparedBody = jsx:encode(Body),
Response = {ok, {Code, Headers, PreparedBody}},
handle_request(Response, Req1, State)
process_response(Response, Req1, State)
end;
{error, Reason, Req1} ->
handle_request({error, Reason}, Req1, State)
process_response({error, Reason}, Req1, State)
end.

validate_headers(_, Req) -> {true, Req}.

-spec report(Level :: error | info | warning, Message :: iodata()) -> ok.
-spec report(Level :: error | info, Message :: iodata()) -> ok.

report(info, Message) ->
error_logger:info_msg(Message);

report(warning, Message) ->
error_logger:warning_msg(Message);

report(error, Message) ->
error_logger:error_msg(Message).
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

-export([get_paths/1]).

-spec get_paths(LogicHandler :: atom()) -> [{'_',[any()]},...].

get_paths(LogicHandler) ->
ValidatorState = prepare_validator(),
PreparedPaths = maps:fold(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,28 @@

-export([child_spec/2]).

child_spec(Id, #{
ip := Ip,
-spec child_spec( ID :: any(), #{
ip => inet:ip_address(),
port => inet:port_number(),
net_opts => []
}) -> supervisor:child_spec().

child_spec(ID, #{
ip := IP ,
port := Port,
net_opts := NetOpts
} = Params) ->
AcceptorsPool = ?DEFAULT_ACCEPTORS_POOLSIZE,
{Transport, TransportOpts} = get_socket_transport(Ip, Port, NetOpts),
{Transport, TransportOpts} = get_socket_transport(IP, Port, NetOpts),
LogicHandler = maps:get(logic_handler, Params, ?DEFAULT_LOGIC_HANDLER),
ExtraOpts = maps:get(cowboy_extra_opts, Params, []),
CowboyOpts = get_cowboy_config(LogicHandler, ExtraOpts),
ranch:child_spec({?MODULE, Id}, AcceptorsPool,
ranch:child_spec({?MODULE, ID}, AcceptorsPool,
Transport, TransportOpts, cowboy_protocol, CowboyOpts).

get_socket_transport(Ip, Port, Options) ->
get_socket_transport(IP, Port, Options) ->
Opts = [
{ip, Ip},
{ip, IP},
{port, Port}
],
case {{packageName}}_utils:get_opt(ssl, Options) of
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,27 +54,38 @@ to_int(Data) when is_binary(Data) ->
to_int(Data) when is_list(Data) ->
list_to_integer(Data).

-spec set_resp_headers([{binary(), iodata()}], cowboy_req:req()) -> cowboy_req:req().

set_resp_headers([], Req) ->
Req;
set_resp_headers([{K, V} | T], Req0) ->
Req = cowboy_req:set_resp_header(K, V, Req0),
set_resp_headers(T, Req).

-spec to_header(iodata() | atom() | number()) -> binary().

to_header(Name) ->
Prepared = to_binary(Name),
to_lower(Prepared).

-spec to_qs(iodata() | atom() | number()) -> binary().

to_qs(Name) ->
to_binary(Name).

-spec to_binding(iodata() | atom() | number()) -> atom().

to_binding(Name) ->
Prepared = to_binary(Name),
binary_to_atom(Prepared, utf8).

-spec get_opt(any(), []) -> any().

get_opt(Key, Opts) ->
get_opt(Key, Opts, undefined).

-spec get_opt(any(), [], any()) -> any().

get_opt(Key, Opts, Default) ->
case lists:keyfind(Key, 1, Opts) of
{_, Value} -> Value;
Expand Down

0 comments on commit 97dfb92

Please sign in to comment.