Skip to content
This repository was archived by the owner on Jun 11, 2023. It is now read-only.

Commit 2ddbcef

Browse files
committed
Add LogForgeRequest for Create and Edit operations
1 parent 75ed1a6 commit 2ddbcef

File tree

38 files changed

+1500
-107
lines changed

38 files changed

+1500
-107
lines changed

lib/event/dispatcher.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ defmodule Helix.Event.Dispatcher do
149149
event LogEvent.Log.Deleted
150150
event LogEvent.Log.Revised
151151

152+
# Custom handlers
153+
event LogEvent.Forge.Processed,
154+
LogHandler.Log,
155+
:log_forge_processed
156+
152157
##############################################################################
153158
# Process events
154159
##############################################################################

lib/event/loggable/flow.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ defmodule Helix.Event.Loggable.Flow do
3333
alias Helix.Network.Query.Bounce, as: BounceQuery
3434
alias Helix.Server.Model.Server
3535

36-
@typep log_entry ::
36+
@type log_entry ::
3737
{Server.id, Entity.id, Log.info}
3838

3939
@doc """

lib/event/notificable/notificable.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ defprotocol Helix.Event.Notificable do
1212
| %{account_id: Account.id, server_id: Server.id}
1313
| %{account_id: Entity.id, server_id: Server.id}
1414
| Server.id
15+
| :no_one
1516

1617
@spec get_notification_info(Event.t) ::
1718
{Notification.class, Notification.code}

lib/log/action/flow/forge.ex

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# credo:disable-for-this-file Credo.Check.Refactor.FunctionArity
2+
defmodule Helix.Log.Action.Flow.Forge do
3+
4+
alias Helix.Event
5+
alias Helix.Entity.Model.Entity
6+
alias Helix.Network.Model.Connection
7+
alias Helix.Network.Model.Tunnel
8+
alias Helix.Server.Model.Server
9+
alias Helix.Software.Model.File
10+
alias Helix.Log.Model.Log
11+
12+
alias Helix.Log.Process.Forge, as: LogForgeProcess
13+
14+
@spec create(
15+
Server.t,
16+
Server.t,
17+
Log.info,
18+
File.t,
19+
{Tunnel.t, Connection.ssh} | nil,
20+
Event.relay
21+
) ::
22+
term
23+
def create(
24+
gateway = %Server{},
25+
endpoint = %Server{},
26+
log_info,
27+
forger = %File{software_type: :log_forger},
28+
conn,
29+
relay
30+
) do
31+
start_process(gateway, endpoint, nil, log_info, forger, nil, conn, relay)
32+
end
33+
34+
@spec edit(
35+
Server.t,
36+
Server.t,
37+
Log.t,
38+
Log.info,
39+
File.t,
40+
Entity.id,
41+
{Tunnel.t, Connection.ssh} | nil,
42+
Event.relay
43+
) ::
44+
term
45+
def edit(
46+
gateway = %Server{},
47+
endpoint = %Server{},
48+
log = %Log{},
49+
log_info,
50+
forger = %File{software_type: :log_forger},
51+
entity_id = %Entity.ID{},
52+
conn,
53+
relay
54+
) do
55+
start_process(
56+
gateway, endpoint, log, log_info, forger, entity_id, conn, relay
57+
)
58+
end
59+
60+
defp start_process(
61+
gateway = %Server{},
62+
endpoint = %Server{},
63+
log,
64+
log_info,
65+
forger = %File{software_type: :log_forger},
66+
entity_id,
67+
conn_info,
68+
relay
69+
) do
70+
action =
71+
if is_nil(log) do
72+
:create
73+
else
74+
:edit
75+
end
76+
77+
{network_id, ssh} =
78+
if is_nil(conn_info) do
79+
{nil, nil}
80+
else
81+
{tunnel, ssh} = conn_info
82+
{tunnel.network_id, ssh}
83+
end
84+
85+
params = %{log_info: log_info}
86+
87+
meta =
88+
%{
89+
forger: forger,
90+
log: log,
91+
action: action,
92+
ssh: ssh,
93+
entity_id: entity_id,
94+
network_id: network_id
95+
}
96+
97+
LogForgeProcess.execute(gateway, endpoint, params, meta, relay)
98+
end
99+
end

lib/log/event/forge.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ defmodule Helix.Log.Event.Forge do
88
achieved its objective and finished executing.
99
"""
1010

