diff --git a/config/config.exs b/config/config.exs index 0122845..38155e0 100644 --- a/config/config.exs +++ b/config/config.exs @@ -36,5 +36,5 @@ config :spark, ] ] -config :diffo, ash_domains: [Diffo.Provider, Diffo.Access] +config :diffo, ash_domains: [Diffo.Provider] import_config "#{config_env()}.exs" diff --git a/lib/diffo.ex b/lib/diffo.ex index 7fc29c1..a0ce600 100644 --- a/lib/diffo.ex +++ b/lib/diffo.ex @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2025 ash_neo4j contributors +# SPDX-FileCopyrightText: 2025 diffo contributors # # SPDX-License-Identifier: MIT diff --git a/lib/diffo/access/access.ex b/lib/diffo/access/access.ex deleted file mode 100644 index 9f1c996..0000000 --- a/lib/diffo/access/access.ex +++ /dev/null @@ -1,63 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - Access - example domain - """ - use Ash.Domain, - otp_app: :diffo - - alias Diffo.Access.DslAccess - alias Diffo.Access.Shelf - alias Diffo.Access.Card - alias Diffo.Access.Cable - alias Diffo.Access.Path - - domain do - description "An example showing how TMF Services and Resources for a fictional Access domain can be extended from the Provider domain" - end - - resources do - resource DslAccess do - define :get_dsl_by_id, action: :read, get_by: :id - define :qualify_dsl, action: :qualify - define :qualify_dsl_result, action: :qualify_result - define :design_dsl_result, action: :design_result - end - - resource Shelf do - define :get_shelf_by_id, action: :read, get_by: :id - define :build_shelf, action: :build - define :define_shelf, action: :define - define :relate_shelf, action: :relate - define :assign_slot, action: :assign_slot - end - - resource Card do - define :get_card_by_id, action: :read, get_by: :id - define :build_card, action: :build - define :define_card, action: :define - define :relate_card, action: :relate - define :assign_port, action: :assign_port - end - - resource Cable do - define :get_cable_by_id, action: :read, get_by: :id - define :build_cable, action: :build - define :define_cable, action: :define - define :relate_cable, action: :relate - define :assign_pair, action: :assign_pair - end - - resource Path do - define :get_path_by_id, action: :read, get_by: :id - define :build_path, action: :build - define :define_path, action: :define - define :relate_path, action: :relate - end - end -end diff --git a/lib/diffo/access/resources/cable.ex b/lib/diffo/access/resources/cable.ex deleted file mode 100644 index 1d91673..0000000 --- a/lib/diffo/access/resources/cable.ex +++ /dev/null @@ -1,117 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.Cable do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - Cable - Cable Resource Instance - """ - - alias Diffo.Provider.BaseInstance - alias Diffo.Provider.Instance.Specification - alias Diffo.Provider.Instance.Relationship - alias Diffo.Provider.Instance.Feature - alias Diffo.Provider.Instance.Characteristic - alias Diffo.Provider.Instance.Place - alias Diffo.Provider.Instance.Party - alias Diffo.Provider.Assigner - alias Diffo.Provider.Assignment - - alias Diffo.Access - - use Ash.Resource, - fragments: [BaseInstance], - domain: Access - - resource do - description "An Ash Resource representing a Cable" - plural_name :Cables - end - - specification do - id "ce0a567a-6abb-4862-9e33-851fd79fa595" - name "cable" - type :resourceSpecification - description "A Cable Resource Instance" - category "Network Resource" - end - - characteristics do - characteristic :cable, Diffo.Access.CableValue - characteristic :pairs, Diffo.Provider.AssignableValue - end - - actions do - create :build do - description "creates a new Cable resource instance for build" - accept [:id, :name, :type, :which] - argument :specified_by, :uuid, public?: false - argument :relationships, {:array, :struct} - argument :features, {:array, :uuid}, public?: false - argument :characteristics, {:array, :uuid}, public?: false - argument :places, {:array, :struct} - argument :parties, {:array, :struct} - - change set_attribute(:type, :resource) - - change before_action(fn changeset, _context -> - changeset - |> Specification.set_specified_by_argument() - |> Feature.set_features_argument() - |> Characteristic.set_characteristics_argument() - end) - - change after_action(fn changeset, result, _context -> - with {:ok, with_specification} <- Specification.relate_instance(result, changeset), - {:ok, with_relationships} <- - Relationship.relate_instance(with_specification, changeset), - {:ok, with_features} <- - Feature.relate_instance(with_relationships, changeset), - {:ok, with_characteristics} <- - Characteristic.relate_instance(with_features, changeset), - {:ok, with_places} <- Place.relate_instance(with_characteristics, changeset), - {:ok, _with_parties} <- Party.relate_instance(with_places, changeset), - {:ok, cable} <- Access.get_cable_by_id(result.id), - do: {:ok, cable} - end) - - change load [:href] - upsert? false - end - - update :define do - description "defines the cable" - argument :characteristic_value_updates, {:array, :term} - - change after_action(fn changeset, result, _context -> - with {:ok, _result} <- Characteristic.update_values(result, changeset), - {:ok, cable} <- Access.get_cable_by_id(result.id), - do: {:ok, cable} - end) - end - - update :relate do - description "relates the cable with other instances" - argument :relationships, {:array, :struct} - - change after_action(fn changeset, result, _context -> - with {:ok, _cable} <- Relationship.relate_instance(result, changeset), - {:ok, cable} <- Access.get_cable_by_id(result.id), - do: {:ok, cable} - end) - end - - update :assign_pair do - description "relates the cable with an instance by assigning a pair" - argument :assignment, :struct, constraints: [instance_of: Assignment] - - change after_action(fn changeset, result, _context -> - with {:ok, _cable} <- Assigner.assign(result, changeset, :pairs, :pair), - {:ok, cable} <- Access.get_cable_by_id(result.id), - do: {:ok, cable} - end) - end - end -end diff --git a/lib/diffo/access/resources/characteristic_values/cable_value.ex b/lib/diffo/access/resources/characteristic_values/cable_value.ex deleted file mode 100644 index cdcaf97..0000000 --- a/lib/diffo/access/resources/characteristic_values/cable_value.ex +++ /dev/null @@ -1,43 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.CableValue do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - CableValue - AshTyped Struct for Cable Characteristic Value - """ - use Ash.TypedStruct, extensions: [AshJason.TypedStruct, AshOutstanding.TypedStruct] - - jason do - pick [:name, :pairs, :length, :loss, :technology] - compact(true) - end - - outstanding do - expect [:pairs, :loss] - end - - typed_struct do - field :name, :string, description: "the cable name" - - field :pairs, :integer, description: "the number of pairs in the cable" - - field :length, :struct, - constraints: [instance_of: IntegerUnit], - description: "the length of the cable" - - field :loss, :struct, - constraints: [instance_of: FloatUnit], - description: "the loss of the cable at 300kHz" - - field :technology, :atom, description: "the cable technology" - end - - defimpl String.Chars do - def to_string(struct) do - inspect(struct) - end - end -end diff --git a/lib/diffo/access/resources/characteristic_values/float_unit.ex b/lib/diffo/access/resources/characteristic_values/float_unit.ex deleted file mode 100644 index 57c9600..0000000 --- a/lib/diffo/access/resources/characteristic_values/float_unit.ex +++ /dev/null @@ -1,33 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.FloatUnit do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - FloatUnit - AshTyped Struct for Float with Unit - """ - use Ash.TypedStruct, extensions: [AshJason.TypedStruct, AshOutstanding.TypedStruct] - - jason do - pick [:amount, :unit] - compact(true) - end - - outstanding do - expect [:amount, :unit] - end - - typed_struct do - field :amount, :float, description: "the amount" - - field :unit, :atom, description: "the unit" - end - - defimpl String.Chars do - def to_string(struct) do - inspect(struct) - end - end -end diff --git a/lib/diffo/access/resources/characteristic_values/integer_unit.ex b/lib/diffo/access/resources/characteristic_values/integer_unit.ex deleted file mode 100644 index 764edaa..0000000 --- a/lib/diffo/access/resources/characteristic_values/integer_unit.ex +++ /dev/null @@ -1,33 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.IntegerUnit do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - IntegerUnit - AshTyped Struct for Integer with Unit - """ - use Ash.TypedStruct, extensions: [AshJason.TypedStruct, AshOutstanding.TypedStruct] - - jason do - pick [:amount, :unit] - compact(true) - end - - outstanding do - expect [:amount, :unit] - end - - typed_struct do - field :amount, :integer, description: "the amount" - - field :unit, :atom, description: "the unit" - end - - defimpl String.Chars do - def to_string(struct) do - inspect(struct) - end - end -end diff --git a/lib/diffo/access/resources/characteristic_values/path_value.ex b/lib/diffo/access/resources/characteristic_values/path_value.ex deleted file mode 100644 index aa935ea..0000000 --- a/lib/diffo/access/resources/characteristic_values/path_value.ex +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.PathValue do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - PathValue - AshTyped Struct for Path Characteristic Value - """ - use Ash.TypedStruct, extensions: [AshJason.TypedStruct, AshOutstanding.TypedStruct] - - jason do - pick [:name, :sections, :length, :loss, :technology] - compact(true) - end - - outstanding do - expect [:loss] - end - - typed_struct do - field :name, :string, description: "the cable name" - - field :sections, :integer, - default: 0, - constraints: [min: 0], - description: "the number of sections in the path" - - field :length, :struct, - constraints: [instance_of: IntegerUnit], - description: "the length of the path" - - field :loss, :struct, - constraints: [instance_of: FloatUnit], - description: "the loss of the path at 300kHz" - - field :technology, :atom, description: "the path technology" - end - - defimpl String.Chars do - def to_string(struct) do - inspect(struct) - end - end -end diff --git a/lib/diffo/access/resources/path.ex b/lib/diffo/access/resources/path.ex deleted file mode 100644 index bbf1262..0000000 --- a/lib/diffo/access/resources/path.ex +++ /dev/null @@ -1,103 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.Path do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - Path - Path Resource Instance - """ - - alias Diffo.Provider.BaseInstance - alias Diffo.Provider.Instance.Specification - alias Diffo.Provider.Instance.Relationship - alias Diffo.Provider.Instance.Feature - alias Diffo.Provider.Instance.Characteristic - alias Diffo.Provider.Instance.Place - alias Diffo.Provider.Instance.Party - - alias Diffo.Access - - use Ash.Resource, - fragments: [BaseInstance], - domain: Access - - resource do - description "An Ash Resource representing a Path" - plural_name :Paths - end - - specification do - id "1d507914-8f76-48cb-aa0e-3a8f92951ab0" - name "path" - type :resourceSpecification - description "A Path Resource Instance" - category "Network Resource" - end - - characteristics do - characteristic :path, Diffo.Access.PathValue - end - - actions do - create :build do - description "creates a new Path resource instance for build" - accept [:id, :name, :type, :which] - argument :specified_by, :uuid, public?: false - argument :relationships, {:array, :struct} - argument :features, {:array, :uuid}, public?: false - argument :characteristics, {:array, :uuid}, public?: false - argument :places, {:array, :struct} - argument :parties, {:array, :struct} - - change set_attribute(:type, :resource) - - change before_action(fn changeset, _context -> - changeset - |> Specification.set_specified_by_argument() - |> Feature.set_features_argument() - |> Characteristic.set_characteristics_argument() - end) - - change after_action(fn changeset, result, _context -> - with {:ok, with_specification} <- Specification.relate_instance(result, changeset), - {:ok, with_relationships} <- - Relationship.relate_instance(with_specification, changeset), - {:ok, with_features} <- - Feature.relate_instance(with_relationships, changeset), - {:ok, with_characteristics} <- - Characteristic.relate_instance(with_features, changeset), - {:ok, with_places} <- Place.relate_instance(with_characteristics, changeset), - {:ok, _with_parties} <- Party.relate_instance(with_places, changeset), - {:ok, path} <- Access.get_path_by_id(result.id), - do: {:ok, path} - end) - - change load [:href] - upsert? false - end - - update :define do - description "defines the path" - argument :characteristic_value_updates, {:array, :term} - - change after_action(fn changeset, result, _context -> - with {:ok, _result} <- Characteristic.update_values(result, changeset), - {:ok, path} <- Access.get_path_by_id(result.id), - do: {:ok, path} - end) - end - - update :relate do - description "relates the path with other instances" - argument :relationships, {:array, :struct} - - change after_action(fn changeset, result, _context -> - with {:ok, _path} <- Relationship.relate_instance(result, changeset), - {:ok, path} <- Access.get_path_by_id(result.id), - do: {:ok, path} - end) - end - end -end diff --git a/lib/diffo/access/services/characteristic_values/aggregate_interface.ex b/lib/diffo/access/services/characteristic_values/aggregate_interface.ex deleted file mode 100644 index 383ee18..0000000 --- a/lib/diffo/access/services/characteristic_values/aggregate_interface.ex +++ /dev/null @@ -1,55 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.AggregateInterface do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - AggregateInterface - AshTyped Struct for AggregateInterface Characteristic Value - """ - use Ash.TypedStruct, extensions: [AshJason.TypedStruct, AshOutstanding.TypedStruct] - - jason do - pick [:name, :physical_interface, :physical_layer, :link_layer, :svlan_id, :vpi] - compact(true) - end - - outstanding do - expect [:name] - end - - typed_struct do - field :name, :string, description: "the name of the aggregate interface" - - field :physical_interface, :string, - constraints: [match: ~r/OC-3 LR(-2)?|1000BASE-(L|E|Z)X/], - description: "the aggregate interface physical interface type" - - field :physical_layer, :atom, - constraints: [one_of: [:STM1, :GbE]], - default: :GbE, - description: "the aggregate interface physical layer standard" - - field :link_layer, :atom, - constraints: [one_of: [:VP, :Q, :QinQ]], - default: :QinQ, - description: "the aggregate interface link layer standard" - - field :svlan_id, :integer, - constraints: [min: 0, max: 4095], - default: 0, - description: "the aggregate interface svlan_id" - - field :vpi, :integer, - constraints: [min: 0, max: 4095], - default: 0, - description: "the aggregate interface vpi" - end - - defimpl String.Chars do - def to_string(struct) do - inspect(struct) - end - end -end diff --git a/lib/diffo/access/services/characteristic_values/bandwidth_profile.ex b/lib/diffo/access/services/characteristic_values/bandwidth_profile.ex deleted file mode 100644 index a7a5ac9..0000000 --- a/lib/diffo/access/services/characteristic_values/bandwidth_profile.ex +++ /dev/null @@ -1,42 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.BandwidthProfile do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - BandwidthProfile - AshTyped Struct for BandwidthProfile - """ - use Ash.TypedStruct, extensions: [AshJason.TypedStruct, AshOutstanding.TypedStruct] - - jason do - pick [:downstream, :upstream, :units] - compact(true) - end - - outstanding do - expect [:downstream, :upstream, :units] - end - - typed_struct do - field :downstream, :integer, - constraints: [min: 0], - description: "the bandwidth profile downstream rate" - - field :upstream, :integer, - constraints: [min: 0], - description: "the bandwidth profile upstream rate" - - field :units, :atom, - default: :Mbps, - constraints: [one_of: [:kbps, :Mbps]], - description: "the bandwidth profile units" - end - - defimpl String.Chars do - def to_string(struct) do - inspect(struct) - end - end -end diff --git a/lib/diffo/access/services/characteristic_values/circuit.ex b/lib/diffo/access/services/characteristic_values/circuit.ex deleted file mode 100644 index e3b33eb..0000000 --- a/lib/diffo/access/services/characteristic_values/circuit.ex +++ /dev/null @@ -1,54 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.Circuit do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - Circuit - AshTyped Struct for Circuit Characteristic Value - """ - use Ash.TypedStruct, extensions: [AshJason.TypedStruct, AshOutstanding.TypedStruct] - - alias Diffo.Access.BandwidthProfile - - jason do - pick [:circuit_id, :cvlan_id, :vci, :encapsulation, :bandwidth_profile] - compact(true) - end - - outstanding do - expect [:circuit_id] - end - - typed_struct do - field :circuit_id, :string, - constraints: [match: ~r/Q[A-Z]{4}\d{4} eth \d{1,4}:\d{1,4}/], - description: "the circuit id" - - field :cvlan_id, :integer, - default: 0, - constraints: [min: 0, max: 4095], - description: "the circuit cvlan id" - - field :vci, :integer, - default: 0, - constraints: [min: 0, max: 4095], - description: "the circuit vci" - - field :encapsulation, :atom, - default: :IPoE, - constraints: [one_of: [:PPPoA, :PPPoE, :IPoE]], - description: "the circuit encapsulation" - - field :bandwidth_profile, :struct, - constraints: [instance_of: BandwidthProfile], - description: "the circuit bandwidth profile" - end - - defimpl String.Chars do - def to_string(struct) do - inspect(struct) - end - end -end diff --git a/lib/diffo/access/services/characteristic_values/constraints.ex b/lib/diffo/access/services/characteristic_values/constraints.ex deleted file mode 100644 index f2baef6..0000000 --- a/lib/diffo/access/services/characteristic_values/constraints.ex +++ /dev/null @@ -1,37 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.Constraints do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - Constraints - AshTyped Struct for Constraints Characteristic Value - """ - use Ash.TypedStruct, extensions: [AshJason.TypedStruct, AshOutstanding.TypedStruct] - - jason do - pick [:max_latency, :min_profile] - compact(true) - end - - outstanding do - expect [:max_latency, :min_profile] - end - - typed_struct do - field :max_latency, :integer, - constraints: [min: 0, max: 47], - description: "the maximum latency in ms" - - field :min_profile, :struct, - constraints: [instance_of: BandwidthProfile], - description: "the circuit bandwidth profile" - end - - defimpl String.Chars do - def to_string(struct) do - inspect(struct) - end - end -end diff --git a/lib/diffo/access/services/characteristic_values/dslam.ex b/lib/diffo/access/services/characteristic_values/dslam.ex deleted file mode 100644 index 051d8e4..0000000 --- a/lib/diffo/access/services/characteristic_values/dslam.ex +++ /dev/null @@ -1,45 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.Dslam do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - Dslam - AshTyped Struct for Dslam Characteristic Value - """ - use Ash.TypedStruct, extensions: [AshJason.TypedStruct, AshOutstanding.TypedStruct] - - jason do - pick [:name, :family, :model, :technology] - compact(true) - end - - outstanding do - expect [:name] - end - - typed_struct do - field :name, :string, - constraints: [match: ~r/Q[A-Z]{4}\d{4}/], - description: "the DSLAM name" - - field :family, :atom, - constraints: [one_of: [:ISAM, :AMX]], - default: :ISAM, - description: "the DSLAM family name" - - field :model, :string, description: "the DSLAM model name" - - field :technology, :atom, - constraints: [one_of: [:eth, :atm]], - default: :eth, - description: "the DSLAM technology" - end - - defimpl String.Chars do - def to_string(struct) do - inspect(struct) - end - end -end diff --git a/lib/diffo/access/services/characteristic_values/line.ex b/lib/diffo/access/services/characteristic_values/line.ex deleted file mode 100644 index 5095654..0000000 --- a/lib/diffo/access/services/characteristic_values/line.ex +++ /dev/null @@ -1,44 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.Line do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - Line - AshTyped Struct for Line Characteristic Value - """ - use Ash.TypedStruct, extensions: [AshJason.TypedStruct, AshOutstanding.TypedStruct] - - jason do - pick [:port, :slot, :standard, :profile] - compact(true) - end - - outstanding do - expect [:port, :slot, :profile] - end - - typed_struct do - field :port, :integer, - constraints: [min: 0, max: 47], - description: "the line port number" - - field :slot, :integer, - constraints: [min: 0, max: 15], - description: "the line port slot number" - - field :standard, :atom, - constraints: [one_of: [:ADSL, :ADSL2plus, :VDSL]], - default: :ADSL2plus, - description: "the line port standard" - - field :profile, :string, description: "the line port profile" - end - - defimpl String.Chars do - def to_string(struct) do - inspect(struct) - end - end -end diff --git a/lib/diffo/access/services/dsl_access.ex b/lib/diffo/access/services/dsl_access.ex deleted file mode 100644 index 98cb2cc..0000000 --- a/lib/diffo/access/services/dsl_access.ex +++ /dev/null @@ -1,127 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.DslAccess do - @moduledoc """ - Diffo - TMF Service and Resource Management with a difference - - DslAccess - DSL Access Service Instance - """ - - alias Diffo.Provider.BaseInstance - alias Diffo.Provider.Instance.Specification - alias Diffo.Provider.Instance.Feature - alias Diffo.Provider.Instance.Characteristic - alias Diffo.Provider.Instance.Party - alias Diffo.Provider.Instance.Place - alias Diffo.Access - - use Ash.Resource, - fragments: [BaseInstance], - domain: Access - - resource do - description "An Ash Resource representing a DSL Access Service" - plural_name :DslAccesses - end - - specification do - id "da9b207a-26c3-451d-8abd-0640c6349979" - name "dslAccess" - description "A DSL Access Network Service connecting a subscriber premises to an NNI" - category "Network Service" - end - - features do - feature :dynamic_line_management do - is_enabled? true - characteristic :constraints, Diffo.Access.Constraints - end - end - - characteristics do - characteristic :dslam, Diffo.Access.Dslam - characteristic :aggregate_interface, Diffo.Access.AggregateInterface - characteristic :circuit, Diffo.Access.Circuit - characteristic :line, Diffo.Access.Line - end - - state_machine do - transitions do - transition action: :qualify_result, from: :initial, to: :feasibilityChecked - transition action: :design_result, from: [:initial, :feasibilityChecked], to: :reserved - end - end - - actions do - create :qualify do - description "creates a new DSL Access service instance for qualification" - accept [:id, :name, :type, :which] - argument :places, {:array, :struct} - argument :parties, {:array, :struct} - argument :specified_by, :uuid, public?: false - argument :characteristics, {:array, :uuid}, public?: false - argument :features, {:array, :uuid}, public?: false - - change before_action(fn changeset, _context -> - changeset - |> Specification.set_specified_by_argument() - |> Feature.set_features_argument() - |> Characteristic.set_characteristics_argument() - end) - - change after_action(fn changeset, result, _context -> - with {:ok, with_specification} <- Specification.relate_instance(result, changeset), - {:ok, with_features} <- - Feature.relate_instance(with_specification, changeset), - {:ok, with_characteristics} <- - Characteristic.relate_instance(with_features, changeset), - {:ok, with_parties} <- Party.relate_instance(with_characteristics, changeset), - {:ok, _with_places} <- Place.relate_instance(with_parties, changeset), - {:ok, dsl_access} <- Access.get_dsl_by_id(result.id), - do: {:ok, dsl_access} - end) - - change load [:href] - upsert? false - end - - update :qualify_result do - description "updates the DSL Access service with qualification result" - accept [:service_operating_status] - argument :places, {:array, :struct} - require_atomic? false - - change transition_state(:feasibilityChecked) - - validate argument_in(:service_operating_status, [ - nil, - :initial, - :pending, - :unknown, - :feasible, - :not_feasible - ]) - - change after_action(fn changeset, result, _context -> - with {:ok, _with_place} <- Place.relate_instance(result, changeset), - {:ok, dsl_access} <- Access.get_dsl_by_id(result.id), - do: {:ok, dsl_access} - end) - end - - update :design_result do - description "updates the DSL Access service with the design" - argument :characteristic_value_updates, {:array, :term} - - change transition_state(:reserved) - - change after_action(fn changeset, result, _context -> - with {:ok, _result} <- Characteristic.update_values(result, changeset), - {:ok, dsl_access} <- Access.get_dsl_by_id(result.id), - do: {:ok, dsl_access} - end) - end - end -end diff --git a/lib/diffo/provider/components/instance/extension/action_helper.ex b/lib/diffo/provider/components/instance/extension/action_helper.ex new file mode 100644 index 0000000..39df01e --- /dev/null +++ b/lib/diffo/provider/components/instance/extension/action_helper.ex @@ -0,0 +1,42 @@ +# SPDX-FileCopyrightText: 2025 diffo contributors +# +# SPDX-License-Identifier: MIT + +defmodule Diffo.Provider.Instance.ActionHelper do + @moduledoc """ + Diffo - TMF Service and Resource Management with a difference + + ActionHelper - helping with Instance actions + """ + + alias Diffo.Provider.Instance.Specification + alias Diffo.Provider.Instance.Relationship + alias Diffo.Provider.Instance.Feature + alias Diffo.Provider.Instance.Characteristic + alias Diffo.Provider.Instance.Place + alias Diffo.Provider.Instance.Party + + @doc """ + build before_action helper, injects instance dsl configuration into the changeset + """ + def build_before(changeset) do + changeset + |> Specification.set_specified_by_argument() + |> Feature.set_features_argument() + |> Characteristic.set_characteristics_argument() + end + + @doc """ + build after_action helper, relates TMF entities to the new instance + """ + def build_after(changeset, result, module, function) do + with {:ok, result} <- Specification.relate_instance(result, changeset), + {:ok, result} <- Relationship.relate_instance(result, changeset), + {:ok, result} <- Feature.relate_instance(result, changeset), + {:ok, result} <- Characteristic.relate_instance(result, changeset), + {:ok, result} <- Place.relate_instance(result, changeset), + {:ok, result} <- Party.relate_instance(result, changeset), + {:ok, result} <- apply(module, function, [result.id]), + do: {:ok, result} + end +end diff --git a/test/access/cable_test.exs b/test/access/cable_test.exs deleted file mode 100644 index 5cc5f07..0000000 --- a/test/access/cable_test.exs +++ /dev/null @@ -1,170 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.CableTest do - @moduledoc false - use ExUnit.Case - alias Diffo.Provider.Specification - alias Diffo.Provider.Characteristic - alias Diffo.Provider.Assignment - alias Diffo.Access - alias Diffo.Access.Cable - alias Diffo.Access.IntegerUnit - alias Diffo.Test.Characteristics - - setup_all do - AshNeo4j.BoltxHelper.start() - end - - setup do - on_exit(fn -> - AshNeo4j.Neo4jHelper.delete_all() - end) - end - - describe "build cable" do - test "create a cable" do - {:ok, cable} = Access.build_cable(%{}) - - # check the instance is a Cable - assert is_struct(cable, Cable) - - # check specification resource enrichment and node relationship - refute is_nil(cable.specification_id) - assert is_struct(cable.specification, Specification) - - assert AshNeo4j.Neo4jHelper.nodes_relate_how?( - :Instance, - %{uuid: cable.id}, - :Specification, - %{uuid: cable.specification_id}, - :SPECIFIED_BY, - :outgoing - ) - - # check characteristic resource enrichment and node relationships - assert is_list(cable.characteristics) - assert length(cable.characteristics) == 2 - - Enum.each(cable.characteristics, fn characteristic -> - assert is_struct(characteristic, Characteristic) - - assert AshNeo4j.Neo4jHelper.nodes_relate_how?( - :Instance, - %{uuid: cable.id}, - :Characteristic, - %{uuid: characteristic.id}, - :HAS, - :outgoing - ) - end) - - encoding = Jason.encode!(cable) |> Diffo.Util.summarise_dates() - - assert encoding == - ~s({\"id\":\"#{cable.id}",\"href\":\"resourceInventoryManagement/v4/resource/cable/#{cable.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"ce0a567a-6abb-4862-9e33-851fd79fa595\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/ce0a567a-6abb-4862-9e33-851fd79fa595\",\"name\":\"cable\",\"version\":\"v1.0.0\"},\"resourceCharacteristic\":[{\"name\":\"cable\",\"value\":{}},{\"name\":\"pairs\",\"value\":{\"first\":1,\"last\":1,\"free\":1,\"algorithm\":\"lowest\"}}]}) - end - - test "define cable" do - {:ok, cable} = Access.build_cable(%{}) - - updates = [ - cable: [pairs: 60, length: %IntegerUnit{amount: 600, unit: :m}, technology: :PIUT], - pairs: [first: 1, last: 60, free: 60, type: "copper"] - ] - - {:ok, cable} = Access.define_cable(cable, %{characteristic_value_updates: updates}) - - encoding = Jason.encode!(cable) |> Diffo.Util.summarise_dates() - - assert encoding == - ~s({\"id\":\"#{cable.id}",\"href\":\"resourceInventoryManagement/v4/resource/cable/#{cable.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"ce0a567a-6abb-4862-9e33-851fd79fa595\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/ce0a567a-6abb-4862-9e33-851fd79fa595\",\"name\":\"cable\",\"version\":\"v1.0.0\"},\"resourceCharacteristic\":[{\"name\":\"cable\",\"value\":{\"pairs\":60,\"length\":{\"amount\":600,\"unit\":\"m\"},\"technology\":\"PIUT\"}},{\"name\":\"pairs\",\"value\":{\"first\":1,\"last\":60,\"free\":60,\"type\":\"copper\",\"algorithm\":\"lowest\"}}]}) - end - - test "auto assign pair to service" do - {:ok, assignee} = Access.qualify_dsl() - - {:ok, cable} = Access.build_cable(%{}) - - updates = [ - cable: [pairs: 60, length: %IntegerUnit{amount: 600, unit: :m}, technology: :PIUT], - pairs: [first: 1, last: 60, free: 60, type: "copper"] - ] - - {:ok, cable} = Access.define_cable(cable, %{characteristic_value_updates: updates}) - - {:ok, cable} = - Access.assign_pair(cable, %{ - assignment: %Assignment{assignee_id: assignee.id, operation: :auto_assign} - }) - - Characteristics.check_values([pairs: [free: 59]], cable) - - encoding = Jason.encode!(cable) |> Diffo.Util.summarise_dates() - - assert encoding == - ~s({\"id\":\"#{cable.id}",\"href\":\"resourceInventoryManagement/v4/resource/cable/#{cable.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"ce0a567a-6abb-4862-9e33-851fd79fa595\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/ce0a567a-6abb-4862-9e33-851fd79fa595\",\"name\":\"cable\",\"version\":\"v1.0.0\"},\"serviceRelationship\":[{\"type\":\"assignedTo\",\"service\":{\"id\":\"#{assignee.id}\",\"href\":\"serviceInventoryManagement/v4/service/dslAccess/#{assignee.id}\"},\"serviceRelationshipCharacteristic\":[{\"name\":\"pair\",\"value\":1}]}],\"resourceCharacteristic\":[{\"name\":\"cable\",\"value\":{\"pairs\":60,\"length\":{\"amount\":600,\"unit\":\"m\"},\"technology\":\"PIUT\"}},{\"name\":\"pairs\",\"value\":{\"first\":1,\"last\":60,\"free\":59,\"type\":\"copper\",\"algorithm\":\"lowest\"}}]}) - end - - test "auto assign two pairs to same service" do - {:ok, assignee} = Access.qualify_dsl() - - {:ok, cable} = Access.build_cable(%{}) - - updates = [ - cable: [pairs: 60, length: %IntegerUnit{amount: 600, unit: :m}, technology: :PIUT], - pairs: [first: 1, last: 60, free: 60, type: "copper"] - ] - - {:ok, cable} = Access.define_cable(cable, %{characteristic_value_updates: updates}) - - {:ok, cable} = - Access.assign_pair(cable, %{ - assignment: %Assignment{assignee_id: assignee.id, operation: :auto_assign} - }) - - {:ok, cable} = - Access.assign_pair(cable, %{ - assignment: %Assignment{assignee_id: assignee.id, operation: :auto_assign} - }) - - Characteristics.check_values([pairs: [free: 58]], cable) - - encoding = Jason.encode!(cable) |> Diffo.Util.summarise_dates() - - assert encoding == - ~s({\"id\":\"#{cable.id}",\"href\":\"resourceInventoryManagement/v4/resource/cable/#{cable.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"ce0a567a-6abb-4862-9e33-851fd79fa595\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/ce0a567a-6abb-4862-9e33-851fd79fa595\",\"name\":\"cable\",\"version\":\"v1.0.0\"},\"serviceRelationship\":[{\"type\":\"assignedTo\",\"service\":{\"id\":\"#{assignee.id}\",\"href\":\"serviceInventoryManagement/v4/service/dslAccess/#{assignee.id}\"},\"serviceRelationshipCharacteristic\":[{\"name\":\"pair\",\"value\":1}]},{\"type\":\"assignedTo\",\"service\":{\"id\":\"#{assignee.id}\",\"href\":\"serviceInventoryManagement/v4/service/dslAccess/#{assignee.id}\"},\"serviceRelationshipCharacteristic\":[{\"name\":\"pair\",\"value\":2}]}],\"resourceCharacteristic\":[{\"name\":\"cable\",\"value\":{\"pairs\":60,\"length\":{\"amount\":600,\"unit\":\"m\"},\"technology\":\"PIUT\"}},{\"name\":\"pairs\",\"value\":{\"first\":1,\"last\":60,\"free\":58,\"type\":\"copper\",\"algorithm\":\"lowest\"}}]}) - end - - test "specific assignment rejects duplicate request" do - {:ok, assignee} = Access.qualify_dsl() - - {:ok, cable} = Access.build_cable(%{}) - - updates = [ - cable: [pairs: 60, length: %IntegerUnit{amount: 600, unit: :m}, technology: :PIUT], - pairs: [first: 1, last: 60, free: 60, type: "copper"] - ] - - {:ok, cable} = Access.define_cable(cable, %{characteristic_value_updates: updates}) - - {:ok, cable} = - Access.assign_pair(cable, %{ - assignment: %Assignment{id: 5, assignee_id: assignee.id, operation: :assign} - }) - - {:error, _error} = - Access.assign_pair(cable, %{ - assignment: %Assignment{id: 5, assignee_id: assignee.id, operation: :assign} - }) - - Characteristics.check_values([pairs: [free: 59]], cable) - - encoding = Jason.encode!(cable) |> Diffo.Util.summarise_dates() - - assert encoding == - ~s({\"id\":\"#{cable.id}",\"href\":\"resourceInventoryManagement/v4/resource/cable/#{cable.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"ce0a567a-6abb-4862-9e33-851fd79fa595\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/ce0a567a-6abb-4862-9e33-851fd79fa595\",\"name\":\"cable\",\"version\":\"v1.0.0\"},\"serviceRelationship\":[{\"type\":\"assignedTo\",\"service\":{\"id\":\"#{assignee.id}\",\"href\":\"serviceInventoryManagement/v4/service/dslAccess/#{assignee.id}\"},\"serviceRelationshipCharacteristic\":[{\"name\":\"pair\",\"value\":5}]}],\"resourceCharacteristic\":[{\"name\":\"cable\",\"value\":{\"pairs\":60,\"length\":{\"amount\":600,\"unit\":\"m\"},\"technology\":\"PIUT\"}},{\"name\":\"pairs\",\"value\":{\"first\":1,\"last\":60,\"free\":59,\"type\":\"copper\",\"algorithm\":\"lowest\"}}]}) - end - end -end diff --git a/test/access/characteristic_value_test.exs b/test/access/characteristic_value_test.exs deleted file mode 100644 index 304bd28..0000000 --- a/test/access/characteristic_value_test.exs +++ /dev/null @@ -1,103 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.CharacteristicValueTest do - @moduledoc false - use ExUnit.Case - alias Diffo.Access.AggregateInterface - alias Diffo.Access.Circuit - alias Diffo.Access.Dslam - alias Diffo.Access.Line - alias Diffo.Access.BandwidthProfile - - setup_all do - AshNeo4j.BoltxHelper.start() - end - - setup do - on_exit(fn -> - AshNeo4j.Neo4jHelper.delete_all() - end) - end - - @dslam "QDONC0001" - @model "ISAM7330" - @svlan_id 3108 - @cvlan_id 82 - @circuit_id "#{@dslam} eth #{@svlan_id}:#{@cvlan_id}" - @port 5 - @slot 3 - @profile "adsl2Plus24M1IntM" - - describe "Diffo.Access create Characteristics" do - test "create characteristics" do - dslam_value = - Dslam.new!(%{name: @dslam, model: @model}) - - dslam = - Diffo.Provider.create_characteristic!(%{ - name: :dslam, - value: dslam_value, - type: :instance - }) - - encoding = Jason.encode!(dslam) - - assert encoding == - ~s({\"name\":\"dslam\",\"value\":{\"name\":\"#{@dslam}\",\"family\":\"ISAM",\"model\":\"#{@model}\",\"technology\":\"eth\"}}) - - aggregate_interface_value = - AggregateInterface.new!(%{ - name: "F DONC BOXH 010J", - physical_interface: "1000BASE-LX", - svlan_id: @svlan_id - }) - - aggregate_interface = - Diffo.Provider.create_characteristic!(%{ - name: :aggregate_interface, - value: aggregate_interface_value, - type: :instance - }) - - assert Jason.encode!(aggregate_interface) == - ~s({\"name\":\"aggregate_interface\",\"value\":{\"name\":\"F DONC BOXH 010J\",\"physical_interface\":\"1000BASE-LX\",\"physical_layer\":\"GbE\",\"link_layer\":\"QinQ\",\"svlan_id\":3108,\"vpi\":0}}) - - bandwidth_profile = BandwidthProfile.new!(%{downstream: 24, upstream: 1}) - - assert Jason.encode!(bandwidth_profile) == - ~s({\"downstream\":24,\"upstream\":1,\"units\":\"Mbps\"}) - - {:ok, circuit_value} = - Circuit.new(%{ - circuit_id: @circuit_id, - cvlan_id: @cvlan_id, - bandwidth_profile: bandwidth_profile - }) - - circuit = - Diffo.Provider.create_characteristic!(%{ - name: :circuit, - value: circuit_value, - type: :instance - }) - - assert Jason.encode!(circuit) == - ~s({\"name\":\"circuit\",\"value\":{\"circuit_id\":\"#{@circuit_id}\",\"cvlan_id\":82,\"vci\":0,\"encapsulation\":\"IPoE\",\"bandwidth_profile\":{\"downstream\":24,\"upstream\":1,\"units\":\"Mbps\"}}}) - - {:ok, line_value} = - Line.new(%{port: @port, slot: @slot, standard: :ADSL2plus, profile: @profile}) - - line = - Diffo.Provider.create_characteristic!(%{ - name: :line, - value: line_value, - type: :instance - }) - - assert Jason.encode!(line) == - ~s({\"name\":\"line\",\"value\":{\"port\":5,\"slot\":3,\"standard\":"\ADSL2plus\",\"profile\":\"#{@profile}\"}}) - end - end -end diff --git a/test/access/dsl_access_test.exs b/test/access/dsl_access_test.exs deleted file mode 100644 index fc329df..0000000 --- a/test/access/dsl_access_test.exs +++ /dev/null @@ -1,223 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.DslAccessTest do - @moduledoc false - use ExUnit.Case - alias Diffo.Provider - alias Diffo.Provider.Specification - alias Diffo.Provider.Feature - alias Diffo.Provider.Characteristic - alias Diffo.Provider.Instance.Place - alias Diffo.Provider.Instance.Party - alias Diffo.Access - alias Diffo.Access.DslAccess - alias Diffo.Test.Parties - alias Diffo.Test.Places - - setup_all do - AshNeo4j.BoltxHelper.start() - end - - setup do - on_exit(fn -> - AshNeo4j.Neo4jHelper.delete_all() - end) - end - - describe "service qualification" do - test "create an initial service for service qualification" do - parties = create_initial_parties() - places = [create_initial_place()] - - {:ok, dsl_access} = Access.qualify_dsl(%{parties: parties, places: places}) - - # check the instance is a DslAccess - assert is_struct(dsl_access, DslAccess) - - # check specification resource enrichment and node relationship - refute is_nil(dsl_access.specification_id) - assert is_struct(dsl_access.specification, Specification) - - assert AshNeo4j.Neo4jHelper.nodes_relate_how?( - :Instance, - %{uuid: dsl_access.id}, - :Specification, - %{uuid: dsl_access.specification_id}, - :SPECIFIED_BY, - :outgoing - ) - - # check features resource enrichment and node relationships - assert is_list(dsl_access.features) - assert length(dsl_access.features) == 1 - - Enum.each(dsl_access.features, fn feature -> - assert is_struct(feature, Feature) - - assert AshNeo4j.Neo4jHelper.nodes_relate_how?( - :Instance, - %{uuid: dsl_access.id}, - :Feature, - %{uuid: feature.id}, - :HAS, - :outgoing - ) - - # check feature characteristic resource enrichment and node relationships - assert is_list(feature.characteristics) - assert length(feature.characteristics) == 1 - - Enum.each(feature.characteristics, fn characteristic -> - assert is_struct(characteristic, Characteristic) - - assert AshNeo4j.Neo4jHelper.nodes_relate_how?( - :Feature, - %{uuid: feature.id}, - :Characteristic, - %{uuid: characteristic.id}, - :HAS, - :outgoing - ) - end) - end) - - # check characteristic resource enrichment and node relationships - assert is_list(dsl_access.characteristics) - assert length(dsl_access.characteristics) == 4 - - Enum.each(dsl_access.characteristics, fn characteristic -> - assert is_struct(characteristic, Characteristic) - - assert AshNeo4j.Neo4jHelper.nodes_relate_how?( - :Instance, - %{uuid: dsl_access.id}, - :Characteristic, - %{uuid: characteristic.id}, - :HAS, - :outgoing - ) - end) - - Parties.check_parties(parties, dsl_access) - Places.check_places(places, dsl_access) - - encoding = Jason.encode!(dsl_access) |> Diffo.Util.summarise_dates() - - assert encoding == - ~s({\"id\":\"#{dsl_access.id}",\"href\":\"serviceInventoryManagement/v4/service/dslAccess/#{dsl_access.id}\",\"category\":\"Network Service\",\"serviceSpecification\":{\"id\":\"da9b207a-26c3-451d-8abd-0640c6349979\",\"href\":\"serviceCatalogManagement/v4/serviceSpecification/da9b207a-26c3-451d-8abd-0640c6349979\",\"name\":\"dslAccess\",\"version\":\"v1.0.0\"},\"serviceDate\":\"now\",\"state\":\"initial\",\"feature\":[{\"name\":\"dynamic_line_management\",\"isEnabled\":true,\"featureCharacteristic\":[{\"name\":\"constraints\",\"value\":{}}]}],\"serviceCharacteristic\":[{\"name\":\"aggregate_interface\",\"value\":{\"physical_layer\":\"GbE\",\"link_layer\":\"QinQ\",\"svlan_id\":0,\"vpi\":0}},{\"name\":\"circuit\",\"value\":{\"cvlan_id\":0,\"vci\":0,\"encapsulation\":\"IPoE\"}},{\"name\":\"dslam\",\"value\":{\"family\":\"ISAM\",\"technology\":\"eth\"}},{\"name\":\"line\",\"value\":{\"standard\":\"ADSL2plus\"}}],\"place\":[{\"id\":\"1657363\",\"href\":\"place/telstra/1657363\",\"name\":\"addressId\",\"role\":\"CustomerSite\",\"@referredType\":\"GeographicAddress\",\"@type\":\"PlaceRef\"}],\"relatedParty\":[{\"id\":\"IND000000897354\",\"name\":\"individualId\",\"role\":\"Customer\",\"@referredType\":\"Individual\",\"@type\":\"PartyRef\"},{\"id\":\"ORG000000123456\",\"name\":\"organizationId\",\"role\":\"Reseller\",\"@referredType\":\"Organization\",\"@type\":\"PartyRef\"}]}) - end - - test "advance service to feasibilityChecked" do - initial_parties = create_initial_parties() - initial_place = create_initial_place() - - {:ok, dsl_access} = Access.qualify_dsl(%{parties: initial_parties, places: [initial_place]}) - - esa_place = create_esa_place() - - {:ok, dsl_access} = - Access.qualify_dsl_result(dsl_access, %{ - service_operating_status: :feasible, - places: [esa_place] - }) - - # check the instance is a DslAccess - assert is_struct(dsl_access, DslAccess) - - assert dsl_access.service_state == :feasibilityChecked - assert dsl_access.service_operating_status == :feasible - - Places.check_places([initial_place | [esa_place]], dsl_access) - - encoding = Jason.encode!(dsl_access) |> Diffo.Util.summarise_dates() - - assert encoding == - ~s({\"id\":\"#{dsl_access.id}",\"href\":\"serviceInventoryManagement/v4/service/dslAccess/#{dsl_access.id}\",\"category\":\"Network Service\",\"serviceSpecification\":{\"id\":\"da9b207a-26c3-451d-8abd-0640c6349979\",\"href\":\"serviceCatalogManagement/v4/serviceSpecification/da9b207a-26c3-451d-8abd-0640c6349979\",\"name\":\"dslAccess\",\"version\":\"v1.0.0\"},\"serviceDate\":\"now\",\"state\":\"feasibilityChecked\",\"operatingStatus\":\"feasible\",\"feature\":[{\"name\":\"dynamic_line_management\",\"isEnabled\":true,\"featureCharacteristic\":[{\"name\":\"constraints\",\"value\":{}}]}],\"serviceCharacteristic\":[{\"name\":\"aggregate_interface\",\"value\":{\"physical_layer\":\"GbE\",\"link_layer\":\"QinQ\",\"svlan_id\":0,\"vpi\":0}},{\"name\":\"circuit\",\"value\":{\"cvlan_id\":0,\"vci\":0,\"encapsulation\":\"IPoE\"}},{\"name\":\"dslam\",\"value\":{\"family\":\"ISAM\",\"technology\":\"eth\"}},{\"name\":\"line\",\"value\":{\"standard\":\"ADSL2plus\"}}],\"place\":[{\"id\":\"1657363\",\"href\":\"place/telstra/1657363\",\"name\":\"addressId\",\"role\":\"CustomerSite\",\"@referredType\":\"GeographicAddress\",\"@type\":\"PlaceRef\"},{\"id\":\"DONC-0001\",\"href\":\"place/telstra/DONC-0001\",\"name\":\"esaId\",\"role\":\"ServingArea\",\"@referredType\":\"GeographicLocation\",\"@type\":\"PlaceRef\"}],\"relatedParty\":[{\"id\":\"IND000000897354\",\"name\":\"individualId\",\"role\":\"Customer\",\"@referredType\":\"Individual\",\"@type\":\"PartyRef\"},{\"id\":\"ORG000000123456\",\"name\":\"organizationId\",\"role\":\"Reseller\",\"@referredType\":\"Organization\",\"@type\":\"PartyRef\"}]}) - end - end - - describe "service activation" do - test "design the service" do - initial_parties = create_initial_parties() - initial_place = create_initial_place() - {:ok, dsl_access} = Access.qualify_dsl(%{parties: initial_parties, places: [initial_place]}) - esa_place = create_esa_place() - - {:ok, dsl_access} = - Access.qualify_dsl_result(dsl_access, %{ - service_operating_status: :feasible, - places: [esa_place] - }) - - # now we design the circuit, allocating the dslam, slot, port - # and we allocate the backhaul interface, svlan and cvlan, so can derive the cicuit id - - updates = [ - dslam: [name: QDONC0001, model: ISAM7330], - aggregate_interface: [name: "eth0", svlan_id: 3108], - circuit: [cvlan_id: 82], - line: [slot: 10, port: 5] - ] - - {:ok, dsl_access} = - Access.design_dsl_result(dsl_access, %{characteristic_value_updates: updates}) - - # check the instance is a DslAccess - assert is_struct(dsl_access, DslAccess) - - assert dsl_access.service_state == :reserved - assert dsl_access.service_operating_status == :feasible - - Places.check_places([initial_place | [esa_place]], dsl_access) - - encoding = Jason.encode!(dsl_access) |> Diffo.Util.summarise_dates() - - assert encoding == - ~s({\"id\":\"#{dsl_access.id}",\"href\":\"serviceInventoryManagement/v4/service/dslAccess/#{dsl_access.id}\",\"category\":\"Network Service\",\"serviceSpecification\":{\"id\":\"da9b207a-26c3-451d-8abd-0640c6349979\",\"href\":\"serviceCatalogManagement/v4/serviceSpecification/da9b207a-26c3-451d-8abd-0640c6349979\",\"name\":\"dslAccess\",\"version\":\"v1.0.0\"},\"serviceDate\":\"now\",\"state\":\"reserved\",\"operatingStatus\":\"feasible\",\"feature\":[{\"name\":\"dynamic_line_management\",\"isEnabled\":true,\"featureCharacteristic\":[{\"name\":\"constraints\",\"value\":{}}]}],\"serviceCharacteristic\":[{\"name\":\"aggregate_interface\",\"value\":{\"name\":\"eth0\",\"physical_layer\":\"GbE\",\"link_layer\":\"QinQ\",\"svlan_id\":3108,\"vpi\":0}},{\"name\":\"circuit\",\"value\":{\"cvlan_id\":82,\"vci\":0,\"encapsulation\":\"IPoE\"}},{\"name\":\"dslam\",\"value\":{\"name\":\"QDONC0001\",\"family\":\"ISAM\",\"model\":\"ISAM7330\",\"technology\":\"eth\"}},{\"name\":\"line\",\"value\":{\"port\":5,\"slot\":10,\"standard\":\"ADSL2plus\"}}],\"place\":[{\"id\":\"1657363\",\"href\":\"place/telstra/1657363\",\"name\":\"addressId\",\"role\":\"CustomerSite\",\"@referredType\":\"GeographicAddress\",\"@type\":\"PlaceRef\"},{\"id\":\"DONC-0001\",\"href\":\"place/telstra/DONC-0001\",\"name\":\"esaId\",\"role\":\"ServingArea\",\"@referredType\":\"GeographicLocation\",\"@type\":\"PlaceRef\"}],\"relatedParty\":[{\"id\":\"IND000000897354\",\"name\":\"individualId\",\"role\":\"Customer\",\"@referredType\":\"Individual\",\"@type\":\"PartyRef\"},{\"id\":\"ORG000000123456\",\"name\":\"organizationId\",\"role\":\"Reseller\",\"@referredType\":\"Organization\",\"@type\":\"PartyRef\"}]}) - end - end - - defp create_initial_place do - z_end = - Provider.create_place!(%{ - id: "1657363", - name: :addressId, - href: "place/telstra/1657363", - referredType: :GeographicAddress - }) - - %Place{id: z_end.id, role: :CustomerSite} - end - - defp create_esa_place do - esa = - Provider.create_place!(%{ - id: "DONC-0001", - name: :esaId, - href: "place/telstra/DONC-0001", - referredType: :GeographicLocation - }) - - %Place{id: esa.id, role: :ServingArea} - end - - defp create_initial_parties do - individual = - Provider.create_party!(%{ - id: "IND000000897354", - name: :individualId, - referredType: :Individual - }) - - org = - Provider.create_party!(%{ - id: "ORG000000123456", - name: :organizationId, - referredType: :Organization - }) - - [%Party{id: individual.id, role: :Customer}, %Party{id: org.id, role: :Reseller}] - end -end diff --git a/test/access/path_test.exs b/test/access/path_test.exs deleted file mode 100644 index c2afc34..0000000 --- a/test/access/path_test.exs +++ /dev/null @@ -1,239 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.PathTest do - @moduledoc false - use ExUnit.Case - alias Diffo.Provider - alias Diffo.Provider.Specification - alias Diffo.Provider.Characteristic - alias Diffo.Provider.Instance.Place - alias Diffo.Provider.Instance.Party - alias Diffo.Provider.Instance.Relationship - alias Diffo.Provider.Assignment - alias Diffo.Access - alias Diffo.Access.Path - - setup_all do - AshNeo4j.BoltxHelper.start() - end - - setup do - on_exit(fn -> - AshNeo4j.Neo4jHelper.delete_all() - end) - end - - describe "build path" do - test "create a path" do - places = [create_customer_place(), create_exchange_place(), create_esa_place()] - parties = [create_provider_party()] - - {:ok, path} = - Access.build_path(%{name: "82 Rathmullen - DONC", places: places, parties: parties}) - - # check the instance is a Path - assert is_struct(path, Path) - - # check specification resource enrichment and node relationship - refute is_nil(path.specification_id) - assert is_struct(path.specification, Specification) - - assert AshNeo4j.Neo4jHelper.nodes_relate_how?( - :Instance, - %{uuid: path.id}, - :Specification, - %{uuid: path.specification_id}, - :SPECIFIED_BY, - :outgoing - ) - - # check characteristic resource enrichment and node relationships - assert is_list(path.characteristics) - assert length(path.characteristics) == 1 - - Enum.each(path.characteristics, fn characteristic -> - assert is_struct(characteristic, Characteristic) - - assert AshNeo4j.Neo4jHelper.nodes_relate_how?( - :Instance, - %{uuid: path.id}, - :Characteristic, - %{uuid: characteristic.id}, - :HAS, - :outgoing - ) - end) - - Diffo.Test.Places.check_places(places, path) - Diffo.Test.Parties.check_parties(parties, path) - - encoding = Jason.encode!(path) |> Diffo.Util.summarise_dates() - - assert encoding == - ~s({\"id\":\"#{path.id}",\"href\":\"resourceInventoryManagement/v4/resource/path/#{path.id}",\"category\":\"Network Resource\",\"name\":\"82 Rathmullen - DONC\",\"resourceSpecification\":{\"id\":\"1d507914-8f76-48cb-aa0e-3a8f92951ab0\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/1d507914-8f76-48cb-aa0e-3a8f92951ab0\",\"name\":\"path\",\"version\":\"v1.0.0\"},\"resourceCharacteristic\":[{\"name\":\"path\",\"value\":{\"sections\":0}}],\"place\":[{\"id\":\"1657363\",\"href\":\"place/telstra/1657363\",\"name\":\"addressId\",\"role\":\"CustomerSite\",\"@referredType\":\"GeographicAddress\",\"@type\":\"PlaceRef\"},{\"id\":\"DONC\",\"href\":\"place/telstra/DONC\",\"name\":\"exchangeId\",\"role\":\"NetworkSite\",\"@referredType\":\"GeographicSite\",\"@type\":\"PlaceRef\"},{\"id\":\"DONC-0001\",\"href\":\"place/telstra/DONC-0001\",\"name\":\"esaId\",\"role\":\"ServingArea\",\"@referredType\":\"GeographicLocation\",\"@type\":\"PlaceRef\"}],\"relatedParty\":[{\"id\":\"Access\",\"name\":\"organizationId\",\"role\":\"Provider\",\"@referredType\":\"Organization\",\"@type\":\"PartyRef\"}]}) - end - end - - test "define path" do - places = [create_customer_place(), create_exchange_place(), create_esa_place()] - parties = [create_provider_party()] - - {:ok, path} = - Access.build_path(%{name: "82 Rathmullen - DONC", places: places, parties: parties}) - - updates = [ - path: [name: "82 Rathmullen - DONC", technology: :copper] - ] - - {:ok, path} = Access.define_path(path, %{characteristic_value_updates: updates}) - - encoding = Jason.encode!(path) |> Diffo.Util.summarise_dates() - - assert encoding == - ~s({\"id\":\"#{path.id}",\"href\":\"resourceInventoryManagement/v4/resource/path/#{path.id}",\"category\":\"Network Resource\",\"name\":\"82 Rathmullen - DONC\",\"resourceSpecification\":{\"id\":\"1d507914-8f76-48cb-aa0e-3a8f92951ab0\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/1d507914-8f76-48cb-aa0e-3a8f92951ab0\",\"name\":\"path\",\"version\":\"v1.0.0\"},\"resourceCharacteristic\":[{\"name\":\"path\",\"value\":{\"name\":\"82 Rathmullen - DONC\",\"sections\":0,\"technology\":\"copper\"}}],\"place\":[{\"id\":\"1657363\",\"href\":\"place/telstra/1657363\",\"name\":\"addressId\",\"role\":\"CustomerSite\",\"@referredType\":\"GeographicAddress\",\"@type\":\"PlaceRef\"},{\"id\":\"DONC\",\"href\":\"place/telstra/DONC\",\"name\":\"exchangeId\",\"role\":\"NetworkSite\",\"@referredType\":\"GeographicSite\",\"@type\":\"PlaceRef\"},{\"id\":\"DONC-0001\",\"href\":\"place/telstra/DONC-0001\",\"name\":\"esaId\",\"role\":\"ServingArea\",\"@referredType\":\"GeographicLocation\",\"@type\":\"PlaceRef\"}],\"relatedParty\":[{\"id\":\"Access\",\"name\":\"organizationId\",\"role\":\"Provider\",\"@referredType\":\"Organization\",\"@type\":\"PartyRef\"}]}) - end - - test "relate cables and dslam" do - places = [create_customer_place(), create_exchange_place(), create_esa_place()] - parties = [create_provider_party()] - - {:ok, path} = - Access.build_path(%{name: "82 Rathmullen - DONC", places: places, parties: parties}) - - updates = [ - path: [name: "82 Rathmullen - DONC", technology: :copper] - ] - - {:ok, path} = Access.define_path(path, %{characteristic_value_updates: updates}) - - cables = create_cables(places) - - # now assign a pair from each cable - _cables = - Enum.into(cables, [], fn cable -> - Access.assign_pair!(cable, %{ - assignment: %Assignment{assignee_id: path.id, operation: :auto_assign} - }) - end) - - # now assign a port from a line card - [_dslam, line_card] = create_dslam_with_line_card("QDONC-0001", tl(places), parties) - - Access.assign_port!(line_card, %{ - assignment: %Assignment{assignee_id: path.id, operation: :auto_assign} - }) - - # refresh the path loading the reverse relationships explicitly, which should include - # relationships with cables assigning pairs - # relationship with line card assigning port - - {:ok, path} = Access.get_path_by_id(path.id, load: [:reverse_relationships]) - assert length(path.reverse_relationships) == 6 - - encoding = Jason.encode!(path) |> Diffo.Util.summarise_dates() - - # the reverse relationships are not encoded to json - assert encoding == - ~s({\"id\":\"#{path.id}",\"href\":\"resourceInventoryManagement/v4/resource/path/#{path.id}",\"category\":\"Network Resource\",\"name\":\"82 Rathmullen - DONC\",\"resourceSpecification\":{\"id\":\"1d507914-8f76-48cb-aa0e-3a8f92951ab0\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/1d507914-8f76-48cb-aa0e-3a8f92951ab0\",\"name\":\"path\",\"version\":\"v1.0.0\"},\"resourceCharacteristic\":[{\"name\":\"path\",\"value\":{\"name\":\"82 Rathmullen - DONC\",\"sections\":0,\"technology\":\"copper\"}}],\"place\":[{\"id\":\"1657363\",\"href\":\"place/telstra/1657363\",\"name\":\"addressId\",\"role\":\"CustomerSite\",\"@referredType\":\"GeographicAddress\",\"@type\":\"PlaceRef\"},{\"id\":\"DONC\",\"href\":\"place/telstra/DONC\",\"name\":\"exchangeId\",\"role\":\"NetworkSite\",\"@referredType\":\"GeographicSite\",\"@type\":\"PlaceRef\"},{\"id\":\"DONC-0001\",\"href\":\"place/telstra/DONC-0001\",\"name\":\"esaId\",\"role\":\"ServingArea\",\"@referredType\":\"GeographicLocation\",\"@type\":\"PlaceRef\"}],\"relatedParty\":[{\"id\":\"Access\",\"name\":\"organizationId\",\"role\":\"Provider\",\"@referredType\":\"Organization\",\"@type\":\"PartyRef\"}]}) - end - - defp create_customer_place do - z_end = - Provider.create_place!(%{ - id: "1657363", - name: :addressId, - href: "place/telstra/1657363", - referredType: :GeographicAddress - }) - - %Place{id: z_end.id, role: :CustomerSite} - end - - defp create_esa_place do - esa = - Provider.create_place!(%{ - id: "DONC-0001", - name: :esaId, - href: "place/telstra/DONC-0001", - referredType: :GeographicLocation - }) - - %Place{id: esa.id, role: :ServingArea} - end - - defp create_exchange_place do - exchange = - Provider.create_place!(%{ - id: "DONC", - name: :exchangeId, - href: "place/telstra/DONC", - referredType: :GeographicSite - }) - - %Place{id: exchange.id, role: :NetworkSite} - end - - defp create_cables(places) do - [z_end, exchange, _esa] = places - tie = create_cable("QDONC-0001 line card 1 tie cable", [], []) - - main = - create_cable( - "DONC-0001-001 Lawford St main cable", - [%Relationship{id: tie.id, direction: :forward, type: :connectedTo}], - [z_end] - ) - - secondary = - create_cable( - "DONC-0001-005 North Rathmullen Quad cable", - [%Relationship{id: main.id, direction: :forward, type: :connectedTo}], - [] - ) - - tertiary = - create_cable( - "DONC-0001-013 Rathmullen Quad East cable", - [%Relationship{id: secondary.id, direction: :forward, type: :connectedTo}], - [] - ) - - lead_in = - create_cable( - "82 Rathmullen lead in", - [%Relationship{id: tertiary.id, direction: :forward, type: :connectedTo}], - [exchange] - ) - - [tie, main, secondary, tertiary, lead_in] - end - - defp create_cable(name, relationships, places) - when is_bitstring(name) and is_list(relationships) and is_list(places) do - Access.build_cable!(%{name: "#{name}", places: places, relationships: relationships}) - end - - defp create_dslam_with_line_card(name, places, parties) when is_bitstring(name) do - shelf = Access.build_shelf!(%{name: "#{name}", places: places, parties: parties}) - card = Access.build_card!(%{name: "#{name}"}) - - Access.assign_slot!(shelf, %{ - assignment: %Assignment{assignee_id: card.id, operation: :auto_assign} - }) - - [shelf, card] - end - - defp create_provider_party do - provider = - Provider.create_party!(%{ - id: "Access", - name: :organizationId, - referredType: :Organization - }) - - %Party{id: provider.id, role: :Provider} - end -end diff --git a/test/access/shelf_test.exs b/test/access/shelf_test.exs deleted file mode 100644 index d17dbda..0000000 --- a/test/access/shelf_test.exs +++ /dev/null @@ -1,196 +0,0 @@ -# SPDX-FileCopyrightText: 2025 diffo contributors -# -# SPDX-License-Identifier: MIT - -defmodule Diffo.Access.ShelfTest do - @moduledoc false - use ExUnit.Case - alias Diffo.Provider - alias Diffo.Provider.Specification - alias Diffo.Provider.Characteristic - alias Diffo.Provider.Instance.Place - alias Diffo.Provider.Instance.Party - alias Diffo.Provider.Instance.Relationship - alias Diffo.Provider.Assignment - alias Diffo.Access - alias Diffo.Access.Shelf - alias Diffo.Test.Characteristics - - setup_all do - AshNeo4j.BoltxHelper.start() - end - - setup do - on_exit(fn -> - AshNeo4j.Neo4jHelper.delete_all() - end) - end - - describe "build shelf" do - test "create a shelf" do - places = [create_esa_place()] - parties = [create_provider_party()] - - {:ok, shelf} = Access.build_shelf(%{name: "QDONC-0001", places: places, parties: parties}) - - # check the instance is a Shelf - assert is_struct(shelf, Shelf) - - # check specification resource enrichment and node relationship - refute is_nil(shelf.specification_id) - assert is_struct(shelf.specification, Specification) - - assert AshNeo4j.Neo4jHelper.nodes_relate_how?( - :Instance, - %{uuid: shelf.id}, - :Specification, - %{uuid: shelf.specification_id}, - :SPECIFIED_BY, - :outgoing - ) - - # check characteristic resource enrichment and node relationships - assert is_list(shelf.characteristics) - assert length(shelf.characteristics) == 2 - - Enum.each(shelf.characteristics, fn characteristic -> - assert is_struct(characteristic, Characteristic) - - assert AshNeo4j.Neo4jHelper.nodes_relate_how?( - :Instance, - %{uuid: shelf.id}, - :Characteristic, - %{uuid: characteristic.id}, - :HAS, - :outgoing - ) - end) - - Diffo.Test.Places.check_places(places, shelf) - Diffo.Test.Parties.check_parties(parties, shelf) - - encoding = Jason.encode!(shelf) |> Diffo.Util.summarise_dates() - - assert encoding == - ~s({\"id\":\"#{shelf.id}",\"href\":\"resourceInventoryManagement/v4/resource/shelf/#{shelf.id}",\"category\":\"Network Resource\",\"name\":\"QDONC-0001\",\"resourceSpecification\":{\"id\":\"ef016d85-9dbd-429c-84da-1df56cc7dda5\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/ef016d85-9dbd-429c-84da-1df56cc7dda5\",\"name\":\"shelf\",\"version\":\"v1.0.0\"},\"resourceCharacteristic\":[{\"name\":\"shelf\",\"value\":{}},{\"name\":\"slots\",\"value\":{\"first\":1,\"last\":1,\"free\":1,\"algorithm\":\"lowest\"}}],\"place\":[{\"id\":\"DONC-0001\",\"href\":\"place/telstra/DONC-0001\",\"name\":\"esaId\",\"role\":\"ServingArea\",\"@referredType\":\"GeographicLocation\",\"@type\":\"PlaceRef\"}],\"relatedParty\":[{\"id\":\"Access\",\"name\":\"organizationId\",\"role\":\"Provider\",\"@referredType\":\"Organization\",\"@type\":\"PartyRef\"}]}) - end - end - - test "define shelf" do - places = [create_esa_place()] - parties = [create_provider_party()] - {:ok, shelf} = Access.build_shelf(%{name: "QDONC-0001", places: places, parties: parties}) - - updates = [ - shelf: [name: "QDONC-1001", family: :ISAM, model: "ISAM7330", technology: :DSLAM], - slots: [first: 1, last: 10, free: 10, type: "LineCard"] - ] - - {:ok, shelf} = Access.define_shelf(shelf, %{characteristic_value_updates: updates}) - - encoding = Jason.encode!(shelf) |> Diffo.Util.summarise_dates() - - assert encoding == - ~s({\"id\":\"#{shelf.id}",\"href\":\"resourceInventoryManagement/v4/resource/shelf/#{shelf.id}",\"category\":\"Network Resource\",\"name\":\"QDONC-0001\",\"resourceSpecification\":{\"id\":\"ef016d85-9dbd-429c-84da-1df56cc7dda5\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/ef016d85-9dbd-429c-84da-1df56cc7dda5\",\"name\":\"shelf\",\"version\":\"v1.0.0\"},\"resourceCharacteristic\":[{\"name\":\"shelf\",\"value\":{\"name\":\"QDONC-1001\",\"family\":\"ISAM\",\"model\":\"ISAM7330\",\"technology\":\"DSLAM\"}},{\"name\":\"slots\",\"value\":{\"first\":1,\"last\":10,\"free\":10,\"type\":\"LineCard\",\"algorithm\":\"lowest\"}}],\"place\":[{\"id\":\"DONC-0001\",\"href\":\"place/telstra/DONC-0001\",\"name\":\"esaId\",\"role\":\"ServingArea\",\"@referredType\":\"GeographicLocation\",\"@type\":\"PlaceRef\"}],\"relatedParty\":[{\"id\":\"Access\",\"name\":\"organizationId\",\"role\":\"Provider\",\"@referredType\":\"Organization\",\"@type\":\"PartyRef\"}]}) - end - - test "relate common cards" do - places = [create_esa_place()] - parties = [create_provider_party()] - - {:ok, shelf} = Access.build_shelf(%{places: places, parties: parties}) - - updates = [ - shelf: [name: "QDONC-1001", family: :ISAM, model: "ISAM7330", technology: :DSLAM], - slots: [first: 1, last: 10, free: 10, type: "LineCard"] - ] - - {:ok, shelf} = Access.define_shelf(shelf, %{characteristic_value_updates: updates}) - - cards = create_common_cards() - - {:ok, shelf} = Access.relate_shelf(shelf, %{relationships: cards}) - - encoding = Jason.encode!(shelf) |> Diffo.Util.summarise_dates() - - [card0, card1, card2, card3] = cards - - # resource relationships are sorted in the create order of the relationships - assert encoding == - ~s({\"id\":\"#{shelf.id}",\"href\":\"resourceInventoryManagement/v4/resource/shelf/#{shelf.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"ef016d85-9dbd-429c-84da-1df56cc7dda5\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/ef016d85-9dbd-429c-84da-1df56cc7dda5\",\"name\":\"shelf\",\"version\":\"v1.0.0\"},\"resourceRelationship\":[{\"type\":\"contains\",\"resource\":{\"id\":\"#{card0.id}\",\"href\":\"resourceInventoryManagement/v4/resource/card/#{card0.id}\"}},{\"type\":\"contains\",\"resource\":{\"id\":\"#{card1.id}\",\"href\":\"resourceInventoryManagement/v4/resource/card/#{card1.id}\"}},{\"type\":\"contains\",\"resource\":{\"id\":\"#{card2.id}\",\"href\":\"resourceInventoryManagement/v4/resource/card/#{card2.id}\"}},{\"type\":\"contains\",\"resource\":{\"id\":\"#{card3.id}\",\"href\":\"resourceInventoryManagement/v4/resource/card/#{card3.id}\"}}],\"resourceCharacteristic\":[{\"name\":\"shelf\",\"value\":{\"name\":\"QDONC-1001\",\"family\":\"ISAM\",\"model\":\"ISAM7330\",\"technology\":\"DSLAM\"}},{\"name\":\"slots\",\"value\":{\"first\":1,\"last\":10,\"free\":10,\"type\":\"LineCard\",\"algorithm\":\"lowest\"}}],\"place\":[{\"id\":\"DONC-0001\",\"href\":\"place/telstra/DONC-0001\",\"name\":\"esaId\",\"role\":\"ServingArea\",\"@referredType\":\"GeographicLocation\",\"@type\":\"PlaceRef\"}],\"relatedParty\":[{\"id\":\"Access\",\"name\":\"organizationId\",\"role\":\"Provider\",\"@referredType\":\"Organization\",\"@type\":\"PartyRef\"}]}) - end - - test "auto assign line cards" do - places = [create_esa_place()] - parties = [create_provider_party()] - - {:ok, shelf} = Access.build_shelf(%{name: "QDONC-0001", places: places, parties: parties}) - - updates = [ - shelf: [name: "QDONC-1001", family: :ISAM, model: "ISAM7330", technology: :DSLAM], - slots: [first: 1, last: 10, free: 10, type: "LineCard"] - ] - - {:ok, shelf} = Access.define_shelf(shelf, %{characteristic_value_updates: updates}) - - line_card1 = create_line_card("lc1") - {:ok, shelf} = Access.assign_slot(shelf, %{assignment: line_card1}) - line_card2 = create_line_card("lc2") - {:ok, shelf} = Access.assign_slot(shelf, %{assignment: line_card2}) - - Characteristics.check_values([slots: [free: 8]], shelf) - - encoding = Jason.encode!(shelf) |> Diffo.Util.summarise_dates() - - lc1 = line_card1.assignee_id - lc2 = line_card2.assignee_id - - assert encoding == - ~s({\"id\":\"#{shelf.id}",\"href\":\"resourceInventoryManagement/v4/resource/shelf/#{shelf.id}",\"category\":\"Network Resource\",\"name\":\"QDONC-0001\",\"resourceSpecification\":{\"id\":\"ef016d85-9dbd-429c-84da-1df56cc7dda5\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/ef016d85-9dbd-429c-84da-1df56cc7dda5\",\"name\":\"shelf\",\"version\":\"v1.0.0\"},\"resourceRelationship\":[{\"type\":\"assignedTo\",\"resource\":{\"id\":\"#{lc1}\",\"href\":\"resourceInventoryManagement/v4/resource/card/#{lc1}\"},\"resourceRelationshipCharacteristic\":[{\"name\":\"slot\",\"value\":1}]},{\"type\":\"assignedTo\",\"resource\":{\"id\":\"#{lc2}\",\"href\":\"resourceInventoryManagement/v4/resource/card/#{lc2}\"},\"resourceRelationshipCharacteristic\":[{\"name\":\"slot\",\"value\":2}]}],\"resourceCharacteristic\":[{\"name\":\"shelf\",\"value\":{\"name\":\"QDONC-1001\",\"family\":\"ISAM\",\"model\":\"ISAM7330\",\"technology\":\"DSLAM\"}},{\"name\":\"slots\",\"value\":{\"first\":1,\"last\":10,\"free\":8,\"type\":\"LineCard\",\"algorithm\":\"lowest\"}}],\"place\":[{\"id\":\"DONC-0001\",\"href\":\"place/telstra/DONC-0001\",\"name\":\"esaId\",\"role\":\"ServingArea\",\"@referredType\":\"GeographicLocation\",\"@type\":\"PlaceRef\"}],\"relatedParty\":[{\"id\":\"Access\",\"name\":\"organizationId\",\"role\":\"Provider\",\"@referredType\":\"Organization\",\"@type\":\"PartyRef\"}]}) - end - - defp create_common_cards() do - psu1 = create_common_card("psu1") - psu2 = create_common_card("psu2") - transport1 = create_common_card("transport1") - transport2 = create_common_card("transport2") - [psu1, psu2, transport1, transport2] - end - - defp create_line_card(name) do - card = - Access.build_card!(%{name: "#{name}"}) - - %Assignment{assignee_id: card.id, operation: :auto_assign} - end - - defp create_common_card(name) do - card = - Access.build_card!(%{name: "#{name}"}) - - %Relationship{id: card.id, direction: :forward, type: :contains} - end - - defp create_esa_place do - esa = - Provider.create_place!(%{ - id: "DONC-0001", - name: :esaId, - href: "place/telstra/DONC-0001", - referredType: :GeographicLocation - }) - - %Place{id: esa.id, role: :ServingArea} - end - - defp create_provider_party do - provider = - Provider.create_party!(%{ - id: "Access", - name: :organizationId, - referredType: :Organization - }) - - %Party{id: provider.id, role: :Provider} - end -end diff --git a/test/access/card_test.exs b/test/assigner/assigner_test.exs similarity index 67% rename from test/access/card_test.exs rename to test/assigner/assigner_test.exs index f1c555c..34c56e7 100644 --- a/test/access/card_test.exs +++ b/test/assigner/assigner_test.exs @@ -2,15 +2,16 @@ # # SPDX-License-Identifier: MIT -defmodule Diffo.Access.CardTest do +defmodule Diffo.Test.AssignerTest do @moduledoc false use ExUnit.Case alias Diffo.Provider.Specification alias Diffo.Provider.Characteristic - alias Diffo.Access - alias Diffo.Access.Card alias Diffo.Provider.Assignment + alias Diffo.Test.Characteristics + alias Diffo.Test.Domain + alias Diffo.Test.Card setup_all do AshNeo4j.BoltxHelper.start() @@ -24,7 +25,7 @@ defmodule Diffo.Access.CardTest do describe "build card" do test "create a card" do - {:ok, card} = Access.build_card(%{}) + {:ok, card} = Domain.build_card(%{}) # check the instance is a Card assert is_struct(card, Card) @@ -66,14 +67,14 @@ defmodule Diffo.Access.CardTest do end test "define card" do - {:ok, card} = Access.build_card(%{}) + {:ok, card} = Domain.build_card(%{}) updates = [ card: [family: :ISAM, model: "EBLT48", technology: :adsl2Plus], ports: [first: 1, last: 48, free: 48, type: "ADSL2+"] ] - {:ok, card} = Access.define_card(card, %{characteristic_value_updates: updates}) + {:ok, card} = Domain.define_card(card, %{characteristic_value_updates: updates}) encoding = Jason.encode!(card) |> Diffo.Util.summarise_dates() @@ -81,20 +82,20 @@ defmodule Diffo.Access.CardTest do ~s({\"id\":\"#{card.id}",\"href\":\"resourceInventoryManagement/v4/resource/card/#{card.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"name\":\"card\",\"version\":\"v1.0.0\"},\"resourceCharacteristic\":[{\"name\":\"card\",\"value\":{\"family\":\"ISAM\",\"model\":\"EBLT48\",\"technology\":\"adsl2Plus\"}},{\"name\":\"ports\",\"value\":{\"first\":1,\"last\":48,\"free\":48,\"type\":\"ADSL2+\",\"algorithm\":\"lowest\"}}]}) end - test "auto assign port to service" do - {:ok, assignee} = Access.qualify_dsl() + test "auto assign port to resource" do + {:ok, assignee} = Domain.build_shelf() - {:ok, card} = Access.build_card(%{}) + {:ok, card} = Domain.build_card(%{}) updates = [ card: [family: :ISAM, model: "EBLT48", technology: :adsl2Plus], ports: [first: 1, last: 48, free: 48, type: "ADSL2+"] ] - {:ok, card} = Access.define_card(card, %{characteristic_value_updates: updates}) + {:ok, card} = Domain.define_card(card, %{characteristic_value_updates: updates}) {:ok, card} = - Access.assign_port(card, %{ + Domain.assign_port(card, %{ assignment: %Assignment{assignee_id: assignee.id, operation: :auto_assign} }) @@ -103,28 +104,28 @@ defmodule Diffo.Access.CardTest do encoding = Jason.encode!(card) |> Diffo.Util.summarise_dates() assert encoding == - ~s({\"id\":\"#{card.id}",\"href\":\"resourceInventoryManagement/v4/resource/card/#{card.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"name\":\"card\",\"version\":\"v1.0.0\"},\"serviceRelationship\":[{\"type\":\"assignedTo\",\"service\":{\"id\":\"#{assignee.id}\",\"href\":\"serviceInventoryManagement/v4/service/dslAccess/#{assignee.id}\"},\"serviceRelationshipCharacteristic\":[{\"name\":\"port\",\"value\":1}]}],\"resourceCharacteristic\":[{\"name\":\"card\",\"value\":{\"family\":\"ISAM\",\"model\":\"EBLT48\",\"technology\":\"adsl2Plus\"}},{\"name\":\"ports\",\"value\":{\"first\":1,\"last\":48,\"free\":47,\"type\":\"ADSL2+\",\"algorithm\":\"lowest\"}}]}) + ~s({\"id\":\"#{card.id}",\"href\":\"resourceInventoryManagement/v4/resource/card/#{card.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"name\":\"card\",\"version\":\"v1.0.0\"},\"resourceRelationship\":[{\"type\":\"assignedTo\",\"resource\":{\"id\":\"#{assignee.id}\",\"href\":\"resourceInventoryManagement/v4/resource/shelf/#{assignee.id}\"},\"resourceRelationshipCharacteristic\":[{\"name\":\"port\",\"value\":1}]}],\"resourceCharacteristic\":[{\"name\":\"card\",\"value\":{\"family\":\"ISAM\",\"model\":\"EBLT48\",\"technology\":\"adsl2Plus\"}},{\"name\":\"ports\",\"value\":{\"first\":1,\"last\":48,\"free\":47,\"type\":\"ADSL2+\",\"algorithm\":\"lowest\"}}]}) end - test "auto assign two ports to same service" do - {:ok, assignee} = Access.qualify_dsl() + test "auto assign two ports to same resource" do + {:ok, assignee} = Domain.build_shelf() - {:ok, card} = Access.build_card(%{}) + {:ok, card} = Domain.build_card(%{}) updates = [ card: [family: :ISAM, model: "EBLT48", technology: :adsl2Plus], ports: [first: 1, last: 48, free: 48, type: "ADSL2+"] ] - {:ok, card} = Access.define_card(card, %{characteristic_value_updates: updates}) + {:ok, card} = Domain.define_card(card, %{characteristic_value_updates: updates}) {:ok, card} = - Access.assign_port(card, %{ + Domain.assign_port(card, %{ assignment: %Assignment{assignee_id: assignee.id, operation: :auto_assign} }) {:ok, card} = - Access.assign_port(card, %{ + Domain.assign_port(card, %{ assignment: %Assignment{assignee_id: assignee.id, operation: :auto_assign} }) @@ -133,28 +134,28 @@ defmodule Diffo.Access.CardTest do encoding = Jason.encode!(card) |> Diffo.Util.summarise_dates() assert encoding == - ~s({\"id\":\"#{card.id}",\"href\":\"resourceInventoryManagement/v4/resource/card/#{card.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"name\":\"card\",\"version\":\"v1.0.0\"},\"serviceRelationship\":[{\"type\":\"assignedTo\",\"service\":{\"id\":\"#{assignee.id}\",\"href\":\"serviceInventoryManagement/v4/service/dslAccess/#{assignee.id}\"},\"serviceRelationshipCharacteristic\":[{\"name\":\"port\",\"value\":1}]},{\"type\":\"assignedTo\",\"service\":{\"id\":\"#{assignee.id}\",\"href\":\"serviceInventoryManagement/v4/service/dslAccess/#{assignee.id}\"},\"serviceRelationshipCharacteristic\":[{\"name\":\"port\",\"value\":2}]}],\"resourceCharacteristic\":[{\"name\":\"card\",\"value\":{\"family\":\"ISAM\",\"model\":\"EBLT48\",\"technology\":\"adsl2Plus\"}},{\"name\":\"ports\",\"value\":{\"first\":1,\"last\":48,\"free\":46,\"type\":\"ADSL2+\",\"algorithm\":\"lowest\"}}]}) + ~s({\"id\":\"#{card.id}",\"href\":\"resourceInventoryManagement/v4/resource/card/#{card.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"name\":\"card\",\"version\":\"v1.0.0\"},\"resourceRelationship\":[{\"type\":\"assignedTo\",\"resource\":{\"id\":\"#{assignee.id}\",\"href\":\"resourceInventoryManagement/v4/resource/shelf/#{assignee.id}\"},\"resourceRelationshipCharacteristic\":[{\"name\":\"port\",\"value\":1}]},{\"type\":\"assignedTo\",\"resource\":{\"id\":\"#{assignee.id}\",\"href\":\"resourceInventoryManagement/v4/resource/shelf/#{assignee.id}\"},\"resourceRelationshipCharacteristic\":[{\"name\":\"port\",\"value\":2}]}],\"resourceCharacteristic\":[{\"name\":\"card\",\"value\":{\"family\":\"ISAM\",\"model\":\"EBLT48\",\"technology\":\"adsl2Plus\"}},{\"name\":\"ports\",\"value\":{\"first\":1,\"last\":48,\"free\":46,\"type\":\"ADSL2+\",\"algorithm\":\"lowest\"}}]}) end test "specific assignment rejects duplicate request" do - {:ok, assignee} = Access.qualify_dsl() + {:ok, assignee} = Domain.build_shelf() - {:ok, card} = Access.build_card(%{}) + {:ok, card} = Domain.build_card(%{}) updates = [ card: [family: :ISAM, model: "EBLT48", technology: :adsl2Plus], ports: [first: 1, last: 48, free: 48, type: "ADSL2+"] ] - {:ok, card} = Access.define_card(card, %{characteristic_value_updates: updates}) + {:ok, card} = Domain.define_card(card, %{characteristic_value_updates: updates}) {:ok, card} = - Access.assign_port(card, %{ + Domain.assign_port(card, %{ assignment: %Assignment{id: 5, assignee_id: assignee.id, operation: :assign} }) {:error, _error} = - Access.assign_port(card, %{ + Domain.assign_port(card, %{ assignment: %Assignment{id: 5, assignee_id: assignee.id, operation: :assign} }) @@ -163,7 +164,7 @@ defmodule Diffo.Access.CardTest do encoding = Jason.encode!(card) |> Diffo.Util.summarise_dates() assert encoding == - ~s({\"id\":\"#{card.id}",\"href\":\"resourceInventoryManagement/v4/resource/card/#{card.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"name\":\"card\",\"version\":\"v1.0.0\"},\"serviceRelationship\":[{\"type\":\"assignedTo\",\"service\":{\"id\":\"#{assignee.id}\",\"href\":\"serviceInventoryManagement/v4/service/dslAccess/#{assignee.id}\"},\"serviceRelationshipCharacteristic\":[{\"name\":\"port\",\"value\":5}]}],\"resourceCharacteristic\":[{\"name\":\"card\",\"value\":{\"family\":\"ISAM\",\"model\":\"EBLT48\",\"technology\":\"adsl2Plus\"}},{\"name\":\"ports\",\"value\":{\"first\":1,\"last\":48,\"free\":47,\"type\":\"ADSL2+\",\"algorithm\":\"lowest\"}}]}) + ~s({\"id\":\"#{card.id}",\"href\":\"resourceInventoryManagement/v4/resource/card/#{card.id}",\"category\":\"Network Resource\",\"resourceSpecification\":{\"id\":\"cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"href\":\"resourceCatalogManagement/v4/resourceSpecification/cd29956f-6c68-44cc-bf54-705eb8d2f754\",\"name\":\"card\",\"version\":\"v1.0.0\"},\"resourceRelationship\":[{\"type\":\"assignedTo\",\"resource\":{\"id\":\"#{assignee.id}\",\"href\":\"resourceInventoryManagement/v4/resource/shelf/#{assignee.id}\"},\"resourceRelationshipCharacteristic\":[{\"name\":\"port\",\"value\":5}]}],\"resourceCharacteristic\":[{\"name\":\"card\",\"value\":{\"family\":\"ISAM\",\"model\":\"EBLT48\",\"technology\":\"adsl2Plus\"}},{\"name\":\"ports\",\"value\":{\"first\":1,\"last\":48,\"free\":47,\"type\":\"ADSL2+\",\"algorithm\":\"lowest\"}}]}) end end end diff --git a/test/support/domain.ex b/test/support/domain.ex new file mode 100644 index 0000000..c364ffa --- /dev/null +++ b/test/support/domain.ex @@ -0,0 +1,39 @@ +# SPDX-FileCopyrightText: 2025 diffo contributors +# +# SPDX-License-Identifier: MIT + +defmodule Diffo.Test.Domain do + @moduledoc """ + Diffo - TMF Service and Resource Management with a difference + + Domain - domain for testing + """ + use Ash.Domain, + otp_app: :diffo, + validate_config_inclusion?: false + + alias Diffo.Test.Shelf + alias Diffo.Test.Card + + domain do + description "A domain for testing" + end + + resources do + resource Shelf do + define :get_shelf_by_id, action: :read, get_by: :id + define :build_shelf, action: :build + define :define_shelf, action: :define + define :relate_shelf, action: :relate + define :assign_slot, action: :assign_slot + end + + resource Card do + define :get_card_by_id, action: :read, get_by: :id + define :build_card, action: :build + define :define_card, action: :define + define :relate_card, action: :relate + define :assign_port, action: :assign_port + end + end +end diff --git a/lib/diffo/access/resources/card.ex b/test/support/resource/card.ex similarity index 54% rename from lib/diffo/access/resources/card.ex rename to test/support/resource/card.ex index b6d3b33..ad043f6 100644 --- a/lib/diffo/access/resources/card.ex +++ b/test/support/resource/card.ex @@ -2,28 +2,25 @@ # # SPDX-License-Identifier: MIT -defmodule Diffo.Access.Card do +defmodule Diffo.Test.Card do @moduledoc """ Diffo - TMF Service and Resource Management with a difference Card - Card Resource Instance """ - alias Diffo.Provider.BaseInstance - alias Diffo.Provider.Instance.Specification alias Diffo.Provider.Instance.Relationship - alias Diffo.Provider.Instance.Feature alias Diffo.Provider.Instance.Characteristic - alias Diffo.Provider.Instance.Place - alias Diffo.Provider.Instance.Party + alias Diffo.Provider.Instance.ActionHelper alias Diffo.Provider.Assigner alias Diffo.Provider.Assignment - - alias Diffo.Access + alias Diffo.Provider.AssignableValue + alias Diffo.Test.Domain + alias Diffo.Test.CardValue use Ash.Resource, fragments: [BaseInstance], - domain: Access + domain: Domain resource do description "An Ash Resource representing a Card" @@ -39,8 +36,8 @@ defmodule Diffo.Access.Card do end characteristics do - characteristic :card, Diffo.Access.CardValue - characteristic :ports, Diffo.Provider.AssignableValue + characteristic :card, CardValue + characteristic :ports, AssignableValue end actions do @@ -57,24 +54,11 @@ defmodule Diffo.Access.Card do change set_attribute(:type, :resource) change before_action(fn changeset, _context -> - changeset - |> Specification.set_specified_by_argument() - |> Feature.set_features_argument() - |> Characteristic.set_characteristics_argument() + ActionHelper.build_before(changeset) end) change after_action(fn changeset, result, _context -> - with {:ok, with_specification} <- Specification.relate_instance(result, changeset), - {:ok, with_relationships} <- - Relationship.relate_instance(with_specification, changeset), - {:ok, with_features} <- - Feature.relate_instance(with_relationships, changeset), - {:ok, with_characteristics} <- - Characteristic.relate_instance(with_features, changeset), - {:ok, with_places} <- Place.relate_instance(with_characteristics, changeset), - {:ok, _with_parties} <- Party.relate_instance(with_places, changeset), - {:ok, card} <- Access.get_card_by_id(result.id), - do: {:ok, card} + ActionHelper.build_after(changeset, result, Domain, :get_card_by_id) end) change load [:href] @@ -86,9 +70,9 @@ defmodule Diffo.Access.Card do argument :characteristic_value_updates, {:array, :term} change after_action(fn changeset, result, _context -> - with {:ok, _result} <- Characteristic.update_values(result, changeset), - {:ok, card} <- Access.get_card_by_id(result.id), - do: {:ok, card} + with {:ok, result} <- Characteristic.update_values(result, changeset), + {:ok, result} <- Domain.get_card_by_id(result.id), + do: {:ok, result} end) end @@ -97,9 +81,9 @@ defmodule Diffo.Access.Card do argument :relationships, {:array, :struct} change after_action(fn changeset, result, _context -> - with {:ok, _card} <- Relationship.relate_instance(result, changeset), - {:ok, card} <- Access.get_card_by_id(result.id), - do: {:ok, card} + with {:ok, result} <- Relationship.relate_instance(result, changeset), + {:ok, result} <- Domain.get_card_by_id(result.id), + do: {:ok, result} end) end @@ -108,9 +92,9 @@ defmodule Diffo.Access.Card do argument :assignment, :struct, constraints: [instance_of: Assignment] change after_action(fn changeset, result, _context -> - with {:ok, _card} <- Assigner.assign(result, changeset, :ports, :port), - {:ok, card} <- Access.get_card_by_id(result.id), - do: {:ok, card} + with {:ok, result} <- Assigner.assign(result, changeset, :ports, :port), + {:ok, result} <- Domain.get_card_by_id(result.id), + do: {:ok, result} end) end end diff --git a/lib/diffo/access/resources/characteristic_values/card_value.ex b/test/support/resource/card_value.ex similarity index 96% rename from lib/diffo/access/resources/characteristic_values/card_value.ex rename to test/support/resource/card_value.ex index dce1677..f1e280c 100644 --- a/lib/diffo/access/resources/characteristic_values/card_value.ex +++ b/test/support/resource/card_value.ex @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: MIT -defmodule Diffo.Access.CardValue do +defmodule Diffo.Test.CardValue do @moduledoc """ Diffo - TMF Service and Resource Management with a difference diff --git a/lib/diffo/access/resources/shelf.ex b/test/support/resource/shelf.ex similarity index 54% rename from lib/diffo/access/resources/shelf.ex rename to test/support/resource/shelf.ex index 33c40c7..e41a7db 100644 --- a/lib/diffo/access/resources/shelf.ex +++ b/test/support/resource/shelf.ex @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: MIT -defmodule Diffo.Access.Shelf do +defmodule Diffo.Test.Shelf do @moduledoc """ Diffo - TMF Service and Resource Management with a difference @@ -10,20 +10,19 @@ defmodule Diffo.Access.Shelf do """ alias Diffo.Provider.BaseInstance - alias Diffo.Provider.Instance.Specification alias Diffo.Provider.Instance.Relationship - alias Diffo.Provider.Instance.Feature alias Diffo.Provider.Instance.Characteristic - alias Diffo.Provider.Instance.Place - alias Diffo.Provider.Instance.Party + alias Diffo.Provider.Instance.ActionHelper alias Diffo.Provider.Assigner alias Diffo.Provider.Assignment + alias Diffo.Provider.AssignableValue - alias Diffo.Access + alias Diffo.Test.Domain + alias Diffo.Test.ShelfValue use Ash.Resource, fragments: [BaseInstance], - domain: Access + domain: Domain resource do description "An Ash Resource representing a Shelf" @@ -39,8 +38,8 @@ defmodule Diffo.Access.Shelf do end characteristics do - characteristic :shelf, Diffo.Access.ShelfValue - characteristic :slots, Diffo.Provider.AssignableValue + characteristic :shelf, ShelfValue + characteristic :slots, AssignableValue end actions do @@ -57,24 +56,11 @@ defmodule Diffo.Access.Shelf do change set_attribute(:type, :resource) change before_action(fn changeset, _context -> - changeset - |> Specification.set_specified_by_argument() - |> Feature.set_features_argument() - |> Characteristic.set_characteristics_argument() + ActionHelper.build_before(changeset) end) change after_action(fn changeset, result, _context -> - with {:ok, with_specification} <- Specification.relate_instance(result, changeset), - {:ok, with_relationships} <- - Relationship.relate_instance(with_specification, changeset), - {:ok, with_features} <- - Feature.relate_instance(with_relationships, changeset), - {:ok, with_characteristics} <- - Characteristic.relate_instance(with_features, changeset), - {:ok, with_places} <- Place.relate_instance(with_characteristics, changeset), - {:ok, _with_parties} <- Party.relate_instance(with_places, changeset), - {:ok, shelf} <- Access.get_shelf_by_id(result.id), - do: {:ok, shelf} + ActionHelper.build_after(changeset, result, Domain, :get_shelf_by_id) end) change load [:href] @@ -86,9 +72,9 @@ defmodule Diffo.Access.Shelf do argument :characteristic_value_updates, {:array, :term} change after_action(fn changeset, result, _context -> - with {:ok, _result} <- Characteristic.update_values(result, changeset), - {:ok, card} <- Access.get_shelf_by_id(result.id), - do: {:ok, card} + with {:ok, result} <- Characteristic.update_values(result, changeset), + {:ok, result} <- Domain.get_shelf_by_id(result.id), + do: {:ok, result} end) end @@ -97,9 +83,9 @@ defmodule Diffo.Access.Shelf do argument :relationships, {:array, :struct} change after_action(fn changeset, result, _context -> - with {:ok, _shelf} <- Relationship.relate_instance(result, changeset), - {:ok, shelf} <- Access.get_shelf_by_id(result.id), - do: {:ok, shelf} + with {:ok, result} <- Relationship.relate_instance(result, changeset), + {:ok, result} <- Domain.get_shelf_by_id(result.id), + do: {:ok, result} end) end @@ -108,9 +94,9 @@ defmodule Diffo.Access.Shelf do argument :assignment, :struct, constraints: [instance_of: Assignment] change after_action(fn changeset, result, _context -> - with {:ok, _card} <- Assigner.assign(result, changeset, :slots, :slot), - {:ok, card} <- Access.get_shelf_by_id(result.id), - do: {:ok, card} + with {:ok, result} <- Assigner.assign(result, changeset, :slots, :slot), + {:ok, result} <- Domain.get_shelf_by_id(result.id), + do: {:ok, result} end) end end diff --git a/lib/diffo/access/resources/characteristic_values/shelf_value.ex b/test/support/resource/shelf_value.ex similarity index 95% rename from lib/diffo/access/resources/characteristic_values/shelf_value.ex rename to test/support/resource/shelf_value.ex index 7c44dc2..b7580dc 100644 --- a/lib/diffo/access/resources/characteristic_values/shelf_value.ex +++ b/test/support/resource/shelf_value.ex @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: MIT -defmodule Diffo.Access.ShelfValue do +defmodule Diffo.Test.ShelfValue do @moduledoc """ Diffo - TMF Service and Resource Management with a difference