Loading proto/context.proto +1 −0 Original line number Diff line number Diff line Loading @@ -273,6 +273,7 @@ enum ServiceTypeEnum { SERVICETYPE_L3NM = 1; SERVICETYPE_L2NM = 2; SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3; SERVICETYPE_TE = 4; } enum ServiceStatusEnum { Loading src/context/service/database/models/enums/ServiceType.py +1 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ class ORM_ServiceTypeEnum(enum.Enum): L3NM = ServiceTypeEnum.SERVICETYPE_L3NM L2NM = ServiceTypeEnum.SERVICETYPE_L2NM TAPI_CONNECTIVITY_SERVICE = ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE TE = ServiceTypeEnum.SERVICETYPE_TE grpc_to_enum__service_type = functools.partial( grpc_to_enum, ServiceTypeEnum, ORM_ServiceTypeEnum) src/te/apps/epce/src/epce_server.erl +10 −6 Original line number Diff line number Diff line Loading @@ -181,12 +181,16 @@ terminate(_Reason, _State) -> %%% INTERNAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% compute_path({1, 1, 1, 1}, {6, 6, 6, 6}) -> {ok, [16020, 16040, 16060]}; compute_path({6, 6, 6, 6}, {1, 1, 1, 1}) -> {ok, [16040, 16020, 16010]}; compute_path(_Src, _Dst) -> {error, nopath}. compute_path(From, To) -> case epce_ted:compute_path(pcc_address, From, To) of {ok, Devices} -> Labels = tl([L || #{mpls_label := L} <- Devices, L =/= undefined]), logger:debug("Route from ~p to ~p: ~p", [From, To, Labels]), {ok, Labels}; {error, Reason} -> logger:warning("Failed to find a route from ~p to ~p", [From, To]), {error, Reason} end. route_from_labels(Source, Destination, Constraints, Labels) -> #{ Loading src/te/apps/epce/src/epce_sup.erl +12 −6 Original line number Diff line number Diff line Loading @@ -12,14 +12,14 @@ %%% MACROS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -define(SERVER, ?MODULE). -define(PCE_SERVER, epce_server). -define(TED_WORKER, epce_ted). -define(PCE_WORKER, epce_server). %%% BEHAVIOUR SUPERVISOR FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> SupFlags = #{ Loading @@ -27,11 +27,17 @@ init([]) -> intensity => 0, period => 1 }, TEDSpec = #{ id => ?TED_WORKER, start => {?TED_WORKER, start_link, []}, restart => permanent, shutdown => brutal_kill }, ServerSpec = #{ id => ?PCE_SERVER, start => {?PCE_SERVER, start_link, []}, id => ?PCE_WORKER, start => {?PCE_WORKER, start_link, []}, restart => permanent, shutdown => brutal_kill }, {ok, {SupFlags, [ServerSpec]}}. {ok, {SupFlags, [TEDSpec, ServerSpec]}}. src/te/apps/epce/src/epce_ted.erl 0 → 100644 +203 −0 Original line number Diff line number Diff line -module(epce_ted). -behaviour(gen_server). %%% INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -include_lib("kernel/include/logger.hrl"). %%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % API Functions -export([start_link/0]). -export([device_added/2]). -export([device_updated/2]). -export([device_deleted/1]). -export([link_added/2]). -export([link_updated/2]). -export([link_deleted/1]). -export([compute_path/3]). -export([get_graph/0]). % Behaviour gen_server functions -export([init/1]). -export([handle_call/3]). -export([handle_cast/2]). -export([handle_continue/2]). -export([handle_info/2]). -export([code_change/3]). -export([terminate/2]). %%% RECORDS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -record(state, { graph :: diagraph:graph(), pcc_address_to_id = #{} :: map() }). %%% API FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). device_added(Id, Device) -> gen_server:call(?MODULE, {device_added, Id, Device}). device_updated(Id, Device) -> gen_server:call(?MODULE, {device_updated, Id, Device}). device_deleted(Id) -> gen_server:call(?MODULE, {device_deleted, Id}). link_added(Id, Link) -> gen_server:call(?MODULE, {link_added, Id, Link}). link_updated(Id, Link) -> gen_server:call(?MODULE, {link_updated, Id, Link}). link_deleted(Id) -> gen_server:call(?MODULE, {link_deleted, Id}). compute_path(Index, From, To) when Index =:= id; Index =:= pcc_address -> gen_server:call(?MODULE, {compute_path, Index, From, To}); compute_path(Index, _From, _To) -> {error, {invalid_index, Index}}. get_graph() -> gen_server:call(?MODULE, get_graph). %%% BEHAVIOUR gen_server FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% init([]) -> ?LOG_INFO("Starting TED process...", []), % {ok, #state{graph = digraph:new([private, cyclic])}}. {ok, #state{graph = digraph:new([protected, cyclic])}}. handle_call({device_added, Id, Device}, _From, State) -> ?LOG_DEBUG("Adding TED device ~p: ~p", [Id, Device]), {reply, ok, do_update_device(State, Id, Device)}; handle_call({device_updated, Id, Device}, _From, State) -> ?LOG_DEBUG("Updating TED device ~p: ~p", [Id, Device]), {reply, ok, do_update_device(State, Id, Device)}; handle_call({device_deleted, Id}, _From, State) -> ?LOG_DEBUG("Deleting TED device ~p", [Id]), {reply, ok, do_delete_device(State, Id)}; handle_call({link_added, Id, Link}, _From, State) -> ?LOG_DEBUG("Adding TED link ~p: ~p", [Id, Link]), {reply, ok, do_update_link(State, Id, Link)}; handle_call({link_updated, Id, Link}, _From, State) -> ?LOG_DEBUG("Updating TED link ~p: ~p", [Id, Link]), {reply, ok, do_update_link(State, Id, Link)}; handle_call({link_deleted, Id}, _From, State) -> ?LOG_DEBUG("Deleting TED link ~p", [Id]), {reply, ok, do_delete_link(State, Id)}; handle_call({compute_path, Index, From, To}, _From, #state{graph = G} = State) -> case as_ids(State, Index, [From, To]) of {ok, [FromId, ToId]} -> {reply, do_compute_path(G, FromId, ToId), State}; {error, Reason} -> {reply, {error, Reason}, State} end; handle_call(get_graph, _From, #state{graph = G} = State) -> {reply, G, State}; handle_call(Request, _From, State) -> logger:warning("Unexpected call to TED process ~w", [Request]), {reply, {error, unexpected_call}, State}. handle_cast(Request, State) -> logger:warning("Unexpected cast to TED process ~w", [Request]), {noreply, State}. handle_continue(_Continue, State) -> {noreply, State}. handle_info(Info, State) -> logger:warning("Unexpected message to TED process ~w", [Info]), {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. terminate(_Reason, _State) -> ?LOG_INFO("Terminating TED process...", []), ok. %%% INTERNAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% as_ids(_State, id, Keys) -> {ok, Keys}; as_ids(State, IndexType, Keys) -> as_ids(State, IndexType, Keys, []). as_ids(_State, _IndexType, [], Acc) -> {ok, lists:reverse(Acc)}; as_ids(#state{pcc_address_to_id = Index} = State, pcc_address, [Key | Rest], Acc) -> case maps:find(Key, Index) of error -> {error, {unknown_key, Key}}; {ok, Id} -> as_ids(State, pcc_address, Rest, [Id | Acc]) end. do_update_device(#state{graph = G} = State, Id, NewDevice) -> State2 = case digraph:vertex(G, Id) of false -> State; {Id, OldDevice} -> index_remove_device(State, OldDevice) end, digraph:add_vertex(G, Id, NewDevice), index_add_device(State2, NewDevice). do_delete_device(#state{graph = G} = State, Id) -> case digraph:vertex(G, Id) of false -> State; {Id, OldDevice} -> digraph:del_vertex(G, Id), index_remove_device(State, OldDevice) end. index_remove_device(#state{pcc_address_to_id = Index} = State, #{pcc_address := OldAddress}) -> Index2 = maps:remove(OldAddress, Index), State#state{pcc_address_to_id = Index2}. index_add_device(State, #{pcc_address := undefined}) -> State; index_add_device(#state{pcc_address_to_id = Index} = State, #{id := Id, pcc_address := NewAddress}) -> Index2 = Index#{NewAddress => Id}, State#state{pcc_address_to_id = Index2}. do_update_link(#state{graph = G} = State, Id, Link) -> #{endpoints := [EP1, EP2]} = Link, #{device := D1} = EP1, #{device := D2} = EP2, digraph:add_edge(G, {Id, a}, D1, D2, Link), digraph:add_edge(G, {Id, b}, D2, D1, Link), State. do_delete_link(#state{graph = G} = State, Id) -> digraph:del_edge(G, {Id, a}), digraph:del_edge(G, {Id, b}), State. do_compute_path(G, FromId, ToId) -> case digraph:get_short_path(G, FromId, ToId) of false -> {error, not_found}; Ids -> {ok, retrieve_devices(G, Ids, [])} end. retrieve_devices(_G, [], Acc) -> lists:reverse(Acc); retrieve_devices(G, [Id | Rest], Acc) -> case digraph:vertex(G, Id) of false -> {error, invalid_path}; {Id, Device} -> retrieve_devices(G, Rest, [Device | Acc]) end. Loading
proto/context.proto +1 −0 Original line number Diff line number Diff line Loading @@ -273,6 +273,7 @@ enum ServiceTypeEnum { SERVICETYPE_L3NM = 1; SERVICETYPE_L2NM = 2; SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3; SERVICETYPE_TE = 4; } enum ServiceStatusEnum { Loading
src/context/service/database/models/enums/ServiceType.py +1 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ class ORM_ServiceTypeEnum(enum.Enum): L3NM = ServiceTypeEnum.SERVICETYPE_L3NM L2NM = ServiceTypeEnum.SERVICETYPE_L2NM TAPI_CONNECTIVITY_SERVICE = ServiceTypeEnum.SERVICETYPE_TAPI_CONNECTIVITY_SERVICE TE = ServiceTypeEnum.SERVICETYPE_TE grpc_to_enum__service_type = functools.partial( grpc_to_enum, ServiceTypeEnum, ORM_ServiceTypeEnum)
src/te/apps/epce/src/epce_server.erl +10 −6 Original line number Diff line number Diff line Loading @@ -181,12 +181,16 @@ terminate(_Reason, _State) -> %%% INTERNAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% compute_path({1, 1, 1, 1}, {6, 6, 6, 6}) -> {ok, [16020, 16040, 16060]}; compute_path({6, 6, 6, 6}, {1, 1, 1, 1}) -> {ok, [16040, 16020, 16010]}; compute_path(_Src, _Dst) -> {error, nopath}. compute_path(From, To) -> case epce_ted:compute_path(pcc_address, From, To) of {ok, Devices} -> Labels = tl([L || #{mpls_label := L} <- Devices, L =/= undefined]), logger:debug("Route from ~p to ~p: ~p", [From, To, Labels]), {ok, Labels}; {error, Reason} -> logger:warning("Failed to find a route from ~p to ~p", [From, To]), {error, Reason} end. route_from_labels(Source, Destination, Constraints, Labels) -> #{ Loading
src/te/apps/epce/src/epce_sup.erl +12 −6 Original line number Diff line number Diff line Loading @@ -12,14 +12,14 @@ %%% MACROS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -define(SERVER, ?MODULE). -define(PCE_SERVER, epce_server). -define(TED_WORKER, epce_ted). -define(PCE_WORKER, epce_server). %%% BEHAVIOUR SUPERVISOR FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> SupFlags = #{ Loading @@ -27,11 +27,17 @@ init([]) -> intensity => 0, period => 1 }, TEDSpec = #{ id => ?TED_WORKER, start => {?TED_WORKER, start_link, []}, restart => permanent, shutdown => brutal_kill }, ServerSpec = #{ id => ?PCE_SERVER, start => {?PCE_SERVER, start_link, []}, id => ?PCE_WORKER, start => {?PCE_WORKER, start_link, []}, restart => permanent, shutdown => brutal_kill }, {ok, {SupFlags, [ServerSpec]}}. {ok, {SupFlags, [TEDSpec, ServerSpec]}}.
src/te/apps/epce/src/epce_ted.erl 0 → 100644 +203 −0 Original line number Diff line number Diff line -module(epce_ted). -behaviour(gen_server). %%% INCLUDES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -include_lib("kernel/include/logger.hrl"). %%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % API Functions -export([start_link/0]). -export([device_added/2]). -export([device_updated/2]). -export([device_deleted/1]). -export([link_added/2]). -export([link_updated/2]). -export([link_deleted/1]). -export([compute_path/3]). -export([get_graph/0]). % Behaviour gen_server functions -export([init/1]). -export([handle_call/3]). -export([handle_cast/2]). -export([handle_continue/2]). -export([handle_info/2]). -export([code_change/3]). -export([terminate/2]). %%% RECORDS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -record(state, { graph :: diagraph:graph(), pcc_address_to_id = #{} :: map() }). %%% API FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). device_added(Id, Device) -> gen_server:call(?MODULE, {device_added, Id, Device}). device_updated(Id, Device) -> gen_server:call(?MODULE, {device_updated, Id, Device}). device_deleted(Id) -> gen_server:call(?MODULE, {device_deleted, Id}). link_added(Id, Link) -> gen_server:call(?MODULE, {link_added, Id, Link}). link_updated(Id, Link) -> gen_server:call(?MODULE, {link_updated, Id, Link}). link_deleted(Id) -> gen_server:call(?MODULE, {link_deleted, Id}). compute_path(Index, From, To) when Index =:= id; Index =:= pcc_address -> gen_server:call(?MODULE, {compute_path, Index, From, To}); compute_path(Index, _From, _To) -> {error, {invalid_index, Index}}. get_graph() -> gen_server:call(?MODULE, get_graph). %%% BEHAVIOUR gen_server FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% init([]) -> ?LOG_INFO("Starting TED process...", []), % {ok, #state{graph = digraph:new([private, cyclic])}}. {ok, #state{graph = digraph:new([protected, cyclic])}}. handle_call({device_added, Id, Device}, _From, State) -> ?LOG_DEBUG("Adding TED device ~p: ~p", [Id, Device]), {reply, ok, do_update_device(State, Id, Device)}; handle_call({device_updated, Id, Device}, _From, State) -> ?LOG_DEBUG("Updating TED device ~p: ~p", [Id, Device]), {reply, ok, do_update_device(State, Id, Device)}; handle_call({device_deleted, Id}, _From, State) -> ?LOG_DEBUG("Deleting TED device ~p", [Id]), {reply, ok, do_delete_device(State, Id)}; handle_call({link_added, Id, Link}, _From, State) -> ?LOG_DEBUG("Adding TED link ~p: ~p", [Id, Link]), {reply, ok, do_update_link(State, Id, Link)}; handle_call({link_updated, Id, Link}, _From, State) -> ?LOG_DEBUG("Updating TED link ~p: ~p", [Id, Link]), {reply, ok, do_update_link(State, Id, Link)}; handle_call({link_deleted, Id}, _From, State) -> ?LOG_DEBUG("Deleting TED link ~p", [Id]), {reply, ok, do_delete_link(State, Id)}; handle_call({compute_path, Index, From, To}, _From, #state{graph = G} = State) -> case as_ids(State, Index, [From, To]) of {ok, [FromId, ToId]} -> {reply, do_compute_path(G, FromId, ToId), State}; {error, Reason} -> {reply, {error, Reason}, State} end; handle_call(get_graph, _From, #state{graph = G} = State) -> {reply, G, State}; handle_call(Request, _From, State) -> logger:warning("Unexpected call to TED process ~w", [Request]), {reply, {error, unexpected_call}, State}. handle_cast(Request, State) -> logger:warning("Unexpected cast to TED process ~w", [Request]), {noreply, State}. handle_continue(_Continue, State) -> {noreply, State}. handle_info(Info, State) -> logger:warning("Unexpected message to TED process ~w", [Info]), {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. terminate(_Reason, _State) -> ?LOG_INFO("Terminating TED process...", []), ok. %%% INTERNAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% as_ids(_State, id, Keys) -> {ok, Keys}; as_ids(State, IndexType, Keys) -> as_ids(State, IndexType, Keys, []). as_ids(_State, _IndexType, [], Acc) -> {ok, lists:reverse(Acc)}; as_ids(#state{pcc_address_to_id = Index} = State, pcc_address, [Key | Rest], Acc) -> case maps:find(Key, Index) of error -> {error, {unknown_key, Key}}; {ok, Id} -> as_ids(State, pcc_address, Rest, [Id | Acc]) end. do_update_device(#state{graph = G} = State, Id, NewDevice) -> State2 = case digraph:vertex(G, Id) of false -> State; {Id, OldDevice} -> index_remove_device(State, OldDevice) end, digraph:add_vertex(G, Id, NewDevice), index_add_device(State2, NewDevice). do_delete_device(#state{graph = G} = State, Id) -> case digraph:vertex(G, Id) of false -> State; {Id, OldDevice} -> digraph:del_vertex(G, Id), index_remove_device(State, OldDevice) end. index_remove_device(#state{pcc_address_to_id = Index} = State, #{pcc_address := OldAddress}) -> Index2 = maps:remove(OldAddress, Index), State#state{pcc_address_to_id = Index2}. index_add_device(State, #{pcc_address := undefined}) -> State; index_add_device(#state{pcc_address_to_id = Index} = State, #{id := Id, pcc_address := NewAddress}) -> Index2 = Index#{NewAddress => Id}, State#state{pcc_address_to_id = Index2}. do_update_link(#state{graph = G} = State, Id, Link) -> #{endpoints := [EP1, EP2]} = Link, #{device := D1} = EP1, #{device := D2} = EP2, digraph:add_edge(G, {Id, a}, D1, D2, Link), digraph:add_edge(G, {Id, b}, D2, D1, Link), State. do_delete_link(#state{graph = G} = State, Id) -> digraph:del_edge(G, {Id, a}), digraph:del_edge(G, {Id, b}), State. do_compute_path(G, FromId, ToId) -> case digraph:get_short_path(G, FromId, ToId) of false -> {error, not_found}; Ids -> {ok, retrieve_devices(G, Ids, [])} end. retrieve_devices(_G, [], Acc) -> lists:reverse(Acc); retrieve_devices(G, [Id | Rest], Acc) -> case digraph:vertex(G, Id) of false -> {error, invalid_path}; {Id, Device} -> retrieve_devices(G, Rest, [Device | Acc]) end.