-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add subscriptions projection #138
Changes from all commits
2732738
cbab9c8
020819f
4543b33
e2465a2
255c54c
d35e7dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
defmodule Tronto.Monitoring.Domain.Commands.UpdateSlesSubscriptions do | ||
@moduledoc """ | ||
Update data relative to subscriptions. | ||
""" | ||
|
||
use TypedStruct | ||
use Domo | ||
|
||
alias Tronto.Monitoring.Domain.SlesSubscription | ||
|
||
typedstruct do | ||
@typedoc "UpdateSubscriptions command" | ||
|
||
field :subscriptions, [SlesSubscription.t()], enforce: true | ||
field :host_id, String.t(), enforce: true | ||
end | ||
|
||
use Vex.Struct | ||
|
||
validates :host_id, uuid: true | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
defmodule Tronto.Monitoring.Domain.Events.SlesSubscriptionsUpdated do | ||
@moduledoc """ | ||
Subscriptions updated event | ||
""" | ||
|
||
alias Tronto.Monitoring.Domain.SlesSubscription | ||
|
||
use TypedStruct | ||
|
||
@derive Jason.Encoder | ||
typedstruct do | ||
@typedoc "SubscriptionsUpdated event" | ||
|
||
field :host_id, String.t(), enforce: true | ||
field :subscriptions, [SlesSubscription.t()], enforce: true | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
defmodule Tronto.Monitoring.Domain.SlesSubscription do | ||
@moduledoc """ | ||
SLES subscriptions value object | ||
""" | ||
|
||
use TypedStruct | ||
use Domo | ||
|
||
@derive Jason.Encoder | ||
typedstruct do | ||
@typedoc "SlesSubscription value object" | ||
|
||
field :host_id, String.t(), enforce: true | ||
field :identifier, String.t(), enforce: true | ||
field :version, String.t(), enforce: true | ||
field :arch, String.t(), enforce: true | ||
field :status, String.t(), enforce: true | ||
field :subscription_status, String.t() | ||
field :type, String.t() | ||
field :starts_at, String.t() | ||
field :expires_at, String.t() | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,9 +9,12 @@ defmodule Tronto.Monitoring.Integration.Discovery do | |
alias Tronto.Monitoring.Domain.Commands.{ | ||
RegisterCluster, | ||
RegisterHost, | ||
UpdateProvider | ||
UpdateProvider, | ||
UpdateSlesSubscriptions | ||
} | ||
|
||
alias Tronto.Monitoring.Domain.SlesSubscription | ||
|
||
@spec handle_discovery_event(map) :: {:error, any} | {:ok, command} | ||
def handle_discovery_event(%{ | ||
"discovery_type" => "host_discovery", | ||
|
@@ -67,6 +70,17 @@ defmodule Tronto.Monitoring.Integration.Discovery do | |
) | ||
end | ||
|
||
def handle_discovery_event(%{ | ||
"discovery_type" => "subscription_discovery", | ||
"agent_id" => agent_id, | ||
"payload" => payload | ||
}) do | ||
subscriptions = | ||
Enum.map(payload, fn subscription -> parse_subscription_data(agent_id, subscription) end) | ||
|
||
UpdateSlesSubscriptions.new(host_id: agent_id, subscriptions: subscriptions) | ||
end | ||
|
||
def handle_discovery_event(_) do | ||
{:error, :invalid_payload} | ||
end | ||
|
@@ -123,4 +137,42 @@ defmodule Tronto.Monitoring.Integration.Discovery do | |
nil | ||
end) | ||
end | ||
|
||
defp parse_subscription_data(host_id, %{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know if there is any other option to have just an unique function here, instead of 2 with different values. It would be nice There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the same function with two clauses, ( |
||
"arch" => arch, | ||
"expires_at" => expires_at, | ||
"identifier" => identifier, | ||
"starts_at" => starts_at, | ||
"status" => status, | ||
"subscription_status" => subscription_status, | ||
"type" => type, | ||
"version" => version | ||
}) do | ||
SlesSubscription.new!( | ||
host_id: host_id, | ||
arch: arch, | ||
expires_at: expires_at, | ||
identifier: identifier, | ||
starts_at: starts_at, | ||
status: status, | ||
subscription_status: subscription_status, | ||
type: type, | ||
version: version | ||
) | ||
end | ||
|
||
defp parse_subscription_data(host_id, %{ | ||
"arch" => arch, | ||
"identifier" => identifier, | ||
"status" => status, | ||
"version" => version | ||
}) do | ||
SlesSubscription.new!( | ||
host_id: host_id, | ||
arch: arch, | ||
identifier: identifier, | ||
status: status, | ||
version: version | ||
) | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
defmodule Tronto.Monitoring.SlesSubscriptionsProjector do | ||
@moduledoc """ | ||
Check result projector | ||
""" | ||
|
||
use Commanded.Projections.Ecto, | ||
application: Tronto.Commanded, | ||
repo: Tronto.Repo, | ||
name: "sles_subscription_projector" | ||
|
||
import Ecto.Query | ||
|
||
alias Tronto.Monitoring.Domain.Events.SlesSubscriptionsUpdated | ||
|
||
alias Tronto.Monitoring.SlesSubscriptionReadModel | ||
|
||
project( | ||
%SlesSubscriptionsUpdated{host_id: host_id, subscriptions: subscriptions}, | ||
fn multi -> | ||
multi = | ||
Ecto.Multi.delete_all( | ||
multi, | ||
:delete_old_sles_subscriptions, | ||
from(s in SlesSubscriptionReadModel, where: s.host_id == ^host_id) | ||
) | ||
|
||
subscriptions | ||
|> Enum.map(fn subscription -> | ||
SlesSubscriptionReadModel.changeset( | ||
%SlesSubscriptionReadModel{}, | ||
subscription | ||
) | ||
end) | ||
|> Enum.reduce(multi, fn %{changes: %{host_id: host_id, identifier: identifier}} = changeset, | ||
acc -> | ||
Ecto.Multi.insert(acc, "#{host_id}_#{identifier}", changeset) | ||
end) | ||
end | ||
) | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
defmodule Tronto.Monitoring.SlesSubscriptionReadModel do | ||
@moduledoc """ | ||
SLES subscriptions read model | ||
""" | ||
|
||
use Ecto.Schema | ||
|
||
import Ecto.Changeset | ||
|
||
alias Tronto.Monitoring.HostReadModel | ||
|
||
@type t :: %__MODULE__{} | ||
|
||
@derive {Jason.Encoder, except: [:__meta__, :__struct__]} | ||
@primary_key false | ||
schema "sles_subscriptions" do | ||
field :host_id, Ecto.UUID, primary_key: true | ||
field :identifier, :string, primary_key: true | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. perfect There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually @arbulu89 helped me on this one 😄 |
||
field :version, :string | ||
field :arch, :string | ||
field :status, :string | ||
field :subscription_status, :string | ||
field :type, :string | ||
field :starts_at, :string | ||
field :expires_at, :string | ||
|
||
has_one :host, HostReadModel, references: :host_id, foreign_key: :id | ||
timestamps() | ||
end | ||
|
||
@spec changeset(t() | Ecto.Changeset.t(), map) :: Ecto.Changeset.t() | ||
def changeset(sles_subscription, attrs) do | ||
cast(sles_subscription, attrs, __MODULE__.__schema__(:fields)) | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
defmodule Tronto.Repo.Migrations.CreateSlesSubscriptionReadModel do | ||
use Ecto.Migration | ||
|
||
def change do | ||
create table(:sles_subscriptions, primary_key: false) do | ||
add :host_id, :uuid, primary_key: true | ||
add :identifier, :string, primary_key: true | ||
add :version, :string | ||
add :arch, :string | ||
add :status, :string | ||
add :subscription_status, :string | ||
add :type, :string | ||
add :starts_at, :string | ||
add :expires_at, :string | ||
|
||
timestamps | ||
end | ||
|
||
create index(:sles_subscriptions, [:host_id]) | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this
host_id
field ever used?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like to have it for completion, I don't have a strong opinion about it 😅