diff options
author | Magnus <mfeuer@jaguarlandrover.com> | 2014-07-26 12:57:56 -0700 |
---|---|---|
committer | Magnus <mfeuer@jaguarlandrover.com> | 2014-07-26 12:57:56 -0700 |
commit | 3d10497be8659df18917d03013de9d9a74aca232 (patch) | |
tree | 159e847dc053e52216bccd74a226018f45b9fc67 | |
parent | 186ee249f9a5846ec2db24bf12a4e647246ebf82 (diff) | |
download | rvi_core-3d10497be8659df18917d03013de9d9a74aca232.tar.gz |
Initial gerrit commit
Signed-off-by: Magnus <mfeuer@jaguarlandrover.com>
-rw-r--r-- | Makefile | 40 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | curl_scripts/register_service.sh | 31 | ||||
-rwxr-xr-x | find_setup_gen.sh | 17 | ||||
-rw-r--r-- | priv/setup.config | 57 | ||||
-rw-r--r-- | rebar.config | 9 | ||||
-rw-r--r-- | src/service_edge.app.src | 14 | ||||
-rw-r--r-- | src/service_edge_app.erl | 22 | ||||
-rw-r--r-- | src/service_edge_rpc.erl | 194 | ||||
-rw-r--r-- | src/service_edge_sup.erl | 31 |
10 files changed, 416 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4da5223 --- /dev/null +++ b/Makefile @@ -0,0 +1,40 @@ +.PHONY: all deps compile setup clean doc + + +NAME=service_edge +export KVDB_BACKENDS=ets + +SETUP_GEN=$(shell ./find_setup_gen.sh) + +all: deps compile + +deps: + rebar get-deps + +compile: + rebar compile + +recomp: + rebar compile skip_deps=true + +setup: + ERL_LIBS=$(PWD)/deps:$(ERL_LIBS):$(PWD) \ + $(SETUP_GEN) $(NAME) priv/setup.config setup + +target: + ERL_LIBS=$(PWD)/deps:$(ERL_LIBS) \ + $(SETUP_GEN) $(NAME) priv/setup.config setup -pz $(PWD)/ebin \ + -target rel -vsn 0.1 + +run: setup + erl -boot setup/start -config setup/sys + +doc: + REBAR_DOC=1 rebar skip_deps=true get-deps doc + +clean: + rebar clean + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..9c0852f --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +Better documentation will come. diff --git a/curl_scripts/register_service.sh b/curl_scripts/register_service.sh new file mode 100644 index 0000000..ed6400e --- /dev/null +++ b/curl_scripts/register_service.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# Create new accounts, like the ga account +# But other accounts may be create +. $HOME/.exodmrc + + #if [ $# != 2 ] +#then +# echo "Usage: $0 temperature" +# exit 255 +#fi +# the password (actually erlang node cookie) must be 100% hidden +# so this is only for testing!!!!! + +URL=http://localhost:8800/exodm/rpc +curl -u $USER_AUTH -k -X POST $URL -d @- << EOF +{ + "jsonrpc": "2.0", + + "method": "service_edge:register_service", + "id": "1", + "params": + { + "service": "hvac", + "address": "http://localhost:8901", + "methods": [ + { "access_type": "rpc", "method": "set_temperature" }, + { "access_type": "rpc", "method": "set_fan_speed" } + ] + } +} +EOF diff --git a/find_setup_gen.sh b/find_setup_gen.sh new file mode 100755 index 0000000..72cc213 --- /dev/null +++ b/find_setup_gen.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +if [ -z $ERL_LIBS ]; then + L=`pwd`/deps +else + L=`pwd`/deps:$ERL_LIBS +fi + +dirs=`echo $L | sed 's/\:/ /g'` + +for d in $dirs; do + f=$d/setup/setup_gen + if [ -f $f ]; then + echo "$f" + exit 0 + fi +done diff --git a/priv/setup.config b/priv/setup.config new file mode 100644 index 0000000..f68ece5 --- /dev/null +++ b/priv/setup.config @@ -0,0 +1,57 @@ +%% -*- erlang -*- +[ + %% Put include first, making it possible to override any defaults below + {include_lib, "exoport/priv/setup.config"}, + %% + %% Add our own app(s) + {add_apps, [asn1, + ssl, + rvi_common, + service_edge + ]}, + %% + %% Custom environment settings + {env, + [ + {service_edge, + [ + { components, + [ + { service_discovery, "http://localhost:8801" }, + { store_and_forward, "http://localhost:8802" } + ] + } + ]}, + + {setup, [{data_dir, "db"}]}, + %% Tell exoport where to find our config file + {exoport, + [ + {bert_port, 9990}, %% 9999 was taken. + {config, filename:join(CWD, "exoport.config")}, + {access, + [{redirect, [{service_edge, service_edge_rpc}]}, + {accept, service_edge_rpc} + ]}, + {exo_http, + [{port, 8800}, + {appmod, {exoport_exo_http, service_edge_rpc}}]}, + {kvdb_databases, + [{kvdb_conf, + [{file,"$DATA_DIR/kvdb_conf.db"}, + {backend,ets}, + {log_dir, "$DATA_DIR/kvdb_conf.log"}, + {log_threshold, [{writes, 1000}]}, + {save_mode, [on_switch, on_close]}, + {tables,[data]}, + {encoding,{raw,term,term}}, + {schema,kvdb_schema_events}]} + ]} + ]} + %% %% We run with a logging ETS backend in the database + %% {kvdb, + %% [ + %% ]} + %% ]} + ]} +]. diff --git a/rebar.config b/rebar.config new file mode 100644 index 0000000..a85e8ea --- /dev/null +++ b/rebar.config @@ -0,0 +1,9 @@ +%% -*- erlang -*- + +{erl_opts, [debug_info]}. + +{deps, + [ + {setup, ".*", {git, "https://github.com/uwiger/setup.git", "HEAD"}}, + {rvi_common, ".*", {git, "https://gerrit.automotivelinux.org/gerrit/RVI/rvi_common", "HEAD"}} + ]}. diff --git a/src/service_edge.app.src b/src/service_edge.app.src new file mode 100644 index 0000000..2eb353f --- /dev/null +++ b/src/service_edge.app.src @@ -0,0 +1,14 @@ +%% -*- erlang -*- +{application, service_edge, + [ + {description, ""}, + {vsn, "0.1"}, + {registered, []}, + {applications, [ + kernel, + stdlib, + rvi_common + ]}, + {mod, { service_edge_app, []}}, + {start_phases, [{init, []}]} + ]}. diff --git a/src/service_edge_app.erl b/src/service_edge_app.erl new file mode 100644 index 0000000..2b57a7a --- /dev/null +++ b/src/service_edge_app.erl @@ -0,0 +1,22 @@ +-module(service_edge_app). + +-behaviour(application). + +%% Application callbacks +-export([start/2, + start_phase/3, + stop/1]). + +%% =================================================================== +%% Application callbacks +%% =================================================================== + +start(_StartType, _StartArgs) -> + service_edge_sup:start_link(). + +start_phase(init, _, _) -> + service_edge_rpc:init(), + ok. + +stop(_State) -> + ok. diff --git a/src/service_edge_rpc.erl b/src/service_edge_rpc.erl new file mode 100644 index 0000000..383c46f --- /dev/null +++ b/src/service_edge_rpc.erl @@ -0,0 +1,194 @@ +-module(service_edge_rpc). + + +-export([handle_rpc/2]). +-export([init/0]). + +%%-include_lib("lhttpc/include/lhttpc.hrl"). +-include_lib("lager/include/log.hrl"). + +%% Called by service_edge_app:start_phase(). +init() -> + case rvi_common:get_component_config(service_edge, exo_http_opts) of + { ok, ExoHttpOpts } -> + exoport_exo_http:instance(service_edge_sup, + service_edge_rpc, + ExoHttpOpts); + Err -> Err + end. + + +register_service(Service, Address) -> + ?debug("service_edge_rpc:register_service(): service: ~p ", [Service]), + ?debug("service_edge_rpc:register_service(): address: ~p ", [Address]), + + case + rvi_common:send_component_request(service_discovery, register_service, + [ + {service, Service}, + {network_address, Address} + ]) of + { ok, JSONStatus, _JSON} -> + { ok, [ {status, rvi_common:json_rpc_status(JSONStatus)} ] }; + + Err -> + ?debug("service_edge_rpc:register_service() Failed at service_discovery(): ~p", + [ Err ]), + Err + end. + +%% +%% Handle a message, delivered from a locally connected service, that is +%% to be forwarded to a remote service. +%% +handle_local_message(Target, Timeout, Parameters, CallingService) -> + ?debug("service_edge_rpc:call(): target: ~p", [Target]), + ?debug("service_edge_rpc:call(): timeout: ~p", [Timeout]), + ?debug("service_edge_rpc:call(): parameters: ~p", [Parameters]), + ?debug("service_edge_rpc:call(): calling_service: ~p", [CallingService]), + + case + rvi_common:send_component_request(authorize, authorize_local_message, + [ + {calling_service, CallingService}, + {target, Target} + ], + [ certificate, signature ]) of + { ok, ok, [Certificate, Signature], _AuthJSON } -> + case + rvi_common:send_component_request(service_discovery, + resolve_service, + [ {service, Target} ], + [ network_address ]) of + { ok, ok, [ NetworkAddress], _SDJSON } -> + + %% Remember this transaction ID for the reply + %% so that we know where to send the reply. + + %% Ask Schedule the request to resolve the network address + case + rvi_common:send_component_request(schedule, schedule_message, + [ + { timeout, Timeout }, + { parameters, Parameters }, + { network_address, NetworkAddress }, + { certificate, Certificate }, + { signature, Signature }, + { target, Target } + ]) of + + { ok, ok, _SchJSON } -> + %% We are happy. Return. + { ok, [ { status, rvi_common:json_rpc_status(ok)} ] }; + + Err -> + ?debug("service_edge_rpc:register_service() Failed at scheduling: ~p", + [ Err ]), + Err + end; + + Err -> + ?debug("service_edge_rpc:register_service() Failed at service discovery: ~p", + [ Err ]), + Err + end; + + Err -> + ?debug("service_edge_rpc:register_service() Failed at authorize: ~p", + [ Err ]), + Err + end. + + +%% +%% Handle a message, delivered from a remote node through protocol, that is +%% to be forwarded to a locally connected service. +%% +handle_remote_message(Target, Timeout, Parameters, Signature, Certificate) -> + ?debug("service_edge:remote_msg(): target: ~p", [Target]), + ?debug("service_edge:remote_msg(): timeout: ~p", [Timeout]), + ?debug("service_edge:remote_msg(): parameters: ~p", [Parameters]), + ?debug("service_edge:remote_msg(): signature: ~p", [Signature]), + ?debug("service_edge:remote_msg(): certificate: ~p", [Certificate]), + + case + rvi_common:send_component_request(authorize, authorize_remote_message, + [ + {target, Target}, + {certificate, Certificate}, + {signature, Signature} + ]) of + { ok, ok, _AuthJSON } -> + case + rvi_common:send_component_request(service_discovery, + resolve_service, + [ { service, Target } ], + [ network_address ]) of + { ok, ok, [ NetworkAddress], _SDJSON } -> + case + %% Deliver the message to the local service + rvi_common:get_request_result( + rvi_common:send_http_request(NetworkAddress, + "message", + [ { target, Target }, + { parameters, Parameters }])) of + + %% Request delivered. + { ok, ok, _ } -> + { ok, [ { status, rvi_common:json_rpc_status(ok)} ] }; + + %% Request delivered (with no status reply) + {ok, undefined } -> + { ok, [ { status, rvi_common:json_rpc_status(ok)} ] }; + + %% status returned was an error code. + { ok, Status, _ } -> + { error, { json_rpc, rvi_common:json_rpc_status(Status)}}; + + %% HTTP or similar error. + Err -> + Err + end; + + %% service discovery failed. + _ -> { error, { unknown_target, Target}} + end; + + %% Authorization failed. + { ok, Err, _} -> + {error, { authorization, Err }}; + + %% Authorization component error (HTTP, or similar). + Err -> Err + end. + + +%% JSON-RPC entry point +%% Called by local exo http server +handle_rpc("register_service", Args) -> + {ok, Service} = rvi_common:get_json_element(["service"], Args), + {ok, Address} = rvi_common:get_json_element(["network_address"], Args), + register_service(Service, Address); + + +handle_rpc("message", Args) -> + {ok, Target} = rvi_common:get_json_element(["target"], Args), + {ok, Timeout} = rvi_common:get_json_element(["timeout"], Args), + {ok, Parameters} = rvi_common:get_json_element(["parameters"], Args), + {ok, CallingService} = rvi_common:get_json_element(["calling_service"], Args), + handle_local_message( Target, Timeout, Parameters, CallingService); + +handle_rpc("handle_remote_message", Args) -> + { ok, Target } = rvi_common:get_json_element(["target"], Args), + { ok, Timeout } = rvi_common:get_json_element(["timeout"], Args), + { ok, Parameters } = rvi_common:get_json_element(["parameters"], Args), + { ok, Certificate } = rvi_common:get_json_element(["certificate"], Args), + { ok, Signature } = rvi_common:get_json_element(["signature"], Args), + handle_remote_message( Target, Timeout, Parameters, Certificate, Signature); + + + +handle_rpc(Other, _Args) -> + ?debug("service_edge_rpc:handle_rpc(~p): unknown command", [ Other ]), + { ok, [ { status, rvi_common:json_rpc_status(invalid_command)} ] }. + diff --git a/src/service_edge_sup.erl b/src/service_edge_sup.erl new file mode 100644 index 0000000..c877d83 --- /dev/null +++ b/src/service_edge_sup.erl @@ -0,0 +1,31 @@ +-module(service_edge_sup). + +-behaviour(supervisor). + +%% API +-export([start_link/0]). + +%% Supervisor callbacks +-export([init/1]). + +%% Helper macro for declaring children of supervisor +-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}). + +%% =================================================================== +%% API functions +%% =================================================================== + +start_link() -> + supervisor:start_link({local, ?MODULE}, ?MODULE, []). + +%% =================================================================== +%% Supervisor callbacks +%% =================================================================== + +init([]) -> + {ok, { {one_for_one, 5, 10}, + [ + %% ?CHILD(some_module, worker), + %% ?CHILD(exodmo_config, worker) + ]} }. + |