Skip to content

Commit 57ac719

Browse files
author
Szymon Mentel
committed
Merge pull request #2 from shivarammysore/api_update
Api update
2 parents 851b60a + a00782f commit 57ac719

7 files changed

Lines changed: 212 additions & 108 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ eunit: compile
1616
./rebar -v skip_deps=true eunit
1717

1818
ct: compile
19-
./rebar -v ct
19+
./rebar -v ct $(CTARGS)
2020

2121
distclean: clean
2222
./rebar delete-deps

src/dobby_oflib.erl

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
%% API
1111
-export([get_path/2,
12-
publish_new_flow/3]).
12+
publish_new_flow/4]).
1313

1414
-include_lib("dobby_clib/include/dobby.hrl").
1515
-include("dobby_oflib.hrl").
@@ -47,14 +47,14 @@ get_path(SrcEndpoint, DstEndpoint) ->
4747
%%
4848
%% The function returns Net Flow Identifier: `NetFlowId' that can be
4949
%% used for referencing published Net Flow.
50-
-spec publish_new_flow(dby_identifier(), dby_identifier(), flow_path()) ->
51-
Result when
50+
-spec publish_new_flow(binary(), dby_identifier(), dby_identifier(), flow_path())
51+
-> Result when
5252
Result :: {ok, NetFlowId :: dby_endpoint()}
5353
| {error, Reason :: term()}.
5454

55-
publish_new_flow(SrcEndpoint, DstEndpoint, FlowPath) ->
56-
NfId = publish_net_flow_identifier(SrcEndpoint, DstEndpoint),
57-
publish_flow_path(NfId, FlowPath),
55+
publish_new_flow(PublisherId, SrcEndpoint, DstEndpoint, FlowPath) ->
56+
NfId = publish_net_flow_identifier(PublisherId, SrcEndpoint, DstEndpoint),
57+
publish_flow_path(PublisherId, NfId, FlowPath),
5858
lager:info("Published NetFlow: ~p between endpoints src: ~p dst: ~p ~n",
5959
[NfId, SrcEndpoint, DstEndpoint]),
6060
{ok, NfId}.
@@ -63,38 +63,41 @@ publish_new_flow(SrcEndpoint, DstEndpoint, FlowPath) ->
6363
%%% Internal functions
6464
%%%=============================================================================
6565

66-
publish_net_flow_identifier(Src, Dst) ->
67-
%% TODO: In transaction
66+
publish_net_flow_identifier(PublisherId, Src, Dst) ->
6867
NfNode = {NfId, _NfMetadata} = dofl_identifier:net_flow(Src, Dst),
69-
publish(Src, NfNode,
68+
publish(PublisherId, Src, NfNode,
7069
dofl_link_metadata:endpoint_with_net_flow(Src)),
71-
publish(NfId, Dst,
70+
publish(PublisherId, NfId, Dst,
7271
dofl_link_metadata:endpoint_with_net_flow(NfId)),
7372
NfId.
7473

75-
publish_flow_path(NetFlowId, FlowPath0) ->
74+
publish_flow_path(PublisherId, NetFlowId, FlowPath0) ->
7675
FlowPath1 = reconstruct_flow_path(FlowPath0),
77-
publish_flow_path(NetFlowId, FlowPath1, NetFlowId).
76+
publish_flow_path(PublisherId, NetFlowId, FlowPath1, NetFlowId).
7877

79-
publish_flow_path(NetFlowId, [ExtendedFlowMod | T], LastId)
78+
publish_flow_path(PublisherId, NetFlowId, [ExtendedFlowMod | T], LastId)
8079
when LastId =:= NetFlowId ->
81-
publish(NetFlowId,
80+
publish(PublisherId,
81+
NetFlowId,
8282
{Id, _Md} = flow_mod_identifier(ExtendedFlowMod),
8383
dofl_link_metadata:net_flow_with_flow_mod(NetFlowId, NetFlowId)),
84-
publish(Id,
84+
publish(PublisherId,
85+
Id,
8586
flow_table_identifier(ExtendedFlowMod),
8687
dofl_link_metadata:flow_mod_with_flow_table()),
87-
publish_flow_path(NetFlowId, T, Id);
88-
publish_flow_path(NetFlowId, [ExtendedFlowMod | T], LastId) ->
89-
publish(LastId,
88+
publish_flow_path(PublisherId, NetFlowId, T, Id);
89+
publish_flow_path(PublisherId, NetFlowId, [ExtendedFlowMod | T], LastId) ->
90+
publish(PublisherId,
91+
LastId,
9092
{Id, _Md} = flow_mod_identifier(ExtendedFlowMod),
9193
dofl_link_metadata:between_flow_mods(LastId, NetFlowId)),
92-
publish(Id,
94+
publish(PublisherId,
95+
Id,
9396
flow_table_identifier(ExtendedFlowMod),
9497
dofl_link_metadata:flow_mod_with_flow_table()),
95-
publish_flow_path(NetFlowId, T, Id);
96-
publish_flow_path(NetFlowId, [], LastId) ->
97-
publish(LastId, NetFlowId,
98+
publish_flow_path(PublisherId, NetFlowId, T, Id);
99+
publish_flow_path(PublisherId, NetFlowId, [], LastId) ->
100+
publish(PublisherId, LastId, NetFlowId,
98101
dofl_link_metadata:net_flow_with_flow_mod(LastId, NetFlowId)).
99102

100103
flow_mod_identifier({Dpid, OFVersion, FlowMod}) ->
@@ -103,8 +106,8 @@ flow_mod_identifier({Dpid, OFVersion, FlowMod}) ->
103106
flow_table_identifier({Dpid, _OFVersion, FlowMod}) ->
104107
dofl_identifier:flow_table(Dpid, FlowMod).
105108

106-
publish(Src, Dst, LinkMetadata) ->
107-
dby:publish(Src, Dst, LinkMetadata, [persistent]).
109+
publish(PublisherId, Src, Dst, LinkMetadata) ->
110+
dofl_publish:do(PublisherId, Src, Dst, LinkMetadata).
108111

109112
reconstruct_flow_path(FlowPath0) ->
110113
Fun = fun({Dpid, {OFVersion, FlowMods}}) ->

src/dofl_identifier.erl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@
2424
-spec net_flow(dby_identifier(), dby_identifier()) -> dby_endpoint().
2525

2626
net_flow(Src, Dst) ->
27-
{<<"NF:", Src/binary, ":", Dst/binary>>, #{type => of_net_flow}}.
27+
{<<"NF:", Src/binary, ":", Dst/binary>>, [{type, of_net_flow}]}.
2828

2929
-spec flow_mod(dby_identifier(), of_version(), flow_mod()) -> dby_endpoint().
3030

3131
flow_mod(Dpid, OFVersion, FlowMod) ->
3232
{_Matches, _Instructions, Opts} = FlowMod,
3333
Cookie = proplists:get_value(cookie, Opts),
34-
{Cookie, #{type => of_flow_mod, dpid => Dpid, of_version => OFVersion}}.
34+
{Cookie, [{type, of_flow_mod}, {dpid, Dpid}, {of_version, OFVersion}]}.
3535

3636

3737
-spec flow_table(dby_identifier(), flow_mod()) -> dby_identifier().

src/dofl_link_metadata.erl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,31 @@
2424
-spec endpoint_with_net_flow(dby_identifier()) -> map().
2525

2626
endpoint_with_net_flow(Src) ->
27-
#{type => ep_to_nf, src => Src}.
27+
[{type, ep_to_nf}, {src, Src}].
2828

2929

3030
-spec net_flow_with_flow_mod(dby_identifier(), dby_identifier()) -> map().
3131

3232
net_flow_with_flow_mod(Src, NetFlowId) when Src =:= NetFlowId ->
33-
#{type => of_path_starts_at, src => Src, net_flow_ids => [NetFlowId]};
33+
of_path_link_metadata(of_path_starts_at, Src, [NetFlowId]);
3434
net_flow_with_flow_mod(Src, NetFlowId) ->
35-
#{type => of_path_ends_at, src => Src, net_flow_ids => [NetFlowId]}.
35+
of_path_link_metadata(of_path_ends_at, Src, [NetFlowId]).
3636

3737

3838
-spec between_flow_mods(dby_identifier(), dby_identifier()) -> map().
3939

4040
between_flow_mods(Src, NetFlowId) ->
41-
#{type => of_path_forwards_to, src => Src, net_flow_ids => [NetFlowId]}.
41+
of_path_link_metadata(of_path_forwards_to, Src, [NetFlowId]).
42+
4243

4344
-spec flow_mod_with_flow_table() -> map().
4445

4546
flow_mod_with_flow_table() ->
46-
#{type => of_resource}.
47+
[{type, of_resource}].
4748

4849
%%%=============================================================================
4950
%%% Internal functions
5051
%%%=============================================================================
52+
53+
of_path_link_metadata(LinkType, Src, NetFlowIds) ->
54+
[{type, LinkType}, {src, Src}, {net_flow_ids, NetFlowIds}].

src/dofl_publish.erl

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
%%%=============================================================================
2+
%%% @copyright (C) 2015, Erlang Solutions Ltd
3+
%%% @author Szymon Mentel <szymon.mentel@erlang-solutions.com>
4+
%%% @doc Module encapsulating publishing to the dobby database
5+
%%% @end
6+
%%%=============================================================================
7+
-module(dofl_publish).
8+
-copyright("2015, Erlang Solutions Ltd.").
9+
10+
%% API
11+
-export([do/4]).
12+
13+
-include_lib("dobby_clib/include/dobby.hrl").
14+
-include("dobby_oflib.hrl").
15+
16+
%%%=============================================================================
17+
%%% External functions
18+
%%%=============================================================================
19+
20+
do(PublisherId, Src, Dst, LinkMetadata) ->
21+
do_publish(PublisherId,
22+
binarize(Src),
23+
binarize(Dst),
24+
binarize_metadata(LinkMetadata)).
25+
26+
%%%=============================================================================
27+
%%% Internal functions
28+
%%%=============================================================================
29+
30+
binarize(Identifier) when is_binary(Identifier) ->
31+
Identifier;
32+
binarize({Identifier, Metadata}) when is_binary(Identifier) ->
33+
{Identifier, binarize_metadata(Metadata)}.
34+
35+
binarize_metadata(Metadata) when is_list(Metadata)->
36+
[{binarize_term(K), binarize_term(V)} || {K, V} <- Metadata].
37+
38+
binarize_term(T) when is_atom(T) ->
39+
atom_to_binary(T, utf8);
40+
binarize_term(T)
41+
when is_binary(T);
42+
is_number(T);
43+
is_function(T);
44+
is_list(T);
45+
T =:= delete;
46+
T =:= nochange ->
47+
T.
48+
49+
do_publish(PublisherId, Src, Dst, LinkMetadata) ->
50+
dby:publish(PublisherId, Src, Dst, LinkMetadata, [persistent]).

test/dobby_oflib_SUITE.erl

Lines changed: 66 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
-define(SRC_EP, <<"Src">>).
1616
-define(DST_EP, <<"Dst">>).
17+
-define(PUBLISHER_ID, <<"Publisher">>).
1718

1819
%%%=============================================================================
1920
%%% Callbacks
@@ -35,7 +36,7 @@ end_per_suite(_Config) ->
3536

3637
all() ->
3738
[should_publish_net_flow,
38-
should_publish_flow_path].
39+
should_publish_flow_path].
3940

4041
%%%=============================================================================
4142
%%% Testcases
@@ -46,65 +47,77 @@ should_publish_net_flow(_Config) ->
4647
FlowPath = dofl_test_utils:flow_path(),
4748

4849
%% WHEN
49-
{ok, NetFlowId} = dobby_oflib:publish_new_flow(?SRC_EP, ?DST_EP, FlowPath),
50+
{ok, NetFlowId} = dobby_oflib:publish_new_flow(?PUBLISHER_ID,
51+
?SRC_EP,
52+
?DST_EP,
53+
FlowPath),
5054

5155
%% THEN
52-
assert_net_flow_published(?SRC_EP, ?DST_EP, NetFlowId).
56+
assert_net_flow_published(?PUBLISHER_ID, ?SRC_EP, ?DST_EP, NetFlowId).
5357

5458
should_publish_flow_path(_Config) ->
5559
%% GIVEN
5660
FlowPath0 = dofl_test_utils:flow_path(),
5761
FlowPath1 = reconstruct_flow_path(FlowPath0),
5862

5963
%% WHEN
60-
{ok, NetFlowId} = dobby_oflib:publish_new_flow(?SRC_EP, ?DST_EP, FlowPath0),
64+
{ok, NetFlowId} = dobby_oflib:publish_new_flow(?PUBLISHER_ID,
65+
?SRC_EP,
66+
?DST_EP,
67+
FlowPath0),
6168

6269
%% THEN
63-
assert_flow_path_published(NetFlowId, FlowPath1).
70+
assert_flow_path_published(?PUBLISHER_ID, NetFlowId, FlowPath1).
6471

6572
%%%=============================================================================
6673
%%% Assertions
6774
%%%=============================================================================
6875

69-
assert_net_flow_published(SrcEP, DstEP, NetFlowId) ->
70-
?assert(meck:called(dby, publish, [SrcEP, {NetFlowId, #{type => of_net_flow}},
71-
#{type => ep_to_nf, src => SrcEP},
72-
[persistent]])),
73-
?assert(meck:called(dby, publish, [NetFlowId,
74-
DstEP,
75-
#{type => ep_to_nf, src => NetFlowId},
76-
[persistent]])).
77-
78-
79-
assert_flow_path_published(NetFlowId, FlowPath) ->
80-
assert_flow_path_published(NetFlowId, FlowPath, _PrevId = NetFlowId).
81-
82-
assert_flow_path_published(NetFlowId, [FlowMod | T], NetFlowId) ->
83-
LinkMd = link_metadata(of_path_starts_at, {NetFlowId, NetFlowId}),
84-
LinkMd2 = link_metadata(of_resource, bidirectional),
85-
FmNode = {FmId,_FmMD} = flow_mod_identifier(FlowMod),
86-
FtId = flow_table_identifier(FlowMod),
87-
?assert(meck:called(dby, publish, [NetFlowId, FmNode, LinkMd, [persistent]])),
88-
?assert(meck:called(dby, publish, [FmId, FtId, LinkMd2, [persistent]])),
89-
assert_flow_path_published(NetFlowId, T, FmId);
90-
assert_flow_path_published(NetFlowId, [FlowMod | T], LastId) ->
91-
LinkMd = link_metadata(of_path_forwards_to, {NetFlowId, LastId}),
92-
LinkMd2 = link_metadata(of_resource, bidirectional),
93-
FmNode = {FmId,_FmMD} = flow_mod_identifier(FlowMod),
94-
FtId = flow_table_identifier(FlowMod),
95-
?assert(meck:called(dby, publish, [LastId, FmNode, LinkMd, [persistent]])),
96-
?assert(meck:called(dby, publish, [FmId, FtId, LinkMd2, [persistent]])),
97-
assert_flow_path_published(NetFlowId, T, FmId);
98-
assert_flow_path_published(NetFlowId, [], LastId) ->
99-
LinkMd = link_metadata(of_path_ends_at, {NetFlowId, LastId}),
100-
?assert(meck:called(dby, publish, [LastId, NetFlowId, LinkMd, [persistent]])).
76+
assert_net_flow_published(PublisherId, SrcEP, DstEP, NetFlowId) ->
77+
[assert_dby_publish_called([PublisherId, Src, Dst,
78+
link_metadata({ep_to_nf, Src})])
79+
|| {Src, Dst} <- [{SrcEP, net_flow_identifier(NetFlowId)},
80+
{NetFlowId, DstEP}]].
81+
82+
assert_dby_publish_called(Args) ->
83+
?assert(meck:called(dby, publish, Args ++ [[persistent]])).
84+
85+
assert_flow_path_published(PublisherId, NetFlowId, FlowPath) ->
86+
assert_flow_path_published(PublisherId, NetFlowId, FlowPath,
87+
_PrevId = NetFlowId).
88+
89+
assert_flow_path_published(PublisherId, NetFlowId, [FlowMod | T], NetFlowId) ->
90+
OFPathArgs = [NetFlowId,
91+
{FmId, _FmMd} = flow_mod_identifier(FlowMod),
92+
link_metadata({of_path_starts_at, NetFlowId, NetFlowId})],
93+
OFResourceArgs = [FmId,
94+
flow_table_identifier(FlowMod),
95+
link_metadata(of_resource)],
96+
[assert_dby_publish_called([PublisherId | Args])
97+
|| Args <- [OFPathArgs, OFResourceArgs]],
98+
assert_flow_path_published(PublisherId, NetFlowId, T, FmId);
99+
assert_flow_path_published(PublisherId, NetFlowId, [FlowMod | T], LastId) ->
100+
OFPathArgs = [LastId,
101+
{FmId,_FmMd} = flow_mod_identifier(FlowMod),
102+
link_metadata({of_path_forwards_to, LastId, NetFlowId})],
103+
OFResourceArgs = [FmId,
104+
flow_table_identifier(FlowMod),
105+
link_metadata(of_resource)],
106+
[assert_dby_publish_called([PublisherId | Args])
107+
|| Args <- [OFPathArgs, OFResourceArgs]],
108+
assert_flow_path_published(PublisherId, NetFlowId, T, FmId);
109+
assert_flow_path_published(PublisherId, NetFlowId, [], LastId) ->
110+
OFPathArgs = [LastId,
111+
NetFlowId,
112+
link_metadata({of_path_ends_at, LastId, NetFlowId})],
113+
assert_dby_publish_called([PublisherId | OFPathArgs]).
101114

102115
%%%=============================================================================
103116
%%% Internal functions
104117
%%%=============================================================================
105118

106119
mock_dobby() ->
107-
ok = meck:expect(dby, publish, 4, _Ret = ok).
120+
ok = meck:expect(dby, publish, 5, _Ret = ok).
108121

109122
unmock_dobby() ->
110123
ok = meck:unload(dby).
@@ -123,16 +136,26 @@ unmock_flow_table_identifiers() ->
123136
flow_mod_identifier({Dpid, OFVersion, _FlowTableId, FlowMod}) ->
124137
{_Matches, _Instructions, Opts} = FlowMod,
125138
Cookie = proplists:get_value(cookie, Opts),
126-
{Cookie, #{type => of_flow_mod, dpid => Dpid, of_version => OFVersion}}.
139+
{Cookie, [{<<"type">>, <<"of_flow_mod">>},
140+
{<<"dpid">>, Dpid},
141+
{<<"of_version">>, OFVersion}]}.
127142

128143
flow_table_identifier({Dpid, _OFVersion, TableNo, _FlowMod}) ->
129144
TableNoBin = integer_to_binary(TableNo),
130145
<<Dpid/binary, ":", TableNoBin/binary>>.
131146

132-
link_metadata(Type, {NetFlowId, Src}) ->
133-
#{type => Type, src => Src, net_flow_ids => [NetFlowId]};
134-
link_metadata(Type, bidirectional) ->
135-
#{type => Type}.
147+
net_flow_identifier(NetFlowId) ->
148+
{NetFlowId, [{<<"type">>, <<"of_net_flow">>}]}.
149+
150+
link_metadata({Type, Src}) ->
151+
[{<<"type">>, atom_to_binary(Type, utf8)},
152+
{<<"src">>, Src}];
153+
link_metadata({Type, Src, NetFlowId}) ->
154+
[{<<"type">>, atom_to_binary(Type, utf8)},
155+
{<<"src">>, Src},
156+
{<<"net_flow_ids">>, [NetFlowId]}];
157+
link_metadata(Type) ->
158+
[{<<"type">>, atom_to_binary(Type, utf8)}].
136159

137160
reconstruct_flow_path(FlowPath0) ->
138161
Fun = fun({Dpid, {OFVersion, FlowMods}}) ->

0 commit comments

Comments
 (0)