Skip to content

Commit 9539ef7

Browse files
Merge pull request #37 from diffo-dev/36-update-to-diffo-030
36 update to diffo 040
2 parents c0023a2 + 85ae614 commit 9539ef7

59 files changed

Lines changed: 2337 additions & 1188 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

lib/access/access.ex

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,23 @@ defmodule DiffoExample.Access do
99
Access - example Access domain
1010
"""
1111
use Ash.Domain,
12-
otp_app: :diffo
12+
otp_app: :diffo,
13+
fragments: [Diffo.Provider.DomainFragment]
1314

1415
alias DiffoExample.Access.DslAccess
1516
alias DiffoExample.Access.Shelf
1617
alias DiffoExample.Access.Card
1718
alias DiffoExample.Access.Cable
1819
alias DiffoExample.Access.Path
20+
alias DiffoExample.Access.CableCharacteristic
21+
alias DiffoExample.Access.CardCharacteristic
22+
alias DiffoExample.Access.ShelfCharacteristic
23+
alias DiffoExample.Access.PathCharacteristic
24+
alias DiffoExample.Access.LineCharacteristic
25+
alias DiffoExample.Access.DslamCharacteristic
26+
alias DiffoExample.Access.AggregateCharacteristic
27+
alias DiffoExample.Access.CircuitCharacteristic
28+
alias DiffoExample.Access.ConstraintsCharacteristic
1929

2030
domain do
2131
description "An example showing how TMF Services and Resources for a fictional Access domain can be extended from the Provider domain"
@@ -59,5 +69,15 @@ defmodule DiffoExample.Access do
5969
define :define_path, action: :define
6070
define :relate_path, action: :relate
6171
end
72+
73+
resource CableCharacteristic
74+
resource CardCharacteristic
75+
resource ShelfCharacteristic
76+
resource PathCharacteristic
77+
resource LineCharacteristic
78+
resource DslamCharacteristic
79+
resource AggregateCharacteristic
80+
resource CircuitCharacteristic
81+
resource ConstraintsCharacteristic
6282
end
6383
end
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# SPDX-FileCopyrightText: 2025 diffo_example contributors <https://github.com/diffo-dev/diffo_example/graphs.contributors>
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
defmodule DiffoExample.Access.CharacteristicChanges do
6+
@moduledoc """
7+
Shared changeset helpers for Access characteristic update actions.
8+
9+
Characteristics store nested value structs (units, bandwidth profiles)
10+
as flat attributes. These helpers map the nested argument shape onto
11+
those attributes.
12+
"""
13+
14+
alias Ash.Changeset
15+
16+
@doc """
17+
Splits a `%{amount: a, unit: u}` argument into two attributes.
18+
19+
Returns the changeset unchanged when the argument is nil or not a map
20+
with both keys.
21+
"""
22+
def set_unit(changeset, arg, amount_attr, unit_attr) do
23+
case Changeset.get_argument(changeset, arg) do
24+
%{amount: amount, unit: unit} ->
25+
changeset
26+
|> Changeset.force_change_attribute(amount_attr, amount)
27+
|> Changeset.force_change_attribute(unit_attr, unit)
28+
29+
_ ->
30+
changeset
31+
end
32+
end
33+
34+
@doc """
35+
Splits a `%{downstream: d, upstream: u, units: units}` bandwidth-profile
36+
argument into three attributes.
37+
38+
Returns the changeset unchanged when the argument is nil or not a map
39+
with all three keys.
40+
"""
41+
def set_bandwidth_profile(changeset, arg, downstream_attr, upstream_attr, units_attr) do
42+
case Changeset.get_argument(changeset, arg) do
43+
%{downstream: d, upstream: u, units: units} ->
44+
changeset
45+
|> Changeset.force_change_attribute(downstream_attr, d)
46+
|> Changeset.force_change_attribute(upstream_attr, u)
47+
|> Changeset.force_change_attribute(units_attr, units)
48+
49+
_ ->
50+
changeset
51+
end
52+
end
53+
end

lib/access/resources/cable.ex

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ defmodule DiffoExample.Access.Cable do
1010
"""
1111

1212
alias Diffo.Provider.BaseInstance
13-
alias Diffo.Provider.Instance.Relationship
14-
alias Diffo.Provider.Instance.Characteristic
15-
alias Diffo.Provider.Assigner
1613
alias Diffo.Provider.Assignment
1714

1815
alias DiffoExample.Access
@@ -26,7 +23,7 @@ defmodule DiffoExample.Access.Cable do
2623
plural_name :Cables
2724
end
2825

