Skip to content

Commit

Permalink
Add projector for host checks selection (#1542)
Browse files Browse the repository at this point in the history
* Add host selection projector

* Update host read model and add migration

* Add host selected checks view

* Use host_details_updated view and event
  • Loading branch information
EMaksy authored Jun 22, 2023
1 parent 2a26d81 commit 5d04a50
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 4 deletions.
3 changes: 0 additions & 3 deletions lib/trento/application/projectors/cluster_projector.ex
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@ defmodule Trento.ClusterProjector do
changeset =
ClusterReadModel
|> Repo.get(id)
# TODO: couldn't make it work with Ecto.Multi
# With following line when we receive an empty list of selected checks, the readmodel does not get updated
# %ClusterReadModel{id: id}
|> ClusterReadModel.changeset(%{
selected_checks: checks
})
Expand Down
34 changes: 34 additions & 0 deletions lib/trento/application/projectors/host_projector.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ defmodule Trento.HostProjector do
HeartbeatFailed,
HeartbeatSucceded,
HostAddedToCluster,
HostChecksSelected,
HostDetailsUpdated,
HostRegistered,
ProviderUpdated
Expand Down Expand Up @@ -84,6 +85,23 @@ defmodule Trento.HostProjector do
end
)

project(
%HostChecksSelected{
host_id: id,
checks: checks
},
fn multi ->
changeset =
HostReadModel
|> Repo.get(id)
|> HostReadModel.changeset(%{
selected_checks: checks
})

Ecto.Multi.update(multi, :host, changeset)
end
)

project(
%HeartbeatSucceded{host_id: id},
fn multi ->
Expand Down Expand Up @@ -228,5 +246,21 @@ defmodule Trento.HostProjector do
})
end

def after_update(
%HostChecksSelected{host_id: host_id, checks: checks},
_,
_
) do
host = %HostReadModel{id: host_id, selected_checks: checks}

message =
HostView.render(
"host_details_updated.json",
%{host: host}
)

TrentoWeb.Endpoint.broadcast("monitoring:hosts", "host_details_updated", message)
end

def after_update(_, _, _), do: :ok
end
2 changes: 1 addition & 1 deletion lib/trento/application/read_models/host_read_model.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ defmodule Trento.HostReadModel do
field :agent_version, :string
field :cluster_id, Ecto.UUID
field :heartbeat, Ecto.Enum, values: [:critical, :passing, :unknown]

field :selected_checks, {:array, :string}, default: []
field :provider, Ecto.Enum, values: Provider.values()
field :provider_data, :map

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule Trento.Repo.Migrations.AddSelectedChecksToHosts do
use Ecto.Migration

def change do
alter table(:hosts) do
add :selected_checks, {:array, :string}, default: []
end
end
end
23 changes: 23 additions & 0 deletions test/trento/application/projectors/host_projector_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ defmodule Trento.HostProjectorTest do
HeartbeatFailed,
HeartbeatSucceded,
HostAddedToCluster,
HostChecksSelected,
HostDetailsUpdated,
ProviderUpdated
}
Expand Down Expand Up @@ -166,6 +167,28 @@ defmodule Trento.HostProjectorTest do
1000
end

test "should update the selected_checks field when event is received" do
%{id: host_id} = insert(:host)

cases = [
%{checks: [Faker.StarWars.character(), Faker.StarWars.character()]},
%{checks: []}
]

Enum.each(cases, fn %{checks: checks} ->
event = %HostChecksSelected{host_id: host_id, checks: checks}

ProjectorTestHelper.project(HostProjector, event, "host_projector")
host_projection = Repo.get!(HostReadModel, event.host_id)

assert event.checks == host_projection.selected_checks

assert_broadcast "host_details_updated",
%{selected_checks: ^checks, id: ^host_id},
1000
end)
end

test "should update the heartbeat field to passing status when HeartbeatSucceded is received",
%{host_id: host_id} do
event = %HeartbeatSucceded{
Expand Down

0 comments on commit 5d04a50

Please sign in to comment.