Skip to content

Commit a1c7fbf

Browse files
committed
chainable events
1 parent de85384 commit a1c7fbf

3 files changed

Lines changed: 132 additions & 11 deletions

File tree

lib/diffo/provider/components/characteristic.ex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ defmodule Diffo.Provider.Characteristic do
149149
end
150150
end
151151

152+
validations do
153+
validate present([:instance_id, :feature_id, :relationship_id], at_most: 1) do
154+
message "characteristic must be related to at most one of an instance, feature or relationship"
155+
end
156+
end
157+
152158
preparations do
153159
prepare build(sort: [name: :asc])
154160
end

lib/diffo/provider/components/event.ex

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ defmodule Diffo.Provider.Event do
2323

2424
code_interface do
2525
define :create
26+
define :chain
2627
define :destroy
2728
end
2829

2930
neo4j do
3031
relate [
31-
{:instance, :FIRED, :incoming, :Instance}
32-
# {:earlier_event, :AFTER, :outgoing, :Event}
32+
{:instance, :FIRED, :incoming, :Instance},
33+
{:head, :AFTER, :incoming, :Event},
34+
{:tail, :AFTER, :outgoing, :Event}
3335
]
3436
end
3537

@@ -58,13 +60,21 @@ defmodule Diffo.Provider.Event do
5860
description "creates an event, fired by an instance"
5961
accept [:type]
6062
argument :instance_id, :uuid
61-
# argument :earlier_event_id, :uuid
6263

63-
change manage_relationship(:instance_id, :instance, type: :append_and_remove)
64-
# change manage_relationship(:earlier_event_id, :earlier_event, type: :append_and_remove)
64+
# ideally capture the id of the event last fired by the instance, if any, and call before on it to bump it down the chain
65+
change manage_relationship(:instance_id, :instance, type: :append)
6566
change load [:instance_type, :instance]
6667
end
6768

69+
update :chain do
70+
description "chains the event from the head event"
71+
primary? true
72+
argument :head_id, :uuid
73+
argument :instance_id, :uuid
74+
change manage_relationship(:instance_id, :instance, type: :remove)
75+
change manage_relationship(:head_id, :head, type: :append)
76+
end
77+
6878
read :list do
6979
description "lists all events"
7080
end
@@ -107,14 +117,24 @@ defmodule Diffo.Provider.Event do
107117
relationships do
108118
belongs_to :instance, Diffo.Provider.Instance do
109119
description "the instance which fired the event"
110-
allow_nil? false
120+
allow_nil? true
111121
public? true
112122
end
113123

114-
# has_one :earlier_event, Diffo.Provider.Event do
115-
# description "the earlier event, if any"
116-
# allow_nil? true
117-
# public? true
124+
belongs_to :head, Diffo.Provider.Event,
125+
allow_nil?: true,
126+
public?: true,
127+
source_attribute: :head_id
128+
129+
belongs_to :tail, Diffo.Provider.Event,
130+
allow_nil?: true,
131+
public?: true,
132+
source_attribute: :tail_id
133+
end
134+
135+
validations do
136+
# validate present [:instance_id, :head_id], at_most: 1 do
137+
# message "event cannot be related to both instance and head event"
118138
# end
119139
end
120140

test/provider/event_test.exs

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ defmodule Diffo.Provider.EventTest do
1212

1313
setup do
1414
on_exit(fn ->
15-
AshNeo4j.Neo4jHelper.delete_nodes(:Event)
15+
AshNeo4j.Neo4jHelper.delete_all()
1616
end)
1717
end
1818

@@ -29,6 +29,101 @@ defmodule Diffo.Provider.EventTest do
2929

3030
assert event.type == :serviceCreateEvent
3131
assert event.instance_type == :service
32+
33+
assert AshNeo4j.Neo4jHelper.nodes_relate_how?(
34+
:Instance,
35+
%{uuid: instance.id},
36+
:Event,
37+
%{uuid: event.id},
38+
:FIRED,
39+
:outgoing
40+
)
41+
end
42+
43+
test "create multiple events (no chaining) - success" do
44+
specification = Diffo.Provider.create_specification!(%{name: "nbnAccess"})
45+
instance = Diffo.Provider.create_instance!(%{specified_by: specification.id})
46+
47+
event_1 =
48+
Diffo.Provider.Event.create!(%{
49+
instance_id: instance.id,
50+
type: :serviceCreateEvent
51+
})
52+
53+
event_2 =
54+
Diffo.Provider.Event.create!(%{
55+
instance_id: instance.id,
56+
type: :serviceStateChangeEvent
57+
})
58+
59+
assert AshNeo4j.Neo4jHelper.nodes_relate_how?(
60+
:Instance,
61+
%{uuid: instance.id},
62+
:Event,
63+
%{uuid: event_1.id},
64+
:FIRED,
65+
:outgoing
66+
)
67+
68+
assert AshNeo4j.Neo4jHelper.nodes_relate_how?(
69+
:Instance,
70+
%{uuid: instance.id},
71+
:Event,
72+
%{uuid: event_2.id},
73+
:FIRED,
74+
:outgoing
75+
)
76+
end
77+
78+
test "create event and chain it before previous event - success" do
79+
specification = Diffo.Provider.create_specification!(%{name: "nbnAccess"})
80+
instance = Diffo.Provider.create_instance!(%{specified_by: specification.id})
81+
82+
event_1 =
83+
Diffo.Provider.Event.create!(%{
84+
instance_id: instance.id,
85+
type: :serviceCreateEvent
86+
})
87+
88+
event_2 =
89+
Diffo.Provider.Event.create!(%{
90+
instance_id: instance.id,
91+
type: :serviceStateChangeEvent
92+
})
93+
94+
event_1 =
95+
event_1
96+
|> Diffo.Provider.Event.chain!(%{
97+
instance_id: instance.id,
98+
head_id: event_2.id
99+
})
100+
101+
refute AshNeo4j.Neo4jHelper.nodes_relate_how?(
102+
:Instance,
103+
%{uuid: instance.id},
104+
:Event,
105+
%{uuid: event_1.id},
106+
:FIRED,
107+
:outgoing
108+
)
109+
110+
assert AshNeo4j.Neo4jHelper.nodes_relate_how?(
111+
:Instance,
112+
%{uuid: instance.id},
113+
:Event,
114+
%{uuid: event_2.id},
115+
:FIRED,
116+
:outgoing
117+
)
118+
119+
assert AshNeo4j.Neo4jHelper.nodes_relate_how?(
120+
:Event,
121+
%{uuid: event_2.id},
122+
:Event,
123+
%{uuid: event_1.id},
124+
:AFTER,
125+
:outgoing
126+
)
32127
end
33128
end
34129

0 commit comments

Comments
 (0)