29-
structure do
26+
provider do
3027
specification do
3128
id "ce0a567a-6abb-4862-9e33-851fd79fa595"
3229
name "cable"
@@ -36,14 +33,22 @@ defmodule DiffoExample.Access.Cable do
3633
end
3734

3835
characteristics do
39-
characteristic :cable, DiffoExample.Access.CableValue
40-
characteristic :pairs, Diffo.Provider.AssignableValue
36+
characteristic :cable, DiffoExample.Access.CableCharacteristic
37+
end
38+
39+
pools do
40+
pool :pairs, :pair
4141
end
42-
end
4342

44-
behaviour do
45-
actions do
46-
create :build
43+
relationships do
44+
source :all
45+
target :all
46+
end
47+
48+
behaviour do
49+
actions do
50+
create :build
51+
end
4752
end
4853
end
4954

@@ -64,11 +69,8 @@ defmodule DiffoExample.Access.Cable do
6469
description "defines the cable"
6570
argument :characteristic_value_updates, {:array, :term}
6671

67-
change after_action(fn changeset, result, _context ->
68-
with {:ok, result} <- Characteristic.update_values(result, changeset),
69-
{:ok, result} <- Access.get_cable_by_id(result.id),
70-
do: {:ok, result}
71-
end)
72+
change set_attribute(:resource_state, :operating)
73+
change DiffoExample.Changes.Define
7274
end
7375

7476
update :relate do
@@ -86,11 +88,7 @@ defmodule DiffoExample.Access.Cable do
8688
description "relates the cable with an instance by assigning a pair"
8789
argument :assignment, :struct, constraints: [instance_of: Assignment]
8890

89-
change after_action(fn changeset, result, _context ->
90-
with {:ok, result} <- Assigner.assign(result, changeset, :pairs, :pair),
91-
{:ok, result} <- Access.get_cable_by_id(result.id),
92-
do: {:ok, result}
93-
end)
91+
change {DiffoExample.Changes.Assign, pool: :pairs}
9492
end
9593
end
9694
end

