Skip to content

Commit

Permalink
Fix sr status broadcast on database instance registration
Browse files Browse the repository at this point in the history
  • Loading branch information
arbulu89 committed Aug 1, 2023
1 parent 58e7887 commit 385dff9
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 36 deletions.
16 changes: 13 additions & 3 deletions lib/trento/application/projectors/database_projector.ex
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,23 @@ defmodule Trento.DatabaseProjector do
def after_update(
%DatabaseInstanceRegistered{},
_,
%{database_instance: %DatabaseInstanceReadModel{} = instance}
%{database_instance: %DatabaseInstanceReadModel{sap_system_id: sap_system_id} = instance}
) do
# All database instances are required to compute the system replication status in the current instance
database_instances =
DatabaseInstanceReadModel
|> where([i], i.sap_system_id == ^sap_system_id)
|> Repo.all()

TrentoWeb.Endpoint.broadcast(
@databases_topic,
"database_instance_registered",
SapSystemView.render("database_instance.json",
instance: instance
SapSystemView.render(
"database_instance_with_sr_status.json",
%{
instance: instance,
database_instances: database_instances
}
)
)
end
Expand Down
64 changes: 42 additions & 22 deletions lib/trento_web/views/v1/sap_system_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ defmodule TrentoWeb.V1.SapSystemView do
|> Map.delete(:host)
end

def render("database_instance_with_sr_status.json", %{
instance: instance,
database_instances: database_instances
}) do
"database_instance.json"
|> render(%{instance: instance})
|> add_system_replication_status(database_instances)
end

def render("database_registered.json", %{database: database}) do
database
|> Map.from_struct()
Expand Down Expand Up @@ -159,32 +168,43 @@ defmodule TrentoWeb.V1.SapSystemView do
defp add_system_replication_status_to_secondary_instance(
%{database_instances: database_instances} = sap_system
) do
system_replication_status =
Enum.find_value(database_instances, fn
%{
system_replication: "Primary",
system_replication_status: system_replication_status
} ->
system_replication_status

_ ->
false
end)
system_replication_status = get_system_replication_status(database_instances)

database_instances =
Enum.map(database_instances, fn
%{
system_replication: "Secondary"
} = instance ->
%{instance | system_replication_status: system_replication_status}
Enum.map(
database_instances,
&map_system_replication_status_to_secondary(&1, system_replication_status)
)

%{system_replication: "Primary"} = instance ->
%{instance | system_replication_status: ""}
Map.put(sap_system, :database_instances, database_instances)
end

instance ->
instance
end)
defp add_system_replication_status(instance, database_instances) do
system_replication_status = get_system_replication_status(database_instances)
map_system_replication_status_to_secondary(instance, system_replication_status)
end

Map.put(sap_system, :database_instances, database_instances)
defp get_system_replication_status(database_instances) do
Enum.find_value(database_instances, fn
%{
system_replication: "Primary",
system_replication_status: system_replication_status
} ->
system_replication_status

_ ->
false
end)
end

defp map_system_replication_status_to_secondary(
%{system_replication: "Secondary"} = instance,
system_replication_status
),
do: %{instance | system_replication_status: system_replication_status}

defp map_system_replication_status_to_secondary(%{system_replication: "Primary"} = instance, _),
do: %{instance | system_replication_status: ""}

defp map_system_replication_status_to_secondary(instance, _), do: instance
end
71 changes: 60 additions & 11 deletions test/trento/application/projectors/database_projector_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,14 @@ defmodule Trento.DatabaseProjectorTest do

test "should project a new database instance when DatabaseInstanceRegistered event is received" do
insert(:database, id: sap_system_id = Faker.UUID.v4())
event = build(:database_instance_registered_event, sap_system_id: sap_system_id)

event =
build(
:database_instance_registered_event,
sap_system_id: sap_system_id,
system_replication: "",
system_replication_status: ""
)

ProjectorTestHelper.project(DatabaseProjector, event, "database_projector")

Expand All @@ -82,9 +89,7 @@ defmodule Trento.DatabaseProjectorTest do
sid: sid,
features: features,
host_id: host_id,
tenant: tenant,
system_replication: system_replication,
system_replication_status: system_replication_status
tenant: tenant
} =
database_instance_projection =
Repo.get_by(DatabaseInstanceReadModel,
Expand All @@ -99,11 +104,6 @@ defmodule Trento.DatabaseProjectorTest do
assert event.instance_number == database_instance_projection.instance_number
assert event.features == database_instance_projection.features
assert event.host_id == database_instance_projection.host_id
assert event.system_replication == database_instance_projection.system_replication

assert event.system_replication_status ==
database_instance_projection.system_replication_status

assert event.health == database_instance_projection.health

assert_broadcast "database_instance_registered",
Expand All @@ -118,13 +118,62 @@ defmodule Trento.DatabaseProjectorTest do
instance_number: "00",
sap_system_id: ^sap_system_id,
start_priority: "0.3",
system_replication: ^system_replication,
system_replication_status: ^system_replication_status,
system_replication: "",
system_replication_status: "",
tenant: ^tenant
},
1000
end

test "should project a new database instance as Primary" do
insert(:database, id: sap_system_id = Faker.UUID.v4())

event =
build(
:database_instance_registered_event,
sap_system_id: sap_system_id,
system_replication: "Primary",
system_replication_status: "ACTIVE"
)

ProjectorTestHelper.project(DatabaseProjector, event, "database_projector")

assert_broadcast "database_instance_registered",
%{
system_replication: "Primary",
system_replication_status: ""
},
1000
end

test "should project a new database instance as Secondary" do
%{id: sap_system_id} = insert(:database)

insert(
:database_instance,
sap_system_id: sap_system_id,
system_replication: "Primary",
system_replication_status: "ACTIVE"
)

event =
build(
:database_instance_registered_event,
sap_system_id: sap_system_id,
system_replication: "Secondary",
system_replication_status: ""
)

ProjectorTestHelper.project(DatabaseProjector, event, "database_projector")

assert_broadcast "database_instance_registered",
%{
system_replication: "Secondary",
system_replication_status: "ACTIVE"
},
1000
end

test "should update the system replication when DatabaseInstanceSystemReplicationChanged is received" do
%{
sap_system_id: sap_system_id,
Expand Down

0 comments on commit 385dff9

Please sign in to comment.