Skip to content

Commit

Permalink
Update erlang-server sample
Browse files Browse the repository at this point in the history
  • Loading branch information
feihongmeilian committed Nov 2, 2018
1 parent 0549e73 commit 8f61ace
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 105 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.2-SNAPSHOT
3.3.3-SNAPSHOT
19 changes: 9 additions & 10 deletions samples/server/petstore/erlang-server/src/openapi_api.erl
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ validate(Rule = {pattern, Pattern}, Name, Value, _ValidatorState) ->
end;

validate(Rule = schema, Name, Value, ValidatorState) ->
Definition = list_to_binary("#/definitions/" ++ openapi_utils:to_list(Name)),
Definition = list_to_binary("#/components/schemas/" ++ openapi_utils:to_list(Name)),
try
_ = validate_with_schema(Value, Definition, ValidatorState),
ok
Expand Down Expand Up @@ -688,27 +688,26 @@ validation_error(ViolatedRule, Name, Info) ->
{Value :: any(), Req :: cowboy_req:req()} |
{error, Reason :: any(), Req :: cowboy_req:req()}.
get_value(body, _Name, Req0) ->
{ok, Body, Req} = cowboy_req:body(Req0),
{ok, Body, Req} = cowboy_req:read_body(Req0),
case prepare_body(Body) of
{error, Reason} ->
{error, Reason, Req};
Value ->
{Value, Req}
end;

get_value(qs_val, Name, Req0) ->
{QS, Req} = cowboy_req:qs_vals(Req0),
get_value(qs_val, Name, Req) ->
QS = cowboy_req:parse_qs(Req),
Value = openapi_utils:get_opt(openapi_utils:to_qs(Name), QS),
{Value, Req};

get_value(header, Name, Req0) ->
{Headers, Req} = cowboy_req:headers(Req0),
Value = openapi_utils:get_opt(openapi_utils:to_header(Name), Headers),
get_value(header, Name, Req) ->
Headers = cowboy_req:headers(Req),
Value = maps:get(openapi_utils:to_header(Name), Headers, undefined),
{Value, Req};

get_value(binding, Name, Req0) ->
{Bindings, Req} = cowboy_req:bindings(Req0),
Value = openapi_utils:get_opt(openapi_utils:to_binding(Name), Bindings),
get_value(binding, Name, Req) ->
Value = cowboy_req:binding(openapi_utils:to_binding(Name), Req),
{Value, Req}.

prepare_body(Body) ->
Expand Down
13 changes: 7 additions & 6 deletions samples/server/petstore/erlang-server/src/openapi_auth.erl
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,19 @@ authorize_api_key(LogicHandler, OperationID, From, KeyParam, Req0) ->
end
end.