lib/access/resources/card.ex

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ defmodule DiffoExample.Access.Card do
1010
"""
1111

1212
alias Diffo.Provider.BaseInstance
13-
alias Diffo.Provider.Instance.Relationship
14-
alias Diffo.Provider.Instance.Characteristic
15-
alias Diffo.Provider.Assigner
1613
alias Diffo.Provider.Assignment
1714

1815
alias DiffoExample.Access
@@ -26,7 +23,7 @@ defmodule DiffoExample.Access.Card do
2623
plural_name :Cards
2724
end
2825

29-
structure do
26+
provider do
3027
specification do
3128
id "cd29956f-6c68-44cc-bf54-705eb8d2f754"
3229
name "card"
@@ -36,14 +33,22 @@ defmodule DiffoExample.Access.Card do
3633
end
3734

3835
characteristics do
39-
characteristic :card, DiffoExample.Access.CardValue
40-
characteristic :ports, Diffo.Provider.AssignableValue
36+
characteristic :card, DiffoExample.Access.CardCharacteristic
37+
end
38+
39+
pools do
40+
pool :ports, :port
41+
end
42+
43+
relationships do
44+
source :all
45+
target :all
4146
end
42-
end
4347

44-
behaviour do
45-
actions do
46-
create :build
48+
behaviour do
49+
actions do
50+
create :build
51+
end
4752
end
4853
end
4954

@@ -64,33 +69,22 @@ defmodule DiffoExample.Access.Card do
6469
description "defines the card"
6570
argument :characteristic_value_updates, {:array, :term}
6671

67-
change after_action(fn changeset, result, _context ->
68-
with {:ok, result} <- Characteristic.update_values(result, changeset),
69-
{:ok, result} <- Access.get_card_by_id(result.id),
70-
do: {:ok, result}
71-
end)
72+
change set_attribute(:resource_state, :operating)
73+
change DiffoExample.Changes.Define
7274
end
7375

7476
update :relate do
7577
description "relates the card with other instances"
7678
argument :relationships, {:array, :struct}
7779

78-
change after_action(fn changeset, result, _context ->
79-
with {:ok, result} <- Relationship.relate_instance(result, changeset),
80-
{:ok, result} <- Access.get_card_by_id(result.id),
81-
do: {:ok, result}
82-
end)
80+
change DiffoExample.Changes.Relate
8381
end
8482

8583
update :assign_port do
8684
description "relates the card with an instance by assigning a port"
8785
argument :assignment, :struct, constraints: [instance_of: Assignment]
8886

89-
change after_action(fn changeset, result, _context ->
90-
with {:ok, result} <- Assigner.assign(result, changeset, :ports, :port),
91-
{:ok, result} <- Access.get_card_by_id(result.id),
92-
do: {:ok, result}
93-
end)
87+
change {DiffoExample.Changes.Assign, pool: :ports}
9488
end
9589
end
9690
end
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# SPDX-FileCopyrightText: 2025 diffo_example contributors <https://github.com/diffo-dev/diffo_example/graphs.contributors>
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
defmodule DiffoExample.Access.CableCharacteristic do
6+
@moduledoc "Typed characteristic for a Cable's physical properties."
7+
use Ash.Resource,
8+
fragments: [Diffo.Provider.BaseCharacteristic],
9+
domain: DiffoExample.Access
10+
11+
alias DiffoExample.Access.CharacteristicChanges
12+
13+
resource do
14+
description "Typed characteristic carrying cable physical property fields"
15+
plural_name :cable_characteristics
16+
end
17+
18+
actions do
19+
create :create do
20+
accept [:name, :pairs, :length_amount, :length_unit, :loss_amount, :loss_unit, :technology]
21+
argument :instance_id, :uuid
22+
argument :feature_id, :uuid
23+
change manage_relationship(:instance_id, :instance, type: :append)
24+
change manage_relationship(:feature_id, :feature, type: :append)
25+
end
26+
27+
update :update do
28+
accept [:pairs, :technology, :length_amount, :length_unit, :loss_amount, :loss_unit]
29+
argument :length, :term, allow_nil?: true
30+
argument :loss, :term, allow_nil?: true
31+
32+
change fn changeset, _ ->
33+
changeset
34+
|> CharacteristicChanges.set_unit(:length, :length_amount, :length_unit)
35+
|> CharacteristicChanges.set_unit(:loss, :loss_amount, :loss_unit)
36+
end
37+
end
38+
end
39+
40+
attributes do
41+
attribute :pairs, :integer, public?: true
42+
attribute :length_amount, :integer, public?: true
43+
attribute :length_unit, :atom, public?: true
44+
attribute :loss_amount, :float, public?: true
45+
attribute :loss_unit, :atom, public?: true
46+
attribute :technology, :atom, public?: true
47+
end
48+
49+
calculations do
50+
calculate :value,
51+
Diffo.Type.CharacteristicValue,
52+
DiffoExample.Access.CableCharacteristic.ValueCalculation do
53+
public? true
54+
end
55+
end
56+
57+
preparations do
58+
prepare build(load: [:value])
59+
end
60+
61+
jason do
62+
pick [:name, :value]
63+
compact true
64+
end
65+
end
66+
67+
defmodule DiffoExample.Access.CableCharacteristic.Value do
68+
@moduledoc false
69+
use Ash.TypedStruct, extensions: [AshJason.TypedStruct, AshOutstanding.TypedStruct]
70+
71+
alias DiffoExample.Access.IntegerUnit
72+
alias DiffoExample.Access.FloatUnit
73+
74+
jason do
75+
pick [:pairs, :length, :loss, :technology]
76+
compact true
77+
end
78+
79+
outstanding do
80+
expect [:pairs, :loss]
81+
end
82+
83+
typed_struct do
84+
field :pairs, :integer
85+
field :length, IntegerUnit
86+
field :loss, FloatUnit
87+
field :technology, :atom
88+
end
89+
end
90+
91+
defmodule DiffoExample.Access.CableCharacteristic.ValueCalculation do
92+
@moduledoc false
93+
use Ash.Resource.Calculation
94+
95+
alias DiffoExample.Access.IntegerUnit
96+
alias DiffoExample.Access.FloatUnit
97+
alias DiffoExample.Access.CableCharacteristic
98+
99+
@impl true
100+
def load(_, _, _), do: []
101+
102+
@impl true
103+
def calculate(records, _, _) do
104+
Enum.map(records, fn r ->
105+
%CableCharacteristic.Value{
106+
pairs: r.pairs,
107+
length:
108+
if r.length_amount do
109+
%IntegerUnit{amount: r.length_amount, unit: r.length_unit}
110+
end,
111+
loss:
112+
if r.loss_amount do
113+
%FloatUnit{amount: r.loss_amount, unit: r.loss_unit}
114+
end,
115+
technology: r.technology
116+
}
117+
end)
118+
end
119+
end

0 commit comments

Comments
 (0)