From 984d6f9bee281349ee69e83837ff352a81ed4199 Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Wed, 6 Apr 2022 08:49:30 +0200 Subject: [PATCH 01/14] Parse reachable and msg from execution payload --- lib/trento/application/integration/checks/checks.ex | 4 +++- .../integration/checks/dto/execution_completed_event_dto.ex | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/trento/application/integration/checks/checks.ex b/lib/trento/application/integration/checks/checks.ex index a05ad6e6f6..f20f2c9350 100644 --- a/lib/trento/application/integration/checks/checks.ex +++ b/lib/trento/application/integration/checks/checks.ex @@ -99,9 +99,11 @@ defmodule Trento.Integration.Checks do CompleteChecksExecution.new(%{ cluster_id: cluster_id, hosts_executions: - Enum.map(hosts, fn %{host_id: host_id, results: results} -> + Enum.map(hosts, fn %{host_id: host_id, reachable: reachable, msg: msg, results: results} -> %{ host_id: host_id, + reachable: reachable, + msg: msg, checks_results: Enum.map(results, &Map.from_struct/1) } end) diff --git a/lib/trento/application/integration/checks/dto/execution_completed_event_dto.ex b/lib/trento/application/integration/checks/dto/execution_completed_event_dto.ex index 2fa4dc7512..e2e0fc2bcd 100644 --- a/lib/trento/application/integration/checks/dto/execution_completed_event_dto.ex +++ b/lib/trento/application/integration/checks/dto/execution_completed_event_dto.ex @@ -12,6 +12,8 @@ defmodule Trento.Integration.Checks.ExecutionCompletedEventDto do embeds_many :hosts, Host do field :host_id, Ecto.UUID + field :reachable, :boolean + field :msg, :string embeds_many :results, Result do field :check_id, :string @@ -29,7 +31,7 @@ defmodule Trento.Integration.Checks.ExecutionCompletedEventDto do defp host_changeset(host, attrs) do host - |> cast(attrs, [:host_id]) + |> cast(attrs, [:host_id, :reachable, :msg]) |> cast_embed(:results, with: &result_changeset/2) |> validate_required([:host_id]) end From 73716a65df751fbe79ccb055cd52db4042c3b8f7 Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Wed, 6 Apr 2022 11:15:28 +0200 Subject: [PATCH 02/14] Add host unreachable event --- lib/trento/domain/cluster/cluster.ex | 54 +++++++++++++++---- .../commands/complete_checks_execution.ex | 4 +- .../host_checks_execution_unreachable.ex | 13 +++++ 3 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 lib/trento/domain/cluster/events/host_checks_execution_unreachable.ex diff --git a/lib/trento/domain/cluster/cluster.ex b/lib/trento/domain/cluster/cluster.ex index d5549f4bc5..e94c624025 100644 --- a/lib/trento/domain/cluster/cluster.ex +++ b/lib/trento/domain/cluster/cluster.ex @@ -28,7 +28,8 @@ defmodule Trento.Domain.Cluster do ClusterHealthChanged, ClusterRegistered, HostAddedToCluster, - HostChecksExecutionCompleted + HostChecksExecutionCompleted, + HostChecksExecutionUnreachable } defstruct [ @@ -192,15 +193,7 @@ defmodule Trento.Domain.Cluster do hosts_executions |> Enum.reduce( Multi.new(cluster), - fn %{host_id: host_id, checks_results: results}, multi -> - Multi.execute(multi, fn _ -> - %HostChecksExecutionCompleted{ - cluster_id: cluster_id, - host_id: host_id, - checks_results: results - } - end) - end + &handle_hosts_execution_data(&1, &2, cluster_id) ) |> Multi.execute(fn _ -> %ChecksExecutionCompleted{cluster_id: cluster_id} end) |> Multi.execute(&maybe_emit_cluster_health_changed_event/1) @@ -340,6 +333,21 @@ defmodule Trento.Domain.Cluster do } end + def apply( + %Cluster{hosts_checks_results: hosts_checks_results} = cluster, + %HostChecksExecutionUnreachable{host_id: host_id} + ) do + {_, hosts_checks_results} = + Map.get_and_update(hosts_checks_results, host_id, fn checks -> + {host_id, Enum.map(checks, fn check -> %CheckResult{check_id: check.check_id, result: :unknown} end)} + end) + + %Cluster{ + cluster + | hosts_checks_results: hosts_checks_results + } + end + def apply(%Cluster{} = cluster, %ClusterHealthChanged{health: health}) do %Cluster{cluster | health: health} end @@ -438,4 +446,30 @@ defmodule Trento.Domain.Cluster do %ClusterHealthChanged{cluster_id: cluster_id, health: new_health} end end + + defp handle_hosts_execution_data( + %{host_id: host_id, reachable: false, msg: msg}, multi, cluster_id) do + + multi + |> Multi.execute(fn _ -> + %HostChecksExecutionUnreachable{ + cluster_id: cluster_id, + host_id: host_id, + msg: msg + } + end) + end + + defp handle_hosts_execution_data( + %{host_id: host_id, reachable: true, checks_results: results}, multi, cluster_id) do + + multi + |> Multi.execute(fn _ -> + %HostChecksExecutionCompleted{ + cluster_id: cluster_id, + host_id: host_id, + checks_results: results + } + end) + end end diff --git a/lib/trento/domain/cluster/commands/complete_checks_execution.ex b/lib/trento/domain/cluster/commands/complete_checks_execution.ex index 52439b5fc9..1481c67d7d 100644 --- a/lib/trento/domain/cluster/commands/complete_checks_execution.ex +++ b/lib/trento/domain/cluster/commands/complete_checks_execution.ex @@ -8,13 +8,15 @@ defmodule Trento.Domain.Commands.CompleteChecksExecution do Host checks results value object """ - @required_fields :all + @required_fields [:host_id, :reachable, :checks_results] use Trento.Type alias Trento.Domain.CheckResult deftype do field :host_id, Ecto.UUID + field :reachable, :boolean + field :msg, :string, default: "" embeds_many :checks_results, CheckResult end diff --git a/lib/trento/domain/cluster/events/host_checks_execution_unreachable.ex b/lib/trento/domain/cluster/events/host_checks_execution_unreachable.ex new file mode 100644 index 0000000000..d65d983553 --- /dev/null +++ b/lib/trento/domain/cluster/events/host_checks_execution_unreachable.ex @@ -0,0 +1,13 @@ +defmodule Trento.Domain.Events.HostChecksExecutionUnreachable do + @moduledoc """ + Event of the checks execution unreachable of a host. + """ + + use Trento.Event + + defevent do + field :cluster_id, Ecto.UUID + field :host_id, Ecto.UUID + field :msg, :string + end +end From 0028e95b9b12e737b407789d8b76bd84d1f1d9b3 Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Wed, 6 Apr 2022 13:33:34 +0200 Subject: [PATCH 03/14] Add hosts executions state in the cluster domain --- lib/trento/domain/cluster/cluster.ex | 60 ++++++++++++------- .../commands/complete_checks_execution.ex | 21 +------ .../domain/value_objects/host_execution.ex | 18 ++++++ 3 files changed, 56 insertions(+), 43 deletions(-) create mode 100644 lib/trento/domain/value_objects/host_execution.ex diff --git a/lib/trento/domain/cluster/cluster.ex b/lib/trento/domain/cluster/cluster.ex index e94c624025..4dfa55e7a3 100644 --- a/lib/trento/domain/cluster/cluster.ex +++ b/lib/trento/domain/cluster/cluster.ex @@ -7,7 +7,8 @@ defmodule Trento.Domain.Cluster do CheckResult, Cluster, HanaClusterDetails, - HealthService + HealthService, + HostExecution } alias Trento.Domain.Commands.{ @@ -44,7 +45,7 @@ defmodule Trento.Domain.Cluster do health: :unknown, hosts: [], selected_checks: [], - hosts_checks_results: %{}, + hosts_executions: %{}, checks_execution: :not_running ] @@ -58,7 +59,7 @@ defmodule Trento.Domain.Cluster do details: HanaClusterDetails.t() | nil, hosts: [String.t()], selected_checks: [String.t()], - hosts_checks_results: %{String.t() => [CheckResult.t()]}, + hosts_executions: %{String.t() => HostExecution.t()}, checks_execution: :not_running | :requested | :running } @@ -285,20 +286,24 @@ defmodule Trento.Domain.Cluster do %Cluster{selected_checks: selected_checks, hosts: hosts} = cluster, %ChecksExecutionRequested{} ) do - hosts_checks_results = - Enum.reduce(hosts, %{}, fn host, acc -> + hosts_executions = + Enum.reduce(hosts, %{}, fn host_id, acc -> Map.put( acc, - host, - Enum.map(selected_checks, fn check_id -> - %CheckResult{check_id: check_id, result: :unknown} - end) + host_id, + %HostExecution{ + host_id: host_id, + reachable: true, + checks_results: Enum.map(selected_checks, fn check_id -> + %CheckResult{check_id: check_id, result: :unknown} + end) + } ) end) %Cluster{ cluster - | hosts_checks_results: hosts_checks_results, + | hosts_executions: hosts_executions, checks_execution: :requested } end @@ -324,27 +329,35 @@ defmodule Trento.Domain.Cluster do end def apply( - %Cluster{hosts_checks_results: hosts_checks_results} = cluster, + %Cluster{hosts_executions: hosts_executions} = cluster, %HostChecksExecutionCompleted{host_id: host_id, checks_results: checks_results} ) do %Cluster{ cluster - | hosts_checks_results: Map.put(hosts_checks_results, host_id, checks_results) + | hosts_executions: Map.put(hosts_executions, host_id, + %HostExecution{ + host_id: host_id, + reachable: true, + checks_results: checks_results + } + ) } end def apply( - %Cluster{hosts_checks_results: hosts_checks_results} = cluster, - %HostChecksExecutionUnreachable{host_id: host_id} + %Cluster{hosts_executions: hosts_executions} = cluster, + %HostChecksExecutionUnreachable{host_id: host_id, msg: msg} ) do - {_, hosts_checks_results} = - Map.get_and_update(hosts_checks_results, host_id, fn checks -> - {host_id, Enum.map(checks, fn check -> %CheckResult{check_id: check.check_id, result: :unknown} end)} - end) - %Cluster{ cluster - | hosts_checks_results: hosts_checks_results + | hosts_executions: Map.update(hosts_executions, host_id, %HostExecution{}, fn host -> + %HostExecution{ + host_id: host_id, + reachable: false, + msg: msg, + checks_results: host.checks_results + } + end) } end @@ -430,13 +443,14 @@ defmodule Trento.Domain.Cluster do defp maybe_emit_cluster_health_changed_event(%Cluster{ cluster_id: cluster_id, - hosts_checks_results: hosts_checks_results, + hosts_executions: hosts_executions, discovered_health: discovered_health, health: health }) do new_health = - hosts_checks_results - |> Enum.flat_map(fn {_, results} -> results end) + hosts_executions + |> Enum.map(fn {_, hosts} -> hosts end) + |> Enum.flat_map(fn %{checks_results: checks_results} -> checks_results end) |> Enum.map(fn %{result: result} -> result end) |> Enum.reject(fn result -> result == :skipped end) |> Kernel.++([discovered_health]) diff --git a/lib/trento/domain/cluster/commands/complete_checks_execution.ex b/lib/trento/domain/cluster/commands/complete_checks_execution.ex index 1481c67d7d..47c7c1b121 100644 --- a/lib/trento/domain/cluster/commands/complete_checks_execution.ex +++ b/lib/trento/domain/cluster/commands/complete_checks_execution.ex @@ -3,30 +3,11 @@ defmodule Trento.Domain.Commands.CompleteChecksExecution do Store the checks results coming from an execution on a specific cluster. """ - defmodule HostExecution do - @moduledoc """ - Host checks results value object - """ - - @required_fields [:host_id, :reachable, :checks_results] - - use Trento.Type - alias Trento.Domain.CheckResult - - deftype do - field :host_id, Ecto.UUID - field :reachable, :boolean - field :msg, :string, default: "" - - embeds_many :checks_results, CheckResult - end - end - @required_fields :all use Trento.Command - alias Trento.Domain.CheckResult + alias Trento.Domain.HostExecution defcommand do field :cluster_id, Ecto.UUID diff --git a/lib/trento/domain/value_objects/host_execution.ex b/lib/trento/domain/value_objects/host_execution.ex new file mode 100644 index 0000000000..2c35bcf846 --- /dev/null +++ b/lib/trento/domain/value_objects/host_execution.ex @@ -0,0 +1,18 @@ +defmodule Trento.Domain.HostExecution do + @moduledoc """ + Host checks results value object + """ + + @required_fields [:host_id, :reachable, :checks_results] + + use Trento.Type + alias Trento.Domain.CheckResult + + deftype do + field :host_id, Ecto.UUID + field :reachable, :boolean + field :msg, :string, default: "" + + embeds_many :checks_results, CheckResult + end +end From 2191f581864f96213d0a99ab0ce90e730348f06c Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Wed, 6 Apr 2022 14:10:08 +0200 Subject: [PATCH 04/14] Project hosts executions state data --- .../projectors/check_result_projector.ex | 58 ++++++++++++++++++- .../host_checks_results_read_model.ex | 31 ++++++++++ ...20405142819_create_host_checks_results.exs | 12 ++++ 3 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 lib/trento/application/read_models/host_checks_results_read_model.ex create mode 100644 priv/repo/migrations/20220405142819_create_host_checks_results.exs diff --git a/lib/trento/application/projectors/check_result_projector.ex b/lib/trento/application/projectors/check_result_projector.ex index 5731c736d2..0647a648b0 100644 --- a/lib/trento/application/projectors/check_result_projector.ex +++ b/lib/trento/application/projectors/check_result_projector.ex @@ -12,10 +12,14 @@ defmodule Trento.CheckResultProjector do alias Trento.Domain.Events.{ ChecksExecutionRequested, - HostChecksExecutionCompleted + HostChecksExecutionCompleted, + HostChecksExecutionUnreachable } - alias Trento.CheckResultReadModel + alias Trento.{ + CheckResultReadModel, + HostChecksResultsReadModel + } project( %ChecksExecutionRequested{ @@ -24,14 +28,41 @@ defmodule Trento.CheckResultProjector do checks: checks }, fn multi -> + # Delete old hosts executions states + multi = + Ecto.Multi.delete_all( + multi, + :delete_old_hosts_executions, + from(c in CheckResultReadModel, where: c.cluster_id == ^cluster_id) + ) + # Delete old results multi = Ecto.Multi.delete_all( multi, :delete_old_checks_results, - from(c in CheckResultReadModel, where: c.cluster_id == ^cluster_id) + from(h in HostChecksResultsReadModel, where: h.cluster_id == ^cluster_id) ) + multi = + hosts + |> Enum.map(fn host_id -> + HostChecksResultsReadModel.changeset( + %HostChecksResultsReadModel{}, + %{ + cluster_id: cluster_id, + host_id: host_id, + reachable: true, + msg: "" + } + ) + end) + |> List.flatten() + |> Enum.reduce(multi, fn %{changes: %{cluster_id: cluster_id, host_id: host_id}} = changeset, + acc -> + Ecto.Multi.insert(acc, "#{cluster_id}_#{host_id}", changeset) + end) + hosts |> Enum.map(fn host_id -> Enum.map(checks, fn check_id -> @@ -61,6 +92,12 @@ defmodule Trento.CheckResultProjector do checks_results: checks_results }, fn multi -> + hosts_executions_changeset = + %HostChecksResultsReadModel{cluster_id: cluster_id, host_id: host_id} + |> HostChecksResultsReadModel.changeset(%{reachable: true, msg: ""}) + + Ecto.Multi.update(multi, :hosts_executions, hosts_executions_changeset) + checks_results |> Enum.map(fn %{ check_id: check_id, @@ -85,6 +122,21 @@ defmodule Trento.CheckResultProjector do end ) + project( + %HostChecksExecutionUnreachable{ + cluster_id: cluster_id, + host_id: host_id, + msg: msg + }, + fn multi -> + hosts_executions_changeset = + %HostChecksResultsReadModel{cluster_id: cluster_id, host_id: host_id} + |> HostChecksResultsReadModel.changeset(%{reachable: false, msg: msg}) + + Ecto.Multi.update(multi, :hosts_executions, hosts_executions_changeset) + end + ) + @impl true def after_update( %ChecksExecutionRequested{cluster_id: cluster_id, hosts: hosts, checks: checks}, diff --git a/lib/trento/application/read_models/host_checks_results_read_model.ex b/lib/trento/application/read_models/host_checks_results_read_model.ex new file mode 100644 index 0000000000..ee3ae33191 --- /dev/null +++ b/lib/trento/application/read_models/host_checks_results_read_model.ex @@ -0,0 +1,31 @@ +defmodule Trento.HostChecksResultsReadModel do + @moduledoc """ + Host checks results read model + """ + + use Ecto.Schema + + import Ecto.Changeset + + alias Trento.CheckResultReadModel + + @type t :: %__MODULE__{} + + @derive {Jason.Encoder, except: [:__meta__, :__struct__]} + @primary_key false + schema "hosts_checks_results" do + field :cluster_id, Ecto.UUID, primary_key: true + field :host_id, Ecto.UUID, primary_key: true + field :reachable, :boolean + field :msg, :string + + has_many :checks_results, CheckResultReadModel, + references: :host_id, + foreign_key: :host_id + end + + @spec changeset(t() | Ecto.Changeset.t(), map) :: Ecto.Changeset.t() + def changeset(host_checks_results, attrs) do + cast(host_checks_results, attrs, __MODULE__.__schema__(:fields)) + end +end diff --git a/priv/repo/migrations/20220405142819_create_host_checks_results.exs b/priv/repo/migrations/20220405142819_create_host_checks_results.exs new file mode 100644 index 0000000000..211b92c780 --- /dev/null +++ b/priv/repo/migrations/20220405142819_create_host_checks_results.exs @@ -0,0 +1,12 @@ +defmodule Trento.Repo.Migrations.CreateHostChecksResults do + use Ecto.Migration + + def change do + create table(:hosts_checks_results, primary_key: false) do + add :cluster_id, :uuid, primary_key: true + add :host_id, :uuid, primary_key: true + add :reachable, :boolean + add :msg, :string + end + end +end From e6a90d4b06a3980c70a7a181236ba1531d4f2e3e Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Wed, 6 Apr 2022 14:16:05 +0200 Subject: [PATCH 05/14] Rename hosts execution read model and associate data in usecases --- .../projectors/check_result_projector.ex | 16 ++++++++-------- .../read_models/cluster_read_model.ex | 6 +++++- .../host_checks_results_read_model.ex | 10 ++-------- .../application/usecases/clusters/clusters.ex | 2 +- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/lib/trento/application/projectors/check_result_projector.ex b/lib/trento/application/projectors/check_result_projector.ex index 0647a648b0..c96273869d 100644 --- a/lib/trento/application/projectors/check_result_projector.ex +++ b/lib/trento/application/projectors/check_result_projector.ex @@ -18,7 +18,7 @@ defmodule Trento.CheckResultProjector do alias Trento.{ CheckResultReadModel, - HostChecksResultsReadModel + HostChecksExecutionsReadModel } project( @@ -41,14 +41,14 @@ defmodule Trento.CheckResultProjector do Ecto.Multi.delete_all( multi, :delete_old_checks_results, - from(h in HostChecksResultsReadModel, where: h.cluster_id == ^cluster_id) + from(h in HostChecksExecutionsReadModel, where: h.cluster_id == ^cluster_id) ) multi = hosts |> Enum.map(fn host_id -> - HostChecksResultsReadModel.changeset( - %HostChecksResultsReadModel{}, + HostChecksExecutionsReadModel.changeset( + %HostChecksExecutionsReadModel{}, %{ cluster_id: cluster_id, host_id: host_id, @@ -93,8 +93,8 @@ defmodule Trento.CheckResultProjector do }, fn multi -> hosts_executions_changeset = - %HostChecksResultsReadModel{cluster_id: cluster_id, host_id: host_id} - |> HostChecksResultsReadModel.changeset(%{reachable: true, msg: ""}) + %HostChecksExecutionsReadModel{cluster_id: cluster_id, host_id: host_id} + |> HostChecksExecutionsReadModel.changeset(%{reachable: true, msg: ""}) Ecto.Multi.update(multi, :hosts_executions, hosts_executions_changeset) @@ -130,8 +130,8 @@ defmodule Trento.CheckResultProjector do }, fn multi -> hosts_executions_changeset = - %HostChecksResultsReadModel{cluster_id: cluster_id, host_id: host_id} - |> HostChecksResultsReadModel.changeset(%{reachable: false, msg: msg}) + %HostChecksExecutionsReadModel{cluster_id: cluster_id, host_id: host_id} + |> HostChecksExecutionsReadModel.changeset(%{reachable: false, msg: msg}) Ecto.Multi.update(multi, :hosts_executions, hosts_executions_changeset) end diff --git a/lib/trento/application/read_models/cluster_read_model.ex b/lib/trento/application/read_models/cluster_read_model.ex index f35e2ec85e..fc8bff21f2 100644 --- a/lib/trento/application/read_models/cluster_read_model.ex +++ b/lib/trento/application/read_models/cluster_read_model.ex @@ -7,7 +7,10 @@ defmodule Trento.ClusterReadModel do import Ecto.Changeset - alias Trento.CheckResultReadModel + alias Trento.{ + CheckResultReadModel, + HostChecksExecutionsReadModel + } @type t :: %__MODULE__{} @@ -24,6 +27,7 @@ defmodule Trento.ClusterReadModel do field :details, :map field :checks_execution, Ecto.Enum, values: [:not_running, :requested, :running] + has_many :hosts_executions, HostChecksExecutionsReadModel, foreign_key: :cluster_id has_many :checks_results, CheckResultReadModel, foreign_key: :cluster_id has_many :tags, Trento.Tag, foreign_key: :resource_id end diff --git a/lib/trento/application/read_models/host_checks_results_read_model.ex b/lib/trento/application/read_models/host_checks_results_read_model.ex index ee3ae33191..e8fbbe78ef 100644 --- a/lib/trento/application/read_models/host_checks_results_read_model.ex +++ b/lib/trento/application/read_models/host_checks_results_read_model.ex @@ -1,14 +1,12 @@ -defmodule Trento.HostChecksResultsReadModel do +defmodule Trento.HostChecksExecutionsReadModel do @moduledoc """ - Host checks results read model + Host checks executions read model """ use Ecto.Schema import Ecto.Changeset - alias Trento.CheckResultReadModel - @type t :: %__MODULE__{} @derive {Jason.Encoder, except: [:__meta__, :__struct__]} @@ -18,10 +16,6 @@ defmodule Trento.HostChecksResultsReadModel do field :host_id, Ecto.UUID, primary_key: true field :reachable, :boolean field :msg, :string - - has_many :checks_results, CheckResultReadModel, - references: :host_id, - foreign_key: :host_id end @spec changeset(t() | Ecto.Changeset.t(), map) :: Ecto.Changeset.t() diff --git a/lib/trento/application/usecases/clusters/clusters.ex b/lib/trento/application/usecases/clusters/clusters.ex index 3593fd9d03..96ea89d95c 100644 --- a/lib/trento/application/usecases/clusters/clusters.ex +++ b/lib/trento/application/usecases/clusters/clusters.ex @@ -48,7 +48,7 @@ defmodule Trento.Clusters do ClusterReadModel |> order_by(asc: :name) |> Repo.all() - |> Repo.preload([:tags, :checks_results]) + |> Repo.preload([:tags, :hosts_executions, :checks_results]) end @spec build_check_results([String.t()]) :: {:ok, [CheckResult.t()]} | {:error, any} From eccfa05bc0e05b6f289e78b060e07cadeab84530 Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Wed, 6 Apr 2022 15:01:01 +0200 Subject: [PATCH 06/14] Set requested and running icons in results view better --- assets/js/components/ChecksResults.jsx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/assets/js/components/ChecksResults.jsx b/assets/js/components/ChecksResults.jsx index 4887c6cef1..ec6c8cd6b7 100644 --- a/assets/js/components/ChecksResults.jsx +++ b/assets/js/components/ChecksResults.jsx @@ -2,7 +2,7 @@ import React, { useEffect } from 'react'; import { useParams } from 'react-router-dom'; import { useSelector, useDispatch } from 'react-redux'; -import { EOS_LENS_FILLED, EOS_ERROR } from 'eos-icons-react'; +import { EOS_LENS_FILLED, EOS_ERROR, EOS_SCHEDULE } from 'eos-icons-react'; import Spinner from './Spinner'; import NotificationBox from './NotificationBox'; @@ -45,7 +45,14 @@ const sortChecksResults = (checksResults = [], group) => { }); }; -const getResultIcon = (result) => { +const getResultIcon = (checks_execution, result) => { + switch (checks_execution) { + case 'requested': + return ; + case 'running': + return ; + } + switch (result) { case 'passing': return ; @@ -54,7 +61,7 @@ const getResultIcon = (result) => { case 'critical': return ; default: - return ; + return ; } }; @@ -150,7 +157,7 @@ const ChecksResults = () => { {description(checkResult.check_id)} - {getResultIcon(checkResult.result)} + {getResultIcon(cluster.checks_execution, checkResult.result)} ))} From b5cf097f04bac0f483b3874a0b25e079ed8002ed Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Wed, 6 Apr 2022 16:02:35 +0200 Subject: [PATCH 07/14] Remove the host unreachable event to make the code leaner --- .../projectors/check_result_projector.ex | 30 +++++---------- lib/trento/domain/cluster/cluster.ex | 37 ++++++++++++------- .../events/host_checks_execution_completed.ex | 2 + .../host_checks_execution_unreachable.ex | 13 ------- .../domain/value_objects/check_result.ex | 2 +- 5 files changed, 36 insertions(+), 48 deletions(-) delete mode 100644 lib/trento/domain/cluster/events/host_checks_execution_unreachable.ex diff --git a/lib/trento/application/projectors/check_result_projector.ex b/lib/trento/application/projectors/check_result_projector.ex index c96273869d..6fd9712d4e 100644 --- a/lib/trento/application/projectors/check_result_projector.ex +++ b/lib/trento/application/projectors/check_result_projector.ex @@ -12,8 +12,7 @@ defmodule Trento.CheckResultProjector do alias Trento.Domain.Events.{ ChecksExecutionRequested, - HostChecksExecutionCompleted, - HostChecksExecutionUnreachable + HostChecksExecutionCompleted } alias Trento.{ @@ -52,8 +51,8 @@ defmodule Trento.CheckResultProjector do %{ cluster_id: cluster_id, host_id: host_id, - reachable: true, - msg: "" + reachable: nil, + msg: nil } ) end) @@ -89,12 +88,14 @@ defmodule Trento.CheckResultProjector do %HostChecksExecutionCompleted{ cluster_id: cluster_id, host_id: host_id, + reachable: reachable, + msg: msg, checks_results: checks_results }, fn multi -> hosts_executions_changeset = %HostChecksExecutionsReadModel{cluster_id: cluster_id, host_id: host_id} - |> HostChecksExecutionsReadModel.changeset(%{reachable: true, msg: ""}) + |> HostChecksExecutionsReadModel.changeset(%{reachable: reachable, msg: msg}) Ecto.Multi.update(multi, :hosts_executions, hosts_executions_changeset) @@ -122,21 +123,6 @@ defmodule Trento.CheckResultProjector do end ) - project( - %HostChecksExecutionUnreachable{ - cluster_id: cluster_id, - host_id: host_id, - msg: msg - }, - fn multi -> - hosts_executions_changeset = - %HostChecksExecutionsReadModel{cluster_id: cluster_id, host_id: host_id} - |> HostChecksExecutionsReadModel.changeset(%{reachable: false, msg: msg}) - - Ecto.Multi.update(multi, :hosts_executions, hosts_executions_changeset) - end - ) - @impl true def after_update( %ChecksExecutionRequested{cluster_id: cluster_id, hosts: hosts, checks: checks}, @@ -160,6 +146,8 @@ defmodule Trento.CheckResultProjector do %HostChecksExecutionCompleted{ cluster_id: cluster_id, host_id: host_id, + reachable: reachable, + msg: msg, checks_results: checks_results }, _, @@ -168,6 +156,8 @@ defmodule Trento.CheckResultProjector do TrentoWeb.Endpoint.broadcast("monitoring:clusters", "checks_results_updated", %{ cluster_id: cluster_id, host_id: host_id, + reachable: reachable, + msg: msg, checks_results: Enum.map(checks_results, fn %{check_id: check_id, result: result} -> %{host_id: host_id, check_id: check_id, result: result} diff --git a/lib/trento/domain/cluster/cluster.ex b/lib/trento/domain/cluster/cluster.ex index 4dfa55e7a3..64330c0f98 100644 --- a/lib/trento/domain/cluster/cluster.ex +++ b/lib/trento/domain/cluster/cluster.ex @@ -29,8 +29,7 @@ defmodule Trento.Domain.Cluster do ClusterHealthChanged, ClusterRegistered, HostAddedToCluster, - HostChecksExecutionCompleted, - HostChecksExecutionUnreachable + HostChecksExecutionCompleted } defstruct [ @@ -185,7 +184,8 @@ defmodule Trento.Domain.Cluster do # Store checks results def execute( %Cluster{ - cluster_id: cluster_id + cluster_id: cluster_id, + hosts_executions: old_hosts_executions } = cluster, %CompleteChecksExecution{ hosts_executions: hosts_executions @@ -194,7 +194,7 @@ defmodule Trento.Domain.Cluster do hosts_executions |> Enum.reduce( Multi.new(cluster), - &handle_hosts_execution_data(&1, &2, cluster_id) + &handle_hosts_execution_data(&1, &2, cluster_id, old_hosts_executions) ) |> Multi.execute(fn _ -> %ChecksExecutionCompleted{cluster_id: cluster_id} end) |> Multi.execute(&maybe_emit_cluster_health_changed_event/1) @@ -330,14 +330,16 @@ defmodule Trento.Domain.Cluster do def apply( %Cluster{hosts_executions: hosts_executions} = cluster, - %HostChecksExecutionCompleted{host_id: host_id, checks_results: checks_results} - ) do + %HostChecksExecutionCompleted{host_id: host_id, reachable: reachable, msg: msg, checks_results: checks_results} + ) + when reachable == true do %Cluster{ cluster | hosts_executions: Map.put(hosts_executions, host_id, %HostExecution{ host_id: host_id, - reachable: true, + reachable: reachable, + msg: msg, checks_results: checks_results } ) @@ -346,14 +348,15 @@ defmodule Trento.Domain.Cluster do def apply( %Cluster{hosts_executions: hosts_executions} = cluster, - %HostChecksExecutionUnreachable{host_id: host_id, msg: msg} - ) do + %HostChecksExecutionCompleted{host_id: host_id, reachable: reachable, msg: msg} + ) + when reachable == false do %Cluster{ cluster | hosts_executions: Map.update(hosts_executions, host_id, %HostExecution{}, fn host -> %HostExecution{ host_id: host_id, - reachable: false, + reachable: reachable, msg: msg, checks_results: host.checks_results } @@ -462,26 +465,32 @@ defmodule Trento.Domain.Cluster do end defp handle_hosts_execution_data( - %{host_id: host_id, reachable: false, msg: msg}, multi, cluster_id) do + %{host_id: host_id, reachable: reachable, msg: msg}, multi, cluster_id, hosts_executions) + when reachable == false do multi |> Multi.execute(fn _ -> - %HostChecksExecutionUnreachable{ + %HostChecksExecutionCompleted{ cluster_id: cluster_id, host_id: host_id, - msg: msg + reachable: reachable, + msg: msg, + checks_results: Map.get(hosts_executions, host_id).checks_results } end) end defp handle_hosts_execution_data( - %{host_id: host_id, reachable: true, checks_results: results}, multi, cluster_id) do + %{host_id: host_id, reachable: reachable, msg: msg, checks_results: results}, multi, cluster_id, _hosts_executions) + when reachable == true do multi |> Multi.execute(fn _ -> %HostChecksExecutionCompleted{ cluster_id: cluster_id, host_id: host_id, + reachable: reachable, + msg: msg, checks_results: results } end) diff --git a/lib/trento/domain/cluster/events/host_checks_execution_completed.ex b/lib/trento/domain/cluster/events/host_checks_execution_completed.ex index 195084fa97..c6f420ea0c 100644 --- a/lib/trento/domain/cluster/events/host_checks_execution_completed.ex +++ b/lib/trento/domain/cluster/events/host_checks_execution_completed.ex @@ -10,6 +10,8 @@ defmodule Trento.Domain.Events.HostChecksExecutionCompleted do defevent do field :cluster_id, :string field :host_id, :string + field :reachable, :boolean + field :msg, :string embeds_many :checks_results, CheckResult end diff --git a/lib/trento/domain/cluster/events/host_checks_execution_unreachable.ex b/lib/trento/domain/cluster/events/host_checks_execution_unreachable.ex deleted file mode 100644 index d65d983553..0000000000 --- a/lib/trento/domain/cluster/events/host_checks_execution_unreachable.ex +++ /dev/null @@ -1,13 +0,0 @@ -defmodule Trento.Domain.Events.HostChecksExecutionUnreachable do - @moduledoc """ - Event of the checks execution unreachable of a host. - """ - - use Trento.Event - - defevent do - field :cluster_id, Ecto.UUID - field :host_id, Ecto.UUID - field :msg, :string - end -end diff --git a/lib/trento/domain/value_objects/check_result.ex b/lib/trento/domain/value_objects/check_result.ex index 9fe90e3871..e41a8fece5 100644 --- a/lib/trento/domain/value_objects/check_result.ex +++ b/lib/trento/domain/value_objects/check_result.ex @@ -9,6 +9,6 @@ defmodule Trento.Domain.CheckResult do deftype do field :check_id, :string - field :result, Ecto.Enum, values: [:passing, :warning, :critical, :skipped] + field :result, Ecto.Enum, values: [:passing, :warning, :critical, :skipped, :unknown] end end From 18989ae37fe70aa03275afae53ad52a3f32a2ad0 Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Wed, 6 Apr 2022 17:12:43 +0200 Subject: [PATCH 08/14] Show unreachable state in frontend --- assets/js/components/ChecksResults.jsx | 43 ++++++++----------- assets/js/state/clusters.js | 7 +++ .../projectors/check_result_projector.ex | 6 +-- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/assets/js/components/ChecksResults.jsx b/assets/js/components/ChecksResults.jsx index ec6c8cd6b7..446450d8a8 100644 --- a/assets/js/components/ChecksResults.jsx +++ b/assets/js/components/ChecksResults.jsx @@ -8,22 +8,6 @@ import Spinner from './Spinner'; import NotificationBox from './NotificationBox'; import LoadingBox from './LoadingBox'; -const getChecksResults = (cluster) => { - if (cluster) { - return cluster.checks_results - .filter((check_result) => check_result.result != 'skipped') // Filter "skipped" results by now - .reduce((acc, checkResult) => { - acc[checkResult.host_id] = [ - ...(acc[checkResult.host_id] || []), - checkResult, - ]; - - return acc; - }, {}); - } - return {}; -}; - const getHostname = (hosts = []) => (hostId) => { @@ -36,15 +20,18 @@ const getHostname = }, ''); }; -const sortChecksResults = (checksResults = [], group) => { +const sortChecksResults = (checksResults = []) => { return checksResults.sort((a, b) => { - if (a.check_id === b.check_id) { - return group(a.check_id) > group(b.check_id) ? 1 : -1; - } return a.check_id > b.check_id ? 1 : -1; }); }; +const sortHosts = (hosts = []) => { + return hosts.sort((a, b) => { + return a.host_id > b.host_id ? 1 : -1; + }); +}; + const getResultIcon = (checks_execution, result) => { switch (checks_execution) { case 'requested': @@ -85,8 +72,6 @@ const ChecksResults = () => { }); }; - const checksResults = getChecksResults(cluster); - const hostname = getHostname(useSelector((state) => state.hostsList.hosts)); useEffect(() => { @@ -114,15 +99,20 @@ const ChecksResults = () => { return (
- {Object.keys(checksResults).map((c) => ( + {sortHosts(cluster?.hosts_executions.slice()).map(({cluster_id, host_id, reachable, msg}) => (

- {hostname(c)} + {hostname(host_id)}

+ {reachable == false && ( + + )}
@@ -148,7 +138,10 @@ const ChecksResults = () => { - {sortChecksResults(checksResults[c]).map((checkResult) => ( + {sortChecksResults(cluster?.checks_results.slice()) + .filter((check_result) => check_result.host_id == host_id) + .filter((check_result) => check_result.result != 'skipped') // Filter "skipped" results by now + .map((checkResult) => ( + {sortChecksResults(cluster?.checks_results.slice()) + .filter( + (check_result) => check_result.host_id == host_id + ) + .filter( + (check_result) => check_result.result != 'skipped' + ) // Filter "skipped" results by now + .map((checkResult) => ( + + + + + + ))} + +
{checkResult.check_id} diff --git a/assets/js/state/clusters.js b/assets/js/state/clusters.js index 57b908c7d1..dbbbb69207 100644 --- a/assets/js/state/clusters.js +++ b/assets/js/state/clusters.js @@ -58,6 +58,13 @@ export const clustersListSlice = createSlice({ }), ...action.payload.checks_results, ]; + + cluster.hosts_executions = [ + ...cluster.hosts_executions.filter((host_execution) => { + return host_execution.host_id !== action.payload.host_id; + }), + ...action.payload.hosts_executions, + ]; } return cluster; }); diff --git a/lib/trento/application/projectors/check_result_projector.ex b/lib/trento/application/projectors/check_result_projector.ex index 6fd9712d4e..47417448ff 100644 --- a/lib/trento/application/projectors/check_result_projector.ex +++ b/lib/trento/application/projectors/check_result_projector.ex @@ -97,7 +97,7 @@ defmodule Trento.CheckResultProjector do %HostChecksExecutionsReadModel{cluster_id: cluster_id, host_id: host_id} |> HostChecksExecutionsReadModel.changeset(%{reachable: reachable, msg: msg}) - Ecto.Multi.update(multi, :hosts_executions, hosts_executions_changeset) + multi = Ecto.Multi.update(multi, :hosts_executions, hosts_executions_changeset) checks_results |> Enum.map(fn %{ @@ -133,6 +133,7 @@ defmodule Trento.CheckResultProjector do TrentoWeb.Endpoint.broadcast("monitoring:clusters", "checks_results_updated", %{ cluster_id: cluster_id, host_id: host_id, + hosts_executions: [%{cluster_id: cluster_id, host_id: host_id, reachable: true, msg: ""}], checks_results: Enum.map(checks, fn check_id -> %{host_id: host_id, check_id: check_id, result: :unknown} @@ -156,8 +157,7 @@ defmodule Trento.CheckResultProjector do TrentoWeb.Endpoint.broadcast("monitoring:clusters", "checks_results_updated", %{ cluster_id: cluster_id, host_id: host_id, - reachable: reachable, - msg: msg, + hosts_executions: [%{cluster_id: cluster_id, host_id: host_id, reachable: reachable, msg: msg}], checks_results: Enum.map(checks_results, fn %{check_id: check_id, result: result} -> %{host_id: host_id, check_id: check_id, result: result} From 0c8a0c9677449ff0fd0e0effc63f49fbcbe71f0f Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Mon, 11 Apr 2022 10:32:22 +0200 Subject: [PATCH 09/14] Apply all linting fixes --- assets/js/components/ChecksResults.jsx | 133 ++++++++++-------- .../application/integration/checks/checks.ex | 2 +- .../projectors/check_result_projector.ex | 7 +- lib/trento/domain/cluster/cluster.ex | 60 ++++---- 4 files changed, 116 insertions(+), 86 deletions(-) diff --git a/assets/js/components/ChecksResults.jsx b/assets/js/components/ChecksResults.jsx index 446450d8a8..44319b3cf1 100644 --- a/assets/js/components/ChecksResults.jsx +++ b/assets/js/components/ChecksResults.jsx @@ -35,9 +35,9 @@ const sortHosts = (hosts = []) => { const getResultIcon = (checks_execution, result) => { switch (checks_execution) { case 'requested': - return ; + return ; case 'running': - return ; + return ; } switch (result) { @@ -99,68 +99,83 @@ const ChecksResults = () => { return (
- {sortHosts(cluster?.hosts_executions.slice()).map(({cluster_id, host_id, reachable, msg}) => ( -
-
-
-
-
-

- {hostname(host_id)} -

- {reachable == false && ( - - )} -
- - - - - - - - - - {sortChecksResults(cluster?.checks_results.slice()) - .filter((check_result) => check_result.host_id == host_id) - .filter((check_result) => check_result.result != 'skipped') // Filter "skipped" results by now - .map((checkResult) => ( - - - - +

{msg}

+ + )} + +
- ID - - Description - ( +
+
+
+
+
+

+ {hostname(host_id)} +

+ {reachable == false && ( +
- {checkResult.check_id} - - {description(checkResult.check_id)} - - {getResultIcon(cluster.checks_execution, checkResult.result)} -
+ + + + + - ))} - -
+ ID + + Description + + Result +
+ +
+ {checkResult.check_id} + + {description(checkResult.check_id)} + + {getResultIcon( + cluster.checks_execution, + checkResult.result + )} +
+
-
- ))} + ) + )} ); }; diff --git a/lib/trento/application/integration/checks/checks.ex b/lib/trento/application/integration/checks/checks.ex index f20f2c9350..0e4ca8e73d 100644 --- a/lib/trento/application/integration/checks/checks.ex +++ b/lib/trento/application/integration/checks/checks.ex @@ -103,7 +103,7 @@ defmodule Trento.Integration.Checks do %{ host_id: host_id, reachable: reachable, - msg: msg, + msg: msg, checks_results: Enum.map(results, &Map.from_struct/1) } end) diff --git a/lib/trento/application/projectors/check_result_projector.ex b/lib/trento/application/projectors/check_result_projector.ex index 47417448ff..da997143a0 100644 --- a/lib/trento/application/projectors/check_result_projector.ex +++ b/lib/trento/application/projectors/check_result_projector.ex @@ -57,7 +57,8 @@ defmodule Trento.CheckResultProjector do ) end) |> List.flatten() - |> Enum.reduce(multi, fn %{changes: %{cluster_id: cluster_id, host_id: host_id}} = changeset, + |> Enum.reduce(multi, fn %{changes: %{cluster_id: cluster_id, host_id: host_id}} = + changeset, acc -> Ecto.Multi.insert(acc, "#{cluster_id}_#{host_id}", changeset) end) @@ -157,7 +158,9 @@ defmodule Trento.CheckResultProjector do TrentoWeb.Endpoint.broadcast("monitoring:clusters", "checks_results_updated", %{ cluster_id: cluster_id, host_id: host_id, - hosts_executions: [%{cluster_id: cluster_id, host_id: host_id, reachable: reachable, msg: msg}], + hosts_executions: [ + %{cluster_id: cluster_id, host_id: host_id, reachable: reachable, msg: msg} + ], checks_results: Enum.map(checks_results, fn %{check_id: check_id, result: result} -> %{host_id: host_id, check_id: check_id, result: result} diff --git a/lib/trento/domain/cluster/cluster.ex b/lib/trento/domain/cluster/cluster.ex index 64330c0f98..f5ea6da639 100644 --- a/lib/trento/domain/cluster/cluster.ex +++ b/lib/trento/domain/cluster/cluster.ex @@ -294,9 +294,10 @@ defmodule Trento.Domain.Cluster do %HostExecution{ host_id: host_id, reachable: true, - checks_results: Enum.map(selected_checks, fn check_id -> - %CheckResult{check_id: check_id, result: :unknown} - end) + checks_results: + Enum.map(selected_checks, fn check_id -> + %CheckResult{check_id: check_id, result: :unknown} + end) } ) end) @@ -330,19 +331,23 @@ defmodule Trento.Domain.Cluster do def apply( %Cluster{hosts_executions: hosts_executions} = cluster, - %HostChecksExecutionCompleted{host_id: host_id, reachable: reachable, msg: msg, checks_results: checks_results} - ) - when reachable == true do - %Cluster{ - cluster - | hosts_executions: Map.put(hosts_executions, host_id, - %HostExecution{ + %HostChecksExecutionCompleted{ host_id: host_id, reachable: reachable, msg: msg, checks_results: checks_results } ) + when reachable == true do + %Cluster{ + cluster + | hosts_executions: + Map.put(hosts_executions, host_id, %HostExecution{ + host_id: host_id, + reachable: reachable, + msg: msg, + checks_results: checks_results + }) } end @@ -353,14 +358,15 @@ defmodule Trento.Domain.Cluster do when reachable == false do %Cluster{ cluster - | hosts_executions: Map.update(hosts_executions, host_id, %HostExecution{}, fn host -> - %HostExecution{ - host_id: host_id, - reachable: reachable, - msg: msg, - checks_results: host.checks_results - } - end) + | hosts_executions: + Map.update(hosts_executions, host_id, %HostExecution{}, fn host -> + %HostExecution{ + host_id: host_id, + reachable: reachable, + msg: msg, + checks_results: host.checks_results + } + end) } end @@ -465,9 +471,12 @@ defmodule Trento.Domain.Cluster do end defp handle_hosts_execution_data( - %{host_id: host_id, reachable: reachable, msg: msg}, multi, cluster_id, hosts_executions) - when reachable == false do - + %{host_id: host_id, reachable: reachable, msg: msg}, + multi, + cluster_id, + hosts_executions + ) + when reachable == false do multi |> Multi.execute(fn _ -> %HostChecksExecutionCompleted{ @@ -481,9 +490,12 @@ defmodule Trento.Domain.Cluster do end defp handle_hosts_execution_data( - %{host_id: host_id, reachable: reachable, msg: msg, checks_results: results}, multi, cluster_id, _hosts_executions) - when reachable == true do - + %{host_id: host_id, reachable: reachable, msg: msg, checks_results: results}, + multi, + cluster_id, + _hosts_executions + ) + when reachable == true do multi |> Multi.execute(fn _ -> %HostChecksExecutionCompleted{ From 8a029c3b7d1e25105acbef0a4dbb6ce853f18a9c Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Mon, 11 Apr 2022 18:12:48 +0200 Subject: [PATCH 10/14] Update unit tests --- test/support/factory.ex | 10 ++ .../integration/checks/checks_test.exs | 123 ++++++++++++++++++ .../check_result_projector_test.exs | 70 +++++++++- test/trento/domain/cluster/cluster_test.exs | 91 ++++++++++++- 4 files changed, 287 insertions(+), 7 deletions(-) diff --git a/test/support/factory.ex b/test/support/factory.ex index 0225122afb..de5842dde7 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -37,6 +37,7 @@ defmodule Trento.Factory do ClusterReadModel, DatabaseInstanceReadModel, DatabaseReadModel, + HostChecksExecutionsReadModel, HostConnectionSettings, HostReadModel, HostTelemetryReadModel, @@ -387,6 +388,15 @@ defmodule Trento.Factory do }) end + def host_checks_result_projection(attrs \\ []) do + Repo.insert!(%HostChecksExecutionsReadModel{ + cluster_id: Keyword.get(attrs, :cluster_id, Faker.UUID.v4()), + host_id: Keyword.get(attrs, :host_id, Faker.UUID.v4()), + reachable: Keyword.get(attrs, :reachable, true), + msg: Keyword.get(attrs, :msg, Faker.StarWars.planet()) + }) + end + def sap_system_with_cluster_and_hosts do %ClusterReadModel{id: cluster_id} = cluster_projection(type: :hana_scale_up, health: :passing) diff --git a/test/trento/application/integration/checks/checks_test.exs b/test/trento/application/integration/checks/checks_test.exs index 40bff99969..66767234cf 100644 --- a/test/trento/application/integration/checks/checks_test.exs +++ b/test/trento/application/integration/checks/checks_test.exs @@ -3,6 +3,7 @@ defmodule Trento.Integration.ChecksTest do use Trento.DataCase import Mox + import Mock alias Trento.Integration.Checks @@ -15,6 +16,16 @@ defmodule Trento.Integration.ChecksTest do ProviderDto } + alias Trento.Domain.Commands.{ + CompleteChecksExecution, + StartChecksExecution + } + + alias Trento.Domain.{ + CheckResult, + HostExecution + } + @runner_fixtures_path File.cwd!() <> "/test/fixtures/runner" def load_runner_fixture(name) do @@ -24,6 +35,8 @@ defmodule Trento.Integration.ChecksTest do |> Jason.decode!() end + @moduletag :integration + test "should return an error if the runner is not reachable" do expect(Trento.Integration.Checks.Mock, :get_catalog, fn -> {:error, "some error"} @@ -287,4 +300,114 @@ defmodule Trento.Integration.ChecksTest do assert {:ok, catalog_by_provider} == Checks.get_catalog_grouped_by_provider() end + + test "should handle execution started event properly" do + with_mock Trento.Commanded, dispatch: fn _, _ -> :ok end do + execution_id = Faker.UUID.v4() + cluster_id = Faker.UUID.v4() + + Checks.handle_callback(%{ + "event" => "execution_started", + "execution_id" => execution_id, + "payload" => %{ + "cluster_id" => cluster_id + } + }) + + assert_called Trento.Commanded.dispatch( + %StartChecksExecution{ + cluster_id: cluster_id + }, + correlation_id: execution_id + ) + end + end + + test "should handle execution completed event properly" do + with_mock Trento.Commanded, dispatch: fn _, _ -> :ok end do + execution_id = Faker.UUID.v4() + cluster_id = Faker.UUID.v4() + host_id_1 = Faker.UUID.v4() + host_id_2 = Faker.UUID.v4() + + Checks.handle_callback(%{ + "event" => "execution_completed", + "execution_id" => execution_id, + "payload" => %{ + "cluster_id" => cluster_id, + "hosts" => [ + %{ + "host_id" => host_id_1, + "reachable" => true, + "msg" => "", + "results" => [ + %{ + "check_id" => "check1", + "result" => "passing" + }, + %{ + "check_id" => "check2", + "result" => "warning" + } + ] + }, + %{ + "host_id" => host_id_2, + "reachable" => true, + "msg" => "", + "results" => [ + %{ + "check_id" => "check1", + "result" => "critical" + }, + %{ + "check_id" => "check2", + "result" => "warning" + } + ] + } + ] + } + }) + + assert_called Trento.Commanded.dispatch( + %CompleteChecksExecution{ + cluster_id: cluster_id, + hosts_executions: [ + %HostExecution{ + checks_results: [ + %CheckResult{ + check_id: "check1", + result: :passing + }, + %CheckResult{ + check_id: "check2", + result: :warning + } + ], + host_id: host_id_1, + msg: nil, + reachable: true + }, + %HostExecution{ + checks_results: [ + %CheckResult{ + check_id: "check1", + result: :critical + }, + %CheckResult{ + check_id: "check2", + result: :warning + } + ], + host_id: host_id_2, + msg: nil, + reachable: true + } + ] + }, + correlation_id: execution_id + ) + end + end end diff --git a/test/trento/application/projectors/check_result_projector_test.exs b/test/trento/application/projectors/check_result_projector_test.exs index 1483084587..c100bc5346 100644 --- a/test/trento/application/projectors/check_result_projector_test.exs +++ b/test/trento/application/projectors/check_result_projector_test.exs @@ -8,10 +8,14 @@ defmodule Trento.CheckResultProjectorTest do alias Trento.{ CheckResultProjector, - CheckResultReadModel + CheckResultReadModel, + HostChecksExecutionsReadModel } - alias Trento.Domain.Events.HostChecksExecutionCompleted + alias Trento.Domain.Events.{ + ChecksExecutionRequested, + HostChecksExecutionCompleted + } test "should project checks results with result unknown when a ChecksExecutionRequested event is received" do event = checks_execution_requested_event() @@ -32,6 +36,36 @@ defmodule Trento.CheckResultProjectorTest do end) end + test "should project hosts executions with emtpy data when a ChecksExecutionRequested event is received" do + host_checks_result_projection( + cluster_id: cluster_id = Faker.UUID.v4(), + host_id: host_id = Faker.UUID.v4(), + reachable: true, + msg: "" + ) + + event = + ChecksExecutionRequested.new!(%{ + cluster_id: cluster_id, + hosts: [host_id], + checks: ["check1"] + }) + + ProjectorTestHelper.project( + CheckResultProjector, + event, + "check_result_projector" + ) + + hosts_executions = Repo.all(HostChecksExecutionsReadModel) + + assert Enum.all?(hosts_executions, fn %HostChecksExecutionsReadModel{ + reachable: reachable + } -> + reachable == nil + end) + end + test "should update a check result when HostChecksExecutionCompleted event is received" do check_result_projection( cluster_id: cluster_id = Faker.UUID.v4(), @@ -61,4 +95,36 @@ defmodule Trento.CheckResultProjectorTest do assert :critical == check_result_projections.result end + + test "should update a host execution when HostChecksExecutionCompleted event is received" do + host_checks_result_projection( + cluster_id: cluster_id = Faker.UUID.v4(), + host_id: host_id = Faker.UUID.v4(), + reachable: true, + msg: "" + ) + + event = + HostChecksExecutionCompleted.new!(%{ + cluster_id: cluster_id, + host_id: host_id, + reachable: true, + msg: "", + checks_results: [] + }) + + ProjectorTestHelper.project( + CheckResultProjector, + event, + "check_result_projector" + ) + + hosts_executions = Repo.all(HostChecksExecutionsReadModel) + + assert Enum.all?(hosts_executions, fn %HostChecksExecutionsReadModel{ + reachable: reachable + } -> + reachable == true + end) + end end diff --git a/test/trento/domain/cluster/cluster_test.exs b/test/trento/domain/cluster/cluster_test.exs index 5608339d53..3d18595af8 100644 --- a/test/trento/domain/cluster/cluster_test.exs +++ b/test/trento/domain/cluster/cluster_test.exs @@ -5,8 +5,6 @@ defmodule Trento.ClusterTest do alias Trento.Support.StructHelper - alias Trento.Domain.Cluster - alias Trento.Domain.Commands.{ CompleteChecksExecution, RegisterClusterHost, @@ -27,7 +25,11 @@ defmodule Trento.ClusterTest do HostChecksExecutionCompleted } - alias Trento.Domain.Cluster + alias Trento.Domain.{ + CheckResult, + Cluster, + HostExecution + } describe "cluster registration" do test "should register a cluster and add the node host to the cluster if the node is a DC" do @@ -221,6 +223,7 @@ defmodule Trento.ClusterTest do cluster_id = Faker.UUID.v4() host_id = Faker.UUID.v4() selected_checks = Enum.map(0..4, fn _ -> Faker.Cat.name() end) + checks_results = Enum.map(selected_checks, &%CheckResult{check_id: &1, result: :unknown}) assert_events_and_state( [ @@ -248,7 +251,14 @@ defmodule Trento.ClusterTest do fn cluster -> assert %Cluster{ health: :unknown, - checks_execution: :requested + checks_execution: :requested, + hosts_executions: %{ + ^host_id => %HostExecution{ + host_id: ^host_id, + reachable: true, + checks_results: ^checks_results + } + } } = cluster end ) @@ -289,6 +299,8 @@ defmodule Trento.ClusterTest do host_id = Faker.UUID.v4() selected_checks = Enum.map(0..4, fn _ -> Faker.Cat.name() end) checks_results = Enum.map(selected_checks, &%{check_id: &1, result: :critical}) + expected_results = Enum.map(checks_results, &CheckResult.new!(&1)) + msg = Faker.StarWars.planet() assert_events_and_state( [ @@ -304,6 +316,8 @@ defmodule Trento.ClusterTest do hosts_executions: [ %{ host_id: host_id, + reachable: true, + msg: msg, checks_results: checks_results } ] @@ -312,6 +326,8 @@ defmodule Trento.ClusterTest do HostChecksExecutionCompleted.new!(%{ cluster_id: cluster_id, host_id: host_id, + reachable: true, + msg: msg, checks_results: checks_results }), %ChecksExecutionCompleted{ @@ -324,7 +340,72 @@ defmodule Trento.ClusterTest do ], fn cluster -> assert %Cluster{ - checks_execution: :not_running + checks_execution: :not_running, + hosts_executions: %{ + ^host_id => %HostExecution{ + host_id: ^host_id, + reachable: true, + checks_results: ^expected_results + } + } + } = cluster + end + ) + end + + test "should complete a checks execution when reachable is false" do + cluster_id = Faker.UUID.v4() + host_id = Faker.UUID.v4() + selected_checks = Enum.map(0..4, fn _ -> Faker.Cat.name() end) + checks_results = Enum.map(selected_checks, &%{check_id: &1, result: :unknown}) + expected_results = Enum.map(checks_results, &CheckResult.new!(&1)) + msg = Faker.StarWars.planet() + + assert_events_and_state( + [ + cluster_registered_event(cluster_id: cluster_id), + host_added_to_cluster_event(cluster_id: cluster_id, host_id: host_id), + %ChecksSelected{ + cluster_id: cluster_id, + checks: selected_checks + }, + checks_execution_requested_event( + cluster_id: cluster_id, + hosts: [host_id], + checks: selected_checks + ) + ], + CompleteChecksExecution.new!(%{ + cluster_id: cluster_id, + hosts_executions: [ + %{ + host_id: host_id, + reachable: false, + msg: msg + } + ] + }), + [ + HostChecksExecutionCompleted.new!(%{ + cluster_id: cluster_id, + host_id: host_id, + reachable: false, + msg: msg, + checks_results: checks_results + }), + %ChecksExecutionCompleted{ + cluster_id: cluster_id + }, + %ClusterHealthChanged{cluster_id: cluster_id, health: :unknown} + ], + fn cluster -> + assert %Cluster{ + checks_execution: :not_running, + hosts_executions: %{ + ^host_id => %HostExecution{ + checks_results: ^expected_results + } + } } = cluster end ) From 615045c0f14b9851e0d1cfb326101ac49b763296 Mon Sep 17 00:00:00 2001 From: arbulu89 Date: Tue, 12 Apr 2022 10:09:32 +0200 Subject: [PATCH 11/14] Fix frontend linting issues --- assets/js/components/ChecksResults.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/components/ChecksResults.jsx b/assets/js/components/ChecksResults.jsx index 44319b3cf1..42b73bfbe8 100644 --- a/assets/js/components/ChecksResults.jsx +++ b/assets/js/components/ChecksResults.jsx @@ -100,7 +100,7 @@ const ChecksResults = () => { return (
{sortHosts(cluster?.hosts_executions.slice()).map( - ({ cluster_id, host_id, reachable, msg }) => ( + ({ _cluster_id, host_id, reachable, msg }) => (
@@ -111,7 +111,7 @@ const ChecksResults = () => { {reachable == false && (