diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..12d754f --- /dev/null +++ b/LICENSE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2022, Mathieu Kerjouan . + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/_build/default/lib/.rebar3/rebar_compiler_erl/source_project_apps.dag b/_build/default/lib/.rebar3/rebar_compiler_erl/source_project_apps.dag new file mode 100644 index 0000000..5504b24 Binary files /dev/null and b/_build/default/lib/.rebar3/rebar_compiler_erl/source_project_apps.dag differ diff --git a/_build/default/lib/rfc5424/include b/_build/default/lib/rfc5424/include new file mode 120000 index 0000000..0f0436a --- /dev/null +++ b/_build/default/lib/rfc5424/include @@ -0,0 +1 @@ +../../../../include \ No newline at end of file diff --git a/_build/default/lib/rfc5424/priv b/_build/default/lib/rfc5424/priv new file mode 120000 index 0000000..d100101 --- /dev/null +++ b/_build/default/lib/rfc5424/priv @@ -0,0 +1 @@ +../../../../priv \ No newline at end of file diff --git a/_build/default/lib/rfc5424/src b/_build/default/lib/rfc5424/src new file mode 120000 index 0000000..b3e266f --- /dev/null +++ b/_build/default/lib/rfc5424/src @@ -0,0 +1 @@ +../../../../src \ No newline at end of file diff --git a/c_src/Makefile b/c_src/Makefile new file mode 100644 index 0000000..199fe0a --- /dev/null +++ b/c_src/Makefile @@ -0,0 +1,13 @@ +# GNU Makefile for rfc5424 application +all: rfc5424_test rfc5424 + +rfc5424: + cc $@.c -o $@ + +rfc5424_test: + cc $@.c -o $@ + ./$@ + +clean: + rm rfc5424 + rm rfc5424_test diff --git a/c_src/minunit.h b/c_src/minunit.h new file mode 100644 index 0000000..d2e3229 --- /dev/null +++ b/c_src/minunit.h @@ -0,0 +1,6 @@ +/* file: minunit.h */ +/* http://www.jera.com/techinfo/jtns/jtn002.html */ +#define mu_assert(message, test) do { if (!(test)) return message; } while (0) +#define mu_run_test(test) do { char *message = test(); tests_run++; \ + if (message) return message; } while (0) +extern int tests_run; diff --git a/c_src/rfc5424.c b/c_src/rfc5424.c new file mode 100644 index 0000000..f5c1685 --- /dev/null +++ b/c_src/rfc5424.c @@ -0,0 +1,8 @@ +/* file rfc5424.c */ + +#include "rfc5424.h" + +int +main(int argc, char *argv[]) { + return 0; +} diff --git a/c_src/rfc5424.h b/c_src/rfc5424.h new file mode 100644 index 0000000..e859ba5 --- /dev/null +++ b/c_src/rfc5424.h @@ -0,0 +1 @@ +/* file rfc5424.h */ diff --git a/c_src/rfc5424_test.c b/c_src/rfc5424_test.c new file mode 100644 index 0000000..e62f032 --- /dev/null +++ b/c_src/rfc5424_test.c @@ -0,0 +1,43 @@ +/* file rfc5424_test.c */ +/* http://www.jera.com/techinfo/jtns/jtn002.html */ + +#include +#include "minunit.h" + +int tests_run = 0; + +int foo = 7; +int bar = 4; + +static char * +test_foo() { + mu_assert("error, foo != 7", foo == 7); + return 0; +} + +static char * +test_bar() { + mu_assert("error, bar != 5", bar != 5); + return 0; +} + +static char * +all_tests() { + mu_run_test(test_foo); + mu_run_test(test_bar); + return 0; +} + +int +main(int argc, char **argv) { + char *result = all_tests(); + if (result != 0) { + printf("%s\n", result); + } + else { + printf("ALL TESTS PASSED\n"); + } + printf("Tests run: %d\n", tests_run); + + return result != 0; +} diff --git a/include/rfc5424.hrl b/include/rfc5424.hrl new file mode 100644 index 0000000..5b832e0 --- /dev/null +++ b/include/rfc5424.hrl @@ -0,0 +1,4 @@ +%%%------------------------------------------------------------------- +%%% @author Mathieu Kerjouan +%%% @copyright 2022 (c) Mathieu Kerjouan +%%%------------------------------------------------------------------- diff --git a/rebar.config b/rebar.config new file mode 100644 index 0000000..aa2b244 --- /dev/null +++ b/rebar.config @@ -0,0 +1,7 @@ +{erl_opts, [debug_info]}. +{deps, []}. + +{shell, [ + % {config, "config/sys.config"}, + {apps, [rfc5424]} +]}. diff --git a/rebar.lock b/rebar.lock new file mode 100644 index 0000000..57afcca --- /dev/null +++ b/rebar.lock @@ -0,0 +1 @@ +[]. diff --git a/src/rfc5424.app.src b/src/rfc5424.app.src new file mode 100644 index 0000000..0547dfe --- /dev/null +++ b/src/rfc5424.app.src @@ -0,0 +1,14 @@ +{application, rfc5424, + [{description, "rfc5424 application"}, + {vsn, "0.1.0"}, + {registered, [rfc5424_sup]}, + {mod, {rfc5424_app, []}}, + {applications, + [kernel, + stdlib + ]}, + {env,[]}, + {modules, []}, + {licenses, ["Apache 2.0"]}, + {links, []} + ]}. diff --git a/src/rfc5424.erl b/src/rfc5424.erl new file mode 100644 index 0000000..c09d6a7 --- /dev/null +++ b/src/rfc5424.erl @@ -0,0 +1,49 @@ +%%%=================================================================== +%%% +%%%=================================================================== +-module(rfc5424). +-export([decode/1, decode/2]). +-export([encode/1, encode/2]). +-include("rfc5424.hrl"). +-include_lib("eunit/include/eunit.hrl"). + +%%-------------------------------------------------------------------- +%% +%% +%%-------------------------------------------------------------------- +decode(Data) -> + decode(Data, []). + +%%-------------------------------------------------------------------- +%% +%% +%%-------------------------------------------------------------------- +decode(Data, Args) -> + ok. + +decode_test() -> + [?assertEqual(#{ priority => "" + , facility => "" + , version => 1 + , timestamp => <<"2003-10-11T22:14:15.003Z">> + , hostname => <<"mymachine.example.com">> + , appname => <<"su">> + , procid => <<"ID47">> + , message => <<"BOM'su root' failed for lonvick on /dev/pts/">> + } + , <<"<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - BOM'su root' failed for lonvick on /dev/pts/8">>) + ]. + +%%-------------------------------------------------------------------- +%% +%% +%%-------------------------------------------------------------------- +encode(Term) -> + encode(Term, []). + +%%-------------------------------------------------------------------- +%% +%% +%%-------------------------------------------------------------------- +encode(Term, Args) -> + ok. diff --git a/src/rfc5424.hrl b/src/rfc5424.hrl new file mode 100644 index 0000000..e69de29 diff --git a/src/rfc5424_app.erl b/src/rfc5424_app.erl new file mode 100644 index 0000000..554131e --- /dev/null +++ b/src/rfc5424_app.erl @@ -0,0 +1,31 @@ +%%%------------------------------------------------------------------- +%%% @author Mathieu Kerjouan +%%% @copyright 2022 (c) Mathieu Kerjouan +%%% +%%% @doc rfc5424 main application +%%% @end +%%%------------------------------------------------------------------- +-module(rfc5424_app). +-behaviour(application). +-export([start/2, stop/1]). + +%%-------------------------------------------------------------------- +%% @doc start/2 +%% @end +%%-------------------------------------------------------------------- +-spec start(StartType, StartArgs) -> Return when + StartType :: application:start_type(), + StartArgs :: term(), + Return :: pid(). +start(_StartType, _StartArgs) -> + rfc5424_sup:start_link(). + +%%-------------------------------------------------------------------- +%% @doc stop/1 +%% @end +%%-------------------------------------------------------------------- +-spec stop(State) -> Return when + State :: term(), + Return :: ok. +stop(_State) -> + ok. diff --git a/src/rfc5424_module.erl b/src/rfc5424_module.erl new file mode 100644 index 0000000..d74dc1d --- /dev/null +++ b/src/rfc5424_module.erl @@ -0,0 +1 @@ +-module(rfc5424_module). diff --git a/src/rfc5424_module_httpd.erl b/src/rfc5424_module_httpd.erl new file mode 100644 index 0000000..40501dc --- /dev/null +++ b/src/rfc5424_module_httpd.erl @@ -0,0 +1 @@ +-module(rfc5424_module_httpd). diff --git a/src/rfc5424_module_nginx.erl b/src/rfc5424_module_nginx.erl new file mode 100644 index 0000000..53d76bf --- /dev/null +++ b/src/rfc5424_module_nginx.erl @@ -0,0 +1 @@ +-module(rfc5424_module_nginx). diff --git a/src/rfc5424_parser.erl b/src/rfc5424_parser.erl new file mode 100644 index 0000000..0a26268 --- /dev/null +++ b/src/rfc5424_parser.erl @@ -0,0 +1,112 @@ +-module(rfc5424_parser). +-compile([pri/1]). + +% TODO: end facility +-type facility() :: kernel | user | mail | daemon. + +% TODO: end severity: +-type severity() :: error | warning | info | notice | debug. + +-type priority() :: #{ severity => severity(), facility => facility() }. + +%%-------------------------------------------------------------------- +%% +%%-------------------------------------------------------------------- +-spec pri(Data) -> Return when + Data :: bitstring(), + Return :: {ok, Priority} | {ok, Priority, Rest}, + Priority :: priority(), + Rest :: bitstring(). +pri(<<"<0",_,">">>) -> {error, bad_value}; +pri(<<"<00",_,">">>) -> {error, bad_value}; +pri(<<"<", I0:8/bitstring, ">">>) -> + pri_to_map(I0); +pri(<<"<", I0:8/bitstring, I1:8/bitstring, ">">>) -> + pri_to_map(<>); +pri(<<"<", I0:8/bitstring, I1:8/bitstring, I2:8/bitstring, ">">>) -> + pri_to_map(<>); +pri(<<"<", I:8/bitstring, ">", Rest/bitstring>>) -> + case pri(<<"<", I/bitstring, ">">>) of + {ok, Value} -> {ok, Value, Rest} + end; +pri(<<"<", I:16/bitstring, ">", Rest/bitstring>>) -> + case pri(<<"<", I/bitstring, ">">>) of + {ok, Value} -> {ok, Value, Rest} + end; +pri(<<"<", I:24/bitstring, ">", Rest/bitstring>>) -> + case pri(<<"<", I/bitstring, ">">>) of + {ok, Value} -> {ok, Value, Rest} + end. + +%%-------------------------------------------------------------------- +%% +%%-------------------------------------------------------------------- +pri_to_map(Data) -> + case pri_to_integer(Data) of + {ok, Value} -> pri_converter(Value); + {error, Reason} -> {error, Reason} + end. + +%%-------------------------------------------------------------------- +%% +%%-------------------------------------------------------------------- +pri_to_integer(Data) -> + try erlang:binary_to_integer(Data) of + Integer -> {ok, Integer} + catch + _:Reason -> {error, Reason} + end. + +%%-------------------------------------------------------------------- +%% +%%-------------------------------------------------------------------- +pri_converter(Integer) -> + try + Facility = erlang:trunc(Integer/8), + FacilityAtom = facility(Facility), + Severity = Integer-(Facility*8), + SeverityAtom = severity(Severity), + {ok, #{ facility => FacilityAtom, severity => SeverityAtom }} + catch + _:_ -> {error, not_supported} + end. + +%%-------------------------------------------------------------------- +%% +%%-------------------------------------------------------------------- +facility(0) -> kernel; +facility(1) -> user; +facility(2) -> mail; +facility(3) -> daemon; +facility(4) -> security; +facility(5) -> syslogd; +facility(6) -> printer; +facility(7) -> news; +facility(8) -> uucp; +facility(9) -> clock; +facility(10) -> security; +facility(11) -> ftp; +facility(12) -> ntp; +facility(13) -> audit; +facility(14) -> alert; +facility(15) -> clock; +facility(16) -> local0; +facility(17) -> local1; +facility(18) -> local2; +facility(19) -> local3; +facility(20) -> local4; +facility(21) -> local5; +facility(22) -> local6; +facility(23) -> local7. + +%%-------------------------------------------------------------------- +%% +%%-------------------------------------------------------------------- +severity(0) -> emergency; +severity(1) -> alert; +severity(2) -> critical; +severity(3) -> error; +severity(4) -> warning; +severity(5) -> notice; +severity(6) -> info; +severity(7) -> debug. diff --git a/src/rfc5424_server.erl b/src/rfc5424_server.erl new file mode 100644 index 0000000..4e796f4 --- /dev/null +++ b/src/rfc5424_server.erl @@ -0,0 +1,163 @@ +%%%------------------------------------------------------------------- +%%% @author Mathieu Kerjouan +%%% @copyright 2022 (c) Mathieu Kerjouan +%%% +%%% @doc gen_server template for rfc5424 application +%%% @end +%%%------------------------------------------------------------------- +-module(rfc5424_server). +-behaviour(gen_server). +-export([start/0, start/1, start/2, start/3]). +-export([start_link/0, start_link/1, start_link/2, start_link/3]). +-export([init/1, terminate/2]). +-export([handle_call/3, handle_cast/2, handle_info/2]). + +%%-------------------------------------------------------------------- +%% @doc start/0 +%% @end +%%-------------------------------------------------------------------- +-spec start() -> Return when + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start() -> + start([]). + +%%-------------------------------------------------------------------- +%% @doc start/1 +%% @end +%%-------------------------------------------------------------------- +-spec start(Args) -> Return when + Args :: term(), + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start(Args) -> + start(Args, []). + +%%-------------------------------------------------------------------- +%% @doc start/2 +%% @end +%%-------------------------------------------------------------------- +-spec start(Args, Opts) -> Return when + Args :: term(), + Opts :: [term()], + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start(Args, Opts) -> + gen_server:start(?MODULE, Args, Opts). + +%%-------------------------------------------------------------------- +%% @doc start/3 +%% @end +%%-------------------------------------------------------------------- +-spec start(Name, Args, Opts) -> Return when + Name :: atom(), + Args :: term(), + Opts :: [term()], + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start(Name, Args, Opts) -> + gen_server:start({local, ?MODULE}, ?MODULE, Args, Opts). + +%%-------------------------------------------------------------------- +%% @doc start_link/0 +%% @end +%%-------------------------------------------------------------------- +-spec start_link() -> Return when + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start_link() -> + start_link([]). + +%%-------------------------------------------------------------------- +%% @doc start_link/1 +%% @end +%%-------------------------------------------------------------------- +-spec start_link(Args) -> Return when + Args :: term(), + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start_link(Args) -> + start_link(Args, []). + +%%-------------------------------------------------------------------- +%% @doc start_link/2 +%% @end +%%-------------------------------------------------------------------- +-spec start_link(Args, Opts) -> Return when + Args :: term(), + Opts :: [term()], + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start_link(Args, Opts) -> + gen_server:start_link(?MODULE, Args, Opts). + +%%-------------------------------------------------------------------- +%% @doc start_link/3 +%% @end +%%-------------------------------------------------------------------- +-spec start_link(Name, Args, Opts) -> Return when + Name :: atom(), + Args :: term(), + Opts :: [term()], + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start_link(Name, Args, Opts) -> + gen_server:start_link({local, ?MODULE}, ?MODULE, Args, Opts). + +%%-------------------------------------------------------------------- +%% @doc init/1 +%% @end +%%-------------------------------------------------------------------- +-spec init(Args) -> Return when + Args :: term(), + Return :: {ok, State} | {ok,State,Timeout} | {ok,State,hibernate}, + Timeout :: integer(), + State :: term(). +init(_Args) -> + State = [], + {ok, State}. + +%%-------------------------------------------------------------------- +%% @doc terminate/2 +%% @end +%%-------------------------------------------------------------------- +terminate(_Reason, _Data) -> + ok. + + +%%-------------------------------------------------------------------- +%% @doc handle_call/3 +%% @end +%%-------------------------------------------------------------------- +-spec handle_call(Message, From, State) -> Return when + From :: term(), + Message :: term(), + State :: term(), + Return :: term(). +handle_call(Message, From, State) -> + logger:warning("got ~p from ~p", [Message, From]), + {reply, Message, State}. + +%%-------------------------------------------------------------------- +%% @doc handle_cast/2 +%% @end +%%-------------------------------------------------------------------- +-spec handle_cast(Message, State) -> Return when + Message :: term(), + State :: term(), + Return :: term(). +handle_cast(Message, State) -> + logger:warning("got ~p", [Message]), + {noreply, State}. + +%%-------------------------------------------------------------------- +%% @doc handle_info/2 +%% @end +%%-------------------------------------------------------------------- +-spec handle_info(Message, State) -> Return when + Message :: term(), + State :: term(), + Return :: term(). +handle_info(Message, State) -> + logger:warning("got ~p", [Message]), + {noreply, State}. diff --git a/src/rfc5424_statem.erl b/src/rfc5424_statem.erl new file mode 100644 index 0000000..99ecc85 --- /dev/null +++ b/src/rfc5424_statem.erl @@ -0,0 +1,151 @@ +%%%------------------------------------------------------------------- +%%% @author Mathieu Kerjouan +%%% @copyright 2022 (c) Mathieu Kerjouan +%%% +%%% @doc gen_statem template for rfc5424 application +%%% @end +%%%------------------------------------------------------------------- +-module(rfc5424_statem). +-behaviour(gen_statem). +-export([start/0, start/1, start/2, start/3]). +-export([start_link/0, start_link/1, start_link/2, start_link/3]). +-export([callback_mode/0, init/1, terminate/3]). +-export([on/3, off/3]). + +%%-------------------------------------------------------------------- +%% @doc start/0 +%% @end +%%-------------------------------------------------------------------- +-spec start() -> Return when + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start() -> + start([]). + +%%-------------------------------------------------------------------- +%% @doc start/1 +%% @end +%%-------------------------------------------------------------------- +-spec start(Args) -> Return when + Args :: term(), + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start(Args) -> + start(Args, []). + +%%-------------------------------------------------------------------- +%% @doc start/2 +%% @end +%%-------------------------------------------------------------------- +-spec start(Args, Opts) -> Return when + Args :: term(), + Opts :: [term()], + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start(Args, Opts) -> + gen_statem:start(?MODULE, Args, Opts). + +%%-------------------------------------------------------------------- +%% @doc start/3 +%% @end +%%-------------------------------------------------------------------- +-spec start(Name, Args, Opts) -> Return when + Name :: atom(), + Args :: term(), + Opts :: [term()], + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start(Name, Args, Opts) -> + gen_statem:start({local, ?MODULE}, ?MODULE, Args, Opts). + +%%-------------------------------------------------------------------- +%% @doc start_link/0 +%% @end +%%-------------------------------------------------------------------- +-spec start_link() -> Return when + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start_link() -> + start_link([]). + +%%-------------------------------------------------------------------- +%% @doc start_link/1 +%% @end +%%-------------------------------------------------------------------- +-spec start_link(Args) -> Return when + Args :: term(), + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start_link(Args) -> + start_link(Args, []). + +%%-------------------------------------------------------------------- +%% @doc start_link/2 +%% @end +%%-------------------------------------------------------------------- +-spec start_link(Args, Opts) -> Return when + Args :: term(), + Opts :: [term()], + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start_link(Args, Opts) -> + gen_statem:start_link(?MODULE, Args, Opts). + +%%-------------------------------------------------------------------- +%% @doc start_link/3 +%% @end +%%-------------------------------------------------------------------- +-spec start_link(Name, Args, Opts) -> Return when + Name :: atom(), + Args :: term(), + Opts :: [term()], + Return :: {ok, pid()} | ignore | {error, Error}, + Error :: {already_started, pid()} | term(). +start_link(Name, Args, Opts) -> + gen_statem:start_link({local, ?MODULE}, ?MODULE, Args, Opts). + +%%-------------------------------------------------------------------- +%% @doc callback_mode/0 +%% @end +%%-------------------------------------------------------------------- +-spec callback_mode() -> Return when + Return :: atom() | [atom()]. +callback_mode() -> + state_functions. + +%%-------------------------------------------------------------------- +%% @doc init/1 +%% @end +%%-------------------------------------------------------------------- +-spec init(Args) -> Return when + Args :: term(), + Return :: {ok, State, Data}, + State :: term(), + Data :: atom(). +init(_Args) -> + State = on, + Data = [], + {ok, State, Data}. + +%%-------------------------------------------------------------------- +%% @doc terminate/3 +%% @end +%%-------------------------------------------------------------------- +terminate(_Reason, _State, _Data) -> + ok. + +%%-------------------------------------------------------------------- +%% @doc on/3 +%% @end +%%-------------------------------------------------------------------- +on(MessageType, Message, Data) -> + logger:warning("got ~p from ~p", [Message, MessageType]), + {keep_state, Data}. + +%%-------------------------------------------------------------------- +%% @doc off/3 +%% @end +%%-------------------------------------------------------------------- +off(MessageType, Message, Data) -> + logger:warning("got ~p from ~p", [Message, MessageType]), + {keep_state, Data}. diff --git a/src/rfc5424_sup.erl b/src/rfc5424_sup.erl new file mode 100644 index 0000000..b220bc4 --- /dev/null +++ b/src/rfc5424_sup.erl @@ -0,0 +1,58 @@ +%%%------------------------------------------------------------------- +%%% @author Mathieu Kerjouan +%%% @copyright 2022 (c) Mathieu Kerjouan +%%% +%%% @doc rfc5424 application supervisor +%%% @end +%%%------------------------------------------------------------------- +-module(rfc5424_sup). +-behaviour(supervisor). +-export([start_link/0, start_link/1, start_link/2]). +-export([init/1]). + +%%-------------------------------------------------------------------- +%% @doc start_link/0 +%% @end +%%-------------------------------------------------------------------- +-spec start_link() -> Return when + Return :: supervisor:startlink_ret() | + supervisor:startlink_err(). +start_link() -> + start_link([]). + +%%-------------------------------------------------------------------- +%% @doc start_link/1 +%% @end +%%-------------------------------------------------------------------- +-spec start_link(Args) -> Return when + Args :: term(), + Return :: supervisor:startlink_ret() | + supervisor:startlink_err(). +start_link(Args) -> + start_link(?MODULE, Args). + +%%-------------------------------------------------------------------- +%% @doc start_link/2 +%% @end +%%-------------------------------------------------------------------- +-spec start_link(Name, Args) -> Return when + Name :: atom(), + Args :: term(), + Return :: supervisor:startlink_ret() | + supervisor:startlink_err(). +start_link(Name, Args) -> + supervisor:start_link({local, Name}, ?MODULE, Args). + +%%-------------------------------------------------------------------- +%% @doc init/1 +%% @end +%%-------------------------------------------------------------------- +-spec init(Args) -> Return when + Args :: term(), + Return :: {ok, {supervisor:sup_flags() + ,supervisor:child_spec()}} | + ignore. +init(_Args) -> + SupervisorFlags = #{}, + ChildSpecs = [], + {ok, {SupervisorFlags, ChildSpecs}}. diff --git a/test/rfc5424_SUITE.erl b/test/rfc5424_SUITE.erl new file mode 100644 index 0000000..9640307 --- /dev/null +++ b/test/rfc5424_SUITE.erl @@ -0,0 +1,141 @@ +%%%------------------------------------------------------------------- +%%% @author Mathieu Kerjouan +%%% @copyright 2022 (c) Mathieu Kerjouan +%%% +%%% @doc +%%% @end +%%%------------------------------------------------------------------- +-module(rfc5424_SUITE). +-compile(export_all). +-include_lib("common_test/include/ct.hrl"). + +%%-------------------------------------------------------------------- +%% @doc +%% @end +%%-------------------------------------------------------------------- +-spec suite() -> Return when + Return :: [tuple()]. +suite() -> + [{timetrap,{seconds,30}}]. + +%%-------------------------------------------------------------------- +%% @doc +%% @end +%%-------------------------------------------------------------------- +-spec init_per_suite(Config) -> Return when + Config :: [tuple()], + Reason :: term(), + Return :: Config | {skip,Reason} | {skip_and_save,Reason,Config}. +init_per_suite(Config) -> + Config. + +%%-------------------------------------------------------------------- +%% @doc +%% @end +%%-------------------------------------------------------------------- +-spec end_per_suite(Config) -> Return when + Config :: [tuple()], + Return :: term() | {save_config,Config}. +end_per_suite(_Config) -> + ok. + +%%-------------------------------------------------------------------- +%% @doc +%% @end +%%-------------------------------------------------------------------- +-spec init_per_group(GroupName, Config) -> Return when + GroupName :: atom(), + Config :: [tuple()], + Reason :: term(), + Return :: Config | {skip,Reason} | {skip_and_save,Reason,Config}. +init_per_group(_GroupName, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% @doc +%% @end +%%-------------------------------------------------------------------- +-spec end_per_group(GroupName, Config) -> Return when + GroupName :: atom(), + Config :: [tuple()], + Return :: term() | {save_config,Config}. +end_per_group(_GroupName, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% @doc +%% @end +%%-------------------------------------------------------------------- +-spec init_per_testcase(TestCase, Config) -> Return when + TestCase :: atom(), + Config :: [tuple()], + Reason :: term(), + Return :: Config | {skip,Reason} | {skip_and_save,Reason,Config}. +init_per_testcase(_TestCase, Config) -> + Config. + +%%-------------------------------------------------------------------- +%% @doc +%% @end +%%-------------------------------------------------------------------- +-spec end_per_testcase(TestCase, Config) -> Return when + TestCase :: atom(), + Config :: [tuple()], + Reason :: term(), + Return :: term() | {save_config,Config} | {fail,Reason}. +end_per_testcase(_TestCase, _Config) -> + ok. + +%%-------------------------------------------------------------------- +%% @doc +%% @end +%%-------------------------------------------------------------------- +-spec groups() -> Return when + Group :: {GroupName,Properties,GroupsAndTestCases}, + GroupName :: atom(), + Properties :: [parallel | sequence | Shuffle | {RepeatType,N}], + GroupsAndTestCases :: [Group | {group,GroupName} | TestCase], + TestCase :: atom(), + Shuffle :: shuffle | {shuffle,{integer(),integer(),integer()}}, + RepeatType :: repeat | repeat_until_all_ok | repeat_until_all_fail | + repeat_until_any_ok | repeat_until_any_fail, + N :: integer() | forever, + Return :: [Group]. +groups() -> + []. + +%%-------------------------------------------------------------------- +%% @doc +%% @end +%%-------------------------------------------------------------------- +-spec all() -> Return when + GroupsAndTestCases :: [{group,GroupName} | TestCase], + GroupName :: atom(), + TestCase :: atom(), + Reason :: term(), + Return :: GroupsAndTestCases | {skip,Reason}. +all() -> + [my_test_case]. + +%%-------------------------------------------------------------------- +%% @doc +%% @end +%%-------------------------------------------------------------------- +-spec my_test_case() -> Return when + Return :: [tuple()]. +my_test_case() -> + []. + +%%-------------------------------------------------------------------- +%% @doc +%% @end +%%-------------------------------------------------------------------- +-spec my_test_case(Config) -> Return when + Config :: [tuple()], + Reason :: term(), + Comment :: term(), + Return :: ok | erlang:exit() | {skip,Reason} | {comment,Comment} | + {save_config,Config} | {skip_and_save,Reason,Config}. +my_test_case(_Config) -> + ok. +