get_api_key(header, KeyParam, Req0) ->
{Headers, Req} = cowboy_req:headers(Req0),
get_api_key(header, KeyParam, Req) ->
Headers = cowboy_req:headers(Req),
{
openapi_utils:get_opt(
maps:get(
openapi_utils:to_header(KeyParam),
Headers
Headers,
undefined
),
Req
};

get_api_key(qs_val, KeyParam, Req0) ->
{QS, Req} = cowboy_req:qs_vals(Req0),
get_api_key(qs_val, KeyParam, Req) ->
QS = cowboy_req:parse_qs(Req),
{ openapi_utils:get_opt(KeyParam, QS), Req}.


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ authorize_api_key(_, _) -> {true, #{}}.
Req :: cowboy_req:req(),
Context :: #{}
) ->
{Status :: cowboy:http_status(), Headers :: cowboy:http_headers(), Body :: #{}}.
{Status :: cowboy:http_status(), Headers :: cowboy:http_headers(), Body :: jsx:json_term()}.

handle_request(OperationID, Req, Context) ->
error_logger:error_msg(
"Got not implemented request to process: ~p~n",
[{OperationID, Req, Context}]
),
{501, [], #{}}.
{501, #{}, #{}}.
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
Result :: boolean() | {boolean(), context()}.


-callback handle_request(OperationID :: openapi_api:operation_id(), Request :: any(), Context :: context()) ->
-callback handle_request(OperationID :: openapi_api:operation_id(), cowboy_req:req(), Context :: context()) ->
handler_response().

-spec handle_request(
Handler :: atom(),
OperationID :: openapi_api:operation_id(),
Request :: any(),
Request :: cowboy_req:req(),
Context :: context()
) ->
handler_response().
Expand Down
39 changes: 15 additions & 24 deletions samples/server/petstore/erlang-server/src/openapi_pet_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@

%% Cowboy REST callbacks
-export([allowed_methods/2]).
-export([init/3]).
-export([rest_init/2]).
-export([init/2]).
-export([allow_missing_post/2]).
-export([content_types_accepted/2]).
-export([content_types_provided/2]).
Expand All @@ -27,17 +26,11 @@

-type state() :: state().

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

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

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

rest_init(Req0, {Operations, LogicHandler, ValidatorState}) ->
{Method, Req} = cowboy_req:method(Req0),
init(Req, {Operations, LogicHandler, ValidatorState}) ->
Method = cowboy_req:method(Req),
OperationID = maps:get(Method, Operations, undefined),

error_logger:info_msg("Attempt to process operation: ~p", [OperationID]),
Expand All @@ -47,7 +40,7 @@ rest_init(Req0, {Operations, LogicHandler, ValidatorState}) ->
logic_handler = LogicHandler,
validator_state = ValidatorState
},
{ok, Req, State}.
{cowboy_rest, Req, State}.

-spec allowed_methods(Req :: cowboy_req:req(), State :: state()) ->
{Value :: [binary()], Req :: cowboy_req:req(), State :: state()}.
Expand Down Expand Up @@ -423,49 +416,47 @@ valid_entity_length(Req, State) ->
{true, Req, State}.

%%%%

-type result_ok() :: {
ok,
{Status :: cowboy:http_status(), Headers :: cowboy:http_headers(), Body :: iodata()}
}.

-type result_error() :: {error, Reason :: any()}.

-type processed_response() :: {halt, cowboy_req:req(), state()}.
-type processed_response() :: {stop, cowboy_req:req(), state()}.

-spec process_response(result_ok() | result_error(), cowboy_req:req(), state()) ->
processed_response().

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),
{halt, Req, State};
Req = cowboy_req:reply(Code, Headers, Body, Req0),
{stop, Req, State};
{error, Message} ->
error_logger:error_msg("Unable to process request for ~p: ~p", [OperationID, Message]),

{ok, Req} = cowboy_req:reply(400, Req0),
{halt, Req, State}
Req = cowboy_req:reply(400, Req0),
{stop, Req, State}
end.

-spec handle_request_json(cowboy_req:req(), state()) -> {halt, cowboy_req:req(), state()}.
-spec handle_request_json(cowboy_req:req(), state()) -> {cowboy_req:resp_body(), cowboy_req:req(), state()}.

handle_request_json(
Req0,
State = #state{
operation_id = OperationID,
logic_handler = LogicHandler,
validator_state = ValidatorState,
context = Context
validator_state = ValidatorState
}
) ->
case openapi_api:populate_request(OperationID, Req0, ValidatorState) of
{ok, Populated, Req1} ->
{Code, Headers, Body} = openapi_logic_handler:handle_request(
LogicHandler,
OperationID,
Populated,
Context
Req1,
Populated
),
_ = openapi_api:validate_response(
OperationID,
Expand Down
26 changes: 14 additions & 12 deletions samples/server/petstore/erlang-server/src/openapi_server.erl
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
-module(openapi_server).


-define(DEFAULT_ACCEPTORS_POOLSIZE, 100).
-define(DEFAULT_LOGIC_HANDLER, openapi_default_logic_handler).

-export([child_spec/2]).
-export([start/2]).

-spec child_spec( ID :: any(), #{
-spec start( ID :: any(), #{
ip => inet:ip_address(),
port => inet:port_number(),
logic_handler => module(),
net_opts => []
}) -> supervisor:child_spec().
}) -> {ok, pid()} | {error, any()}.

child_spec(ID, #{
start(ID, #{
ip := IP ,
port := Port,
net_opts := NetOpts
} = Params) ->
AcceptorsPool = ?DEFAULT_ACCEPTORS_POOLSIZE,
{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,
Transport, TransportOpts, cowboy_protocol, CowboyOpts).
case Transport of
ssl ->
cowboy:start_tls(ID, TransportOpts, CowboyOpts);
tcp ->
cowboy:start_clear(ID, TransportOpts, CowboyOpts)
end.

get_socket_transport(IP, Port, Options) ->
Opts = [
Expand All @@ -33,9 +35,9 @@ get_socket_transport(IP, Port, Options) ->
],
case openapi_utils:get_opt(ssl, Options) of
SslOpts = [_|_] ->
{ranch_ssl, Opts ++ SslOpts};
{ssl, Opts ++ SslOpts};
undefined ->
{ranch_tcp, Opts}
{tcp, Opts}
end.

get_cowboy_config(LogicHandler, ExtraOpts) ->
Expand All @@ -56,10 +58,10 @@ get_cowboy_config(LogicHandler, [{Key, Value}| Rest], Opts) ->

get_default_dispatch(LogicHandler) ->
Paths = openapi_router:get_paths(LogicHandler),
{dispatch, cowboy_router:compile(Paths)}.
#{dispatch => cowboy_router:compile(Paths)}.

get_default_opts(LogicHandler) ->
[{env, [get_default_dispatch(LogicHandler)]}].
#{env => get_default_dispatch(LogicHandler)}.

store_key(Key, Value, Opts) ->
lists:keystore(Key, 1, Opts, {Key, Value}).
39 changes: 15 additions & 24 deletions samples/server/petstore/erlang-server/src/openapi_store_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@

%% Cowboy REST callbacks
-export([allowed_methods/2]).
-export([init/3]).
-export([rest_init/2]).
-export([init/2]).
-export([allow_missing_post/2]).
-export([content_types_accepted/2]).
-export([content_types_provided/2]).
Expand All @@ -27,17 +26,11 @@

-type state() :: state().

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

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

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

rest_init(Req0, {Operations, LogicHandler, ValidatorState}) ->
{Method, Req} = cowboy_req:method(Req0),
init(Req, {Operations, LogicHandler, ValidatorState}) ->
Method = cowboy_req:method(Req),
OperationID = maps:get(Method, Operations, undefined),

error_logger:info_msg("Attempt to process operation: ~p", [OperationID]),
Expand All @@ -47,7 +40,7 @@ rest_init(Req0, {Operations, LogicHandler, ValidatorState}) ->
logic_handler = LogicHandler,
validator_state = ValidatorState
},
{ok, Req, State}.
{cowboy_rest, Req, State}.

-spec allowed_methods(Req :: cowboy_req:req(), State :: state()) ->
{Value :: [binary()], Req :: cowboy_req:req(), State :: state()}.
Expand Down Expand Up @@ -218,49 +211,47 @@ valid_entity_length(Req, State) ->
{true, Req, State}.

%%%%

-type result_ok() :: {
ok,
{Status :: cowboy:http_status(), Headers :: cowboy:http_headers(), Body :: iodata()}
}.

-type result_error() :: {error, Reason :: any()}.

-type processed_response() :: {halt, cowboy_req:req(), state()}.
-type processed_response() :: {stop, cowboy_req:req(), state()}.

-spec process_response(result_ok() | result_error(), cowboy_req:req(), state()) ->
processed_response().

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),
{halt, Req, State};
Req = cowboy_req:reply(Code, Headers, Body, Req0),
{stop, Req, State};
{error, Message} ->
error_logger:error_msg("Unable to process request for ~p: ~p", [OperationID, Message]),

{ok, Req} = cowboy_req:reply(400, Req0),
{halt, Req, State}
Req = cowboy_req:reply(400, Req0),
{stop, Req, State}
end.

-spec handle_request_json(cowboy_req:req(), state()) -> {halt, cowboy_req:req(), state()}.
-spec handle_request_json(cowboy_req:req(), state()) -> {cowboy_req:resp_body(), cowboy_req:req(), state()}.

handle_request_json(
Req0,
State = #state{
operation_id = OperationID,
logic_handler = LogicHandler,
validator_state = ValidatorState,
context = Context
validator_state = ValidatorState
}
) ->
case openapi_api:populate_request(OperationID, Req0, ValidatorState) of
{ok, Populated, Req1} ->
{Code, Headers, Body} = openapi_logic_handler:handle_request(
LogicHandler,
OperationID,
Populated,
Context
Req1,
Populated
),
_ = openapi_api:validate_response(
OperationID,
Expand Down
Loading

0 comments on commit 8f61ace

Please sign in to comment.