22-behaviour (nova_plugin ).
33
44-export ([
5+ init /0 ,
56 load_local_schemas /0 ,
6- pre_request /2 ,
7- post_request /2 ,
7+ pre_request /4 ,
8+ post_request /4 ,
89 plugin_info /0
910]).
1011
1112-include_lib (" kernel/include/logger.hrl" ).
1213
14+ init () ->
15+ jesse_database :load_all (),
16+ load_local_schemas (),
17+ #{}.
18+
1319% %--------------------------------------------------------------------
1420% % @doc
1521% % Load all local JSON schemas from the main application's
@@ -34,88 +40,85 @@ load_local_schemas() ->
3440% % Pre-request callback
3541% % @end
3642% %--------------------------------------------------------------------
37- -spec pre_request (Req :: cowboy_req :req (), Options :: map ()) ->
38- {ok , Req0 :: cowboy_req :req ()}
39- | {stop , Req0 :: cowboy_req :req ()}
43+ -spec pre_request (Req :: cowboy_req :req (), Env :: any (), Options :: map (), State :: any ()) ->
44+ {ok , Req0 :: cowboy_req :req (), NewState :: any () }
45+ | {stop , Req0 :: cowboy_req :req (), NewState :: any () }
4046 | {error , Reason :: term ()}.
4147pre_request (
42- Req = #{extra_state := #{json_schema := SchemaLocation } = Extra , json := JSON }, Options
48+ Req = #{extra_state := #{json_schema := SchemaLocation } = Extra , json := JSON },
49+ _Env ,
50+ Options ,
51+ State
4352) ->
4453 JesseOpts = maps :get (jesse_options , Extra , []),
45- % % JSON have already been parsed so we can just continue with the validation
4654 case validate_json (SchemaLocation , JSON , JesseOpts ) of
4755 ok ->
4856 ? LOG_DEBUG (" Schema validation on JSON body successful" ),
49- {ok , Req };
57+ {ok , Req , State };
5058 {error , Errors } ->
5159 ? LOG_DEBUG (" Got validation-errors on JSON body. Errors: ~p " , [Errors ]),
5260 case maps :get (render_errors , Options , false ) of
5361 true ->
5462 ? LOG_DEBUG (" Rendering validation-errors and send back to requester" ),
55- JsonLib = nova :get_env (json_lib , thoas ),
5663 Req0 = cowboy_req :set_resp_headers (
5764 #{<<" content-type" >> => <<" application/json" >>}, Req
5865 ),
5966 ErrorStruct = render_error (Errors ),
60- ErrorJson = erlang : apply ( JsonLib , encode , [ ErrorStruct ] ),
67+ ErrorJson = json : encode ( ErrorStruct ),
6168 Req1 = cowboy_req :set_resp_body (ErrorJson , Req0 ),
6269 Req2 = cowboy_req :reply (400 , Req1 ),
63- {stop , Req2 };
70+ {stop , Req2 , State };
6471 _ ->
6572 ? LOG_DEBUG (
6673 " render_errors-option not set for plugin nova_json_schemas - returning plain 400-status to requester"
6774 ),
6875 Req0 = cowboy_req :reply (400 , Req ),
69- {stop , Req0 }
76+ {stop , Req0 , State }
7077 end
7178 end ;
72- pre_request (#{extra_state := #{json_schema := _SchemaLocation }}, _Options ) ->
73- % % The body have not been parsed. Log and error and stop
79+ pre_request (#{extra_state := #{json_schema := _SchemaLocation }}, _Env , _Options , _State ) ->
7480 ? LOG_ERROR (
7581 " JSON Schema is set in 'extra_state' but body have not yet been parsed - rearrange your plugins so that JSON plugin is ran before this.."
7682 ),
7783 {error , body_not_parsed };
78- pre_request (Req , _Options ) ->
79- % % 'json_schema' is not set or 'extra_state' is completly missing. Just continue.
80- HasBody = cowboy_req :has_body (Req ),
81- if
82- HasBody ->
83- ? LOG_DEBUG (" No schema is set for this route so will continue executing" );
84- true ->
85- ok
86- end ,
87- {ok , Req }.
84+ pre_request (Req , _Env , _Options , State ) ->
85+ {ok , Req , State }.
8886
8987% %--------------------------------------------------------------------
9088% % @doc
9189% % Post-request callback
9290% % @end
9391% %--------------------------------------------------------------------
94- -spec post_request (Req :: cowboy_req :req (), Options :: map ()) ->
95- {ok , Req0 :: cowboy_req :req ()}
96- | {stop , Req0 :: cowboy_req :req ()}
97- | {error , Reason :: term ()}.
98- post_request (Req , _Options ) ->
99- {ok , Req }.
92+ -spec post_request (Req :: cowboy_req :req (), Env :: any (), Options :: map (), State :: any ()) ->
93+ {ok , Req0 :: cowboy_req :req (), NewState :: any ()}.
94+ post_request (Req , _Env , _Options , State ) ->
95+ {ok , Req , State }.
10096
10197% %--------------------------------------------------------------------
10298% % @doc
10399% % nova_plugin callback. Returns information about the plugin.
104100% % @end
105101% %--------------------------------------------------------------------
106102-spec plugin_info () ->
107- {Title :: binary (), Version :: binary (), Author :: binary (), Description :: binary (), [
108- {Key :: atom (), OptionDescription :: binary ()}
109- ]}.
103+ #{
104+ title := binary (),
105+ version := binary (),
106+ url := binary (),
107+ authors := [binary ()],
108+ description := binary (),
109+ options := [{Key :: atom (), OptionDescription :: binary ()}]
110+ }.
110111plugin_info () ->
111- {ok , Vsn } = application :get_key (nova_json_schemas , vsn ),
112- {ok , Desc } = application :get_key (nova_json_schemas , description ),
113-
114- {<<" JSON schema plugin" >>, list_to_binary (Vsn ), <<" Niclas Axelsson <niclas@burbas.se" >>,
115- list_to_binary (Desc ), [
116- {render_errors , <<" If this is set, validation-errors is returned to the requester" >>}
117- % % Options is specified as {Key, Description}
118- ]}.
112+ #{
113+ title => <<" Nova JSON Schema plugin" >>,
114+ version => <<" 0.2.0" >>,
115+ url => <<" https://github.com/novaframework/nova_json_schemas" >>,
116+ authors => [<<" Niclas Axelsson <niclas@burbas.se>" >>],
117+ description => <<" Validates JSON request bodies against JSON schemas using jesse" >>,
118+ options => [
119+ {render_errors , <<" If true, validation errors are returned as JSON to the requester" >>}
120+ ]
121+ }.
119122
120123validate_json (SchemaLocation , Json , JesseOpts ) ->
121124 case jesse :validate (SchemaLocation , Json , JesseOpts ) of
@@ -125,8 +128,7 @@ validate_json(SchemaLocation, Json, JesseOpts) ->
125128 PrivDir = code :priv_dir (MainApp ),
126129 SchemaLocation0 = filename :join ([PrivDir , SchemaLocation ]),
127130 {ok , Filecontent } = file :read_file (SchemaLocation0 ),
128- JsonLib = nova :get_env (json_lib , thoas ),
129- {ok , Schema } = erlang :apply (JsonLib , decode , [Filecontent ]),
131+ Schema = json :decode (Filecontent ),
130132 jesse :add_schema (SchemaLocation , Schema ),
131133 validate_json (SchemaLocation , Json , JesseOpts );
132134 {error , ValidationError } ->
@@ -178,12 +180,12 @@ load_schemas_from_dir(Dir, RelativePrefix) ->
178180load_schema_file (FilePath , RelativePath ) ->
179181 case file :read_file (FilePath ) of
180182 {ok , FileContent } ->
181- JsonLib = nova :get_env (json_lib , thoas ),
182- case erlang :apply (JsonLib , decode , [FileContent ]) of
183- {ok , Schema } ->
183+ try json :decode (FileContent ) of
184+ Schema ->
184185 jesse :add_schema (RelativePath , Schema ),
185- ? LOG_DEBUG (" Loaded JSON schema: ~s " , [RelativePath ]);
186- {error , Reason } ->
186+ ? LOG_DEBUG (" Loaded JSON schema: ~s " , [RelativePath ])
187+ catch
188+ error :Reason ->
187189 ? LOG_ERROR (" Failed to decode JSON schema ~s : ~p " , [FilePath , Reason ])
188190 end ;
189191 {error , Reason } ->
0 commit comments