11+
alias Helix.Entity.Model.Entity
1112
alias Helix.Process.Model.Process
13+
alias Helix.Server.Model.Server
1214
alias Helix.Log.Model.Log
1315
alias Helix.Log.Process.Forge, as: LogForgeProcess
1416

lib/log/event/log.ex

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,23 @@ defmodule Helix.Log.Event.Log do
4444
def whom_to_publish(event),
4545
do: %{server: event.log.server_id}
4646
end
47+
48+
notification do
49+
@moduledoc """
50+
When the created log is artificial a notification is sent to the player.
51+
"""
52+
53+
@class :server
54+
@code :log_created
55+
56+
def whom_to_notify(%_{log: log}) do
57+
if Log.is_artificial?(log) do
58+
%{account_id: log.revision.entity_id, server_id: log.server_id}
59+
else
60+
:no_one
61+
end
62+
end
63+
end
4764
end
4865

4966
event Revised do
@@ -86,6 +103,18 @@ defmodule Helix.Log.Event.Log do
86103
def whom_to_publish(event),
87104
do: %{server: event.log.server_id}
88105
end
106+
107+
notification do
108+
@moduledoc """
109+
When the created log is artificial a notification is sent to the player.
110+
"""
111+
112+
@class :server
113+
@code :log_revised
114+
115+
def whom_to_notify(%_{log: log}),
116+
do: %{account_id: log.revision.entity_id, server_id: log.server_id}
117+
end
89118
end
90119

91120
event Deleted do

lib/log/henforcer/log/forge.ex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ defmodule Helix.Log.Henforcer.Log.Forge do
22

33
import Helix.Henforcer
44

5-
alias Helix.Server.Model.Server
65
alias Helix.Server.Henforcer.Server, as: ServerHenforcer
6+
alias Helix.Server.Model.Server
77
alias Helix.Software.Henforcer.File, as: FileHenforcer
8-
alias Helix.Log.Model.Log
8+
alias Helix.Software.Model.File
99
alias Helix.Log.Henforcer.Log, as: LogHenforcer
10+
alias Helix.Log.Model.Log
1011

1112
@type can_edit_relay :: %{log: Log.t, gateway: Server.t, forger: File.t}
1213
@type can_edit_relay_partial :: map

lib/log/model/log.ex

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ defmodule Helix.Log.Model.Log do
77
import HELL.Ecto.Macros
88

99
alias Ecto.Changeset
10-
alias Helix.Entity.Model.Entity
1110
alias Helix.Server.Model.Server
1211
alias Helix.Log.Model.LogType
1312
alias Helix.Log.Model.Revision
@@ -28,11 +27,7 @@ defmodule Helix.Log.Model.Log do
2827
@type data :: LogType.data
2928
@type info :: {type, data}
3029

31-
@type creation_params ::
32-
%{
33-
server_id: Server.id,
34-
entity_id: Entity.id
35-
}
30+
@type creation_params :: %{server_id: Server.id}
3631

3732
@creation_fields [:server_id]
3833
@required_fields [:server_id, :revision_id, :creation_time, :log_id]
@@ -131,6 +126,16 @@ defmodule Helix.Log.Model.Log do
131126
{:recover, changeset}
132127
end
133128

129+
@spec is_artificial?(Log.t) ::
130+
boolean
131+
@doc """
132+
Returns whether the log is artificial or not.
133+
"""
134+
def is_artificial?(%Log{revision: %{forge_version: nil}}),
135+
do: false
136+
def is_artificial?(%Log{}),
137+
do: true
138+
134139
@spec build_heritage(creation_params) ::
135140
Helix.ID.heritage
136141
defp build_heritage(params),

lib/log/model/log_type/macros.ex

Lines changed: 72 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,44 @@ defmodule Helix.Log.Model.LogType.Macros do
2828

2929
defenum LogEnum, @logs
3030

31-
# @spec exists?(term) ::
32-
# boolean
33-
def exists?(log) do
34-
Enum.any?(@logs, fn {valid_log, _} -> valid_log == log end)
35-
end
36-
37-
def new(type, data_params) do
31+
@spec exists?(atom) ::
32+
boolean
33+
def exists?(log_type),
34+
do: Enum.any?(@logs, fn {valid_type, _} -> valid_type == log_type end)
35+
36+
@spec new(type, map) ::
37+
struct
38+
@doc """
39+
Creates a new struct for the given log `type`.
40+
"""
41+
def new(type, data_params),
42+
do: dispatch(type, :new, data_params)
43+
44+
@spec parse(type, map) ::
45+
{:ok, struct}
46+
| :error
47+
@doc """
48+
Attempts to parse the potentially unsafe input into a valid LogData.
49+
"""
50+
def parse(type, unsafe_data_params),
51+
do: dispatch(type, :parse, unsafe_data_params)
52+
53+
@spec dispatch(type, atom, term) ::
54+
term
55+
defp dispatch(type, method, param) when not is_list(param),
56+
do: dispatch(type, method, [param])
57+
defp dispatch(type, method, params) do
3858
type
3959
|> get_type_module()
40-
|> apply(:new, [data_params])
60+
|> apply(method, params)
4161
end
4262

4363
end
4464
end
4565

66+
@doc """
67+
Top-level macro used to define a LogType and its underlying LogData.
68+
"""
4669
defmacro log(name, enum_id, do: block) do
4770
module_name =
4871
__CALLER__.module
@@ -67,6 +90,9 @@ defmodule Helix.Log.Model.LogType.Macros do
6790
end
6891
end
6992

93+
@doc """
94+
Converts the module into a LogData struct.
95+
"""
7096
defmacro data_struct(keys) do
7197
quote do
7298

@@ -76,17 +102,48 @@ defmodule Helix.Log.Model.LogType.Macros do
76102
end
77103
end
78104

79-
defmacro new(args, do: block) do
105+
@doc """
106+
Creates a new LogData from the given `data` map.
107+
"""
108+
defmacro new(data, do: block) do
80109
quote do
81110

82111
@doc false
83-
def new(unquote(args)) do
112+
def new(unquote(data)) do
84113
unquote(block)
85114
end
86115

87116
end
88117
end
89118

119+
@doc """
120+
Attempts to parse the given unsafe input into a valid LogData.
121+
"""
122+
defmacro parse(data, do: block) do
123+
quote do
124+
125+
@spec parse(term) ::
126+
{:ok, data :: struct}
127+
| :error
128+
@doc false
129+
def parse(map = unquote(data)) when is_map(map) do
130+
try do
131+
{:ok, unquote(block)}
132+
rescue
133+
RuntimeError ->
134+
:error
135+
136+
KeyError ->
137+
:error
138+
end
139+
end
140+
141+
def parse(not_map) when not is_map(not_map),
142+
do: :error
143+
144+
end
145+
end
146+
90147
@doc """
91148
Generates the boilerplate for a n-field log type.
92149
@@ -116,22 +173,6 @@ defmodule Helix.Log.Model.LogType.Macros do
116173
defmacro gen3(p1, p2, p3),
117174
do: do_gen3(p1, p2, p3)
118175

119-
defmacro parse(args, do: block) do
120-
quote do
121-
122-
@doc false
123-
def parse(unquote(args)) do
124-
try do
125-
{:ok, unquote(block)}
126-
rescue
127-
RuntimeError ->
128-
:error
129-
end
130-
end
131-
132-
end
133-
end
134-
135176
def validate(field_type, field_value) when is_atom(field_type) do
136177
fun = Utils.concat_atom(:validate_, field_type)
137178

@@ -222,9 +263,9 @@ defmodule Helix.Log.Model.LogType.Macros do
222263
parse(unsafe) do
223264
%__MODULE__{
224265
unquote(f1) =>
225-
validate(unquote(v_f1), Map.get(unsafe, unquote(str_f1))),
266+
validate(unquote(v_f1), Map.fetch!(unsafe, unquote(str_f1))),
226267
unquote(f2) =>
227-
validate(unquote(v_f2), Map.get(unsafe, unquote(str_f2)))
268+
validate(unquote(v_f2), Map.fetch!(unsafe, unquote(str_f2)))
228269
}
229270
end
230271

@@ -249,11 +290,11 @@ defmodule Helix.Log.Model.LogType.Macros do
249290
parse(unsafe) do
250291
%__MODULE__{
251292
unquote(f1) =>
252-
validate(unquote(v_f1), Map.get(unsafe, unquote(str_f1))),
293+
validate(unquote(v_f1), Map.fetch!(unsafe, unquote(str_f1))),
253294
unquote(f2) =>
254-
validate(unquote(v_f2), Map.get(unsafe, unquote(str_f2))),
295+
validate(unquote(v_f2), Map.fetch!(unsafe, unquote(str_f2))),
255296
unquote(f3) =>
256-
validate(unquote(v_f3), Map.get(unsafe, unquote(str_f3)))
297+
validate(unquote(v_f3), Map.fetch!(unsafe, unquote(str_f3)))
257298
}
258299
end
259300

0 commit comments

Comments
 (0)