Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,7 @@ config :spark,
]
]

config :ash, :custom_expressions, [Diffo.Unwrap.AshCustomExpression]

config :diffo, ash_domains: [Diffo.Provider]
import_config "#{config_env()}.exs"
3 changes: 2 additions & 1 deletion config/dev.exs
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ level =
end

config :logger, :console,
level: level,
# level: level,
level: :debug,
format: "$date $time [$level] $metadata$message\n"
7 changes: 4 additions & 3 deletions config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import Config

config :logger, level: :warning
config :ash, disable_async?: true
config :ash, :missed_notifications, :ignore

Expand All @@ -16,8 +15,8 @@ config :bolty, Bolt,
max_overflow: 3,
prefix: :default,
name: Bolt,
log: true,
log_hex: true
log: false,
log_hex: false

level =
if System.get_env("DEBUG") do
Expand All @@ -26,6 +25,8 @@ level =
:info
end

config :logger, level: level

config :logger, :console,
level: level,
format: "$date $time [$level] $metadata$message\n"
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ We need to define each GPU instance, in this case defining the gpu Characteristi
```elixir
updates = [
gpu: [family: :nvidia, model: "GeForce RTX5090", technology: :blackwell],
cores: [first: 1, last: 680, free: 680, type: "tensor"]
cores: [first: 1, last: 680, free: 680, assignable_type: "tensor"]
]

gpu_1 = Compute.define_gpu!(gpu_1, %{characteristic_value_updates: updates})
Expand Down
10 changes: 5 additions & 5 deletions lib/diffo/helpers/uuid.ex
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ defmodule Diffo.Uuid do
@doc """
Returns trailing uuid4 if valid, or nil.
## Examples
iex> Diffo.Uuid.trailing_uuid4("serviceInventoryManagement/v4/service/accessEvc/d2566874-d5ee-400b-9983-10d63ec52f32")
iex> Diffo.Uuid.trailing_uuid4("serviceInventoryManagement/v4/service/d2566874-d5ee-400b-9983-10d63ec52f32")
"d2566874-d5ee-400b-9983-10d63ec52f32"

iex> Diffo.Uuid.trailing_uuid4("serviceInventoryManagement/v4/service/accessEvc/d2566874-d5ee-400b-9983")
iex> Diffo.Uuid.trailing_uuid4("serviceInventoryManagement/v4/service/d2566874-d5ee-400b-9983")
nil

iex> Diffo.Uuid.trailing_uuid4("d2566874-d5ee-400b-9983-10d63ec52f32")
Expand Down Expand Up @@ -136,7 +136,7 @@ defmodule Diffo.Uuid do
iex> Diffo.Uuid.expect_uuid4("d2566874-d5ee-400b-9983-10d63ec52f32")
nil

iex> Diffo.Uuid.expect_uuid4("serviceInventoryManagement/v4/service/accessEvc/d2566874-d5ee-400b-9983-10d63ec52f32")
iex> Diffo.Uuid.expect_uuid4("serviceInventoryManagement/v4/service/d2566874-d5ee-400b-9983-10d63ec52f32")
:uuid4

iex> Diffo.Uuid.expect_uuid4(nil)
Expand All @@ -154,10 +154,10 @@ defmodule Diffo.Uuid do
@doc """
Callback function for outstanding to expect trailing uuid4.
## Examples
iex> Diffo.Uuid.expect_trailing_uuid4("serviceInventoryManagement/v4/service/accessEvc/d2566874-d5ee-400b-9983-10d63ec52f32")
iex> Diffo.Uuid.expect_trailing_uuid4("serviceInventoryManagement/v4/service/d2566874-d5ee-400b-9983-10d63ec52f32")
nil

iex> Diffo.Uuid.expect_trailing_uuid4("serviceInventoryManagement/v4/service/accessEvc/d2566874-d5ee-400b-9983")
iex> Diffo.Uuid.expect_trailing_uuid4("serviceInventoryManagement/v4/service/d2566874-d5ee-400b-9983")
:trailing_uuid4

iex> Diffo.Uuid.expect_trailing_uuid4("d2566874-d5ee-400b-9983-10d63ec52f32")
Expand Down
5 changes: 3 additions & 2 deletions lib/diffo/provider/assigner/assignable_value.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ defmodule Diffo.Provider.AssignableValue do
use Ash.TypedStruct, extensions: [AshJason.TypedStruct]

jason do
pick [:first, :last, :free, :type, :algorithm]
pick [:first, :last, :free, :assignable_type, :algorithm]
compact true
rename assignable_type: :type
end

typed_struct do
Expand All @@ -31,7 +32,7 @@ defmodule Diffo.Provider.AssignableValue do
default: 1,
constraints: [min: 0]

field :type, :atom, description: "the type of the assignable thing"
field :assignable_type, :string, description: "the type of the assignable thing"

field :algorithm, :atom,
description: "the assignment algorithm",
Expand Down
47 changes: 30 additions & 17 deletions lib/diffo/provider/assigner/assigner.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ defmodule Diffo.Provider.Assigner do
"""

alias Diffo.Provider.AssignableValue
alias Diffo.Type.Value

@doc """
Assign a thing using the instance changeset assignment
Expand Down Expand Up @@ -53,7 +54,11 @@ defmodule Diffo.Provider.Assigner do
defp relate_is_assigned(result, things, thing, value, assignee_id)
when is_struct(result) and is_atom(things) and is_atom(thing) and is_integer(value) and
is_bitstring(assignee_id) do
case Diffo.Provider.create_characteristic(%{name: thing, value: value, type: :relationship}) do
case Diffo.Provider.create_characteristic(%{
name: thing,
value: Value.primitive("integer", value),
type: :relationship
}) do
{:ok, characteristic} ->
case Diffo.Provider.create_relationship(%{
type: :assignedTo,
Expand All @@ -62,7 +67,6 @@ defmodule Diffo.Provider.Assigner do
characteristics: [characteristic.id]
}) do
{:ok, _relationship} ->
# we haven't refreshed the result there will be a new forward_relationship and an updated things characteristic
case decrement_free(result, things) do
:ok ->
{:ok, result}
Expand Down Expand Up @@ -91,7 +95,7 @@ defmodule Diffo.Provider.Assigner do
} ->
type == :assignedTo and target_id == assignee_id and
Enum.any?(characteristics, fn %{name: name, value: v} ->
name == thing and v == value
name == thing and Diffo.Unwrap.unwrap(v) == value
end)
end)

Expand All @@ -105,16 +109,13 @@ defmodule Diffo.Provider.Assigner do
characteristic =
Enum.find(relationship.characteristics, fn %{name: n} -> n == thing end)

# unrelate the relationship characterisitic
relationship =
Diffo.Provider.unrelate_relationship_characteristics!(relationship, %{
characteristics: [characteristic.id]
})

# delete the relationship characteristic
Diffo.Provider.delete_characteristic(characteristic.id)

# delete the relationship
case Diffo.Provider.delete_relationship(relationship.id) do
:ok ->
case increment_free(result, things) do
Expand Down Expand Up @@ -148,8 +149,8 @@ defmodule Diffo.Provider.Assigner do
if characteristic do
assignment =
struct(Diffo.Provider.Assignment, %{
id: characteristic.value,
type: thing,
id: Diffo.Unwrap.unwrap(characteristic.value),
assignable_type: thing,
assignee_id: target_id
})

Expand All @@ -168,9 +169,10 @@ defmodule Diffo.Provider.Assigner do
defp next(instance, things, thing)
when is_struct(instance) and is_atom(things) and is_atom(thing) do
characteristic = Enum.find(instance.characteristics, fn %{name: name} -> name == things end)
algorithm = Map.get(characteristic.value, :algorithm)
assignable_value = Diffo.Unwrap.unwrap(characteristic.value)
algorithm = Map.get(assignable_value, :algorithm)

case free = free(instance, thing, characteristic.value) do
case free = free(instance, thing, assignable_value) do
[] ->
{:error, "all things are assigned"}

Expand All @@ -191,7 +193,8 @@ defmodule Diffo.Provider.Assigner do
defp assignable?(instance, things, thing, value)
when is_struct(instance) and is_atom(things) and is_atom(thing) and is_integer(value) do
characteristic = Enum.find(instance.characteristics, fn %{name: name} -> name == things end)
free = free(instance, thing, characteristic.value)
assignable_value = Diffo.Unwrap.unwrap(characteristic.value)
free = free(instance, thing, assignable_value)

value in free
end
Expand All @@ -200,10 +203,15 @@ defmodule Diffo.Provider.Assigner do
characteristic =
Enum.find(instance.characteristics, fn %{name: name} -> name == things end)

{_free, assignable_value} =
Map.get_and_update(characteristic.value, :free, fn free -> {free - 1, free - 1} end)
assignable_value = Diffo.Unwrap.unwrap(characteristic.value)

case Diffo.Provider.update_characteristic(characteristic, %{value: assignable_value}) do
{_free, updated} =
Map.get_and_update(assignable_value, :free, fn free -> {free - 1, free - 1} end)

{:ok, new_struct} = Ash.Type.cast_input(AssignableValue, Map.from_struct(updated), AssignableValue.subtype_constraints())
new_value = Value.dynamic(AssignableValue, new_struct)

case Diffo.Provider.update_characteristic(characteristic, %{value: new_value}) do
{:ok, _characteristic} ->
:ok

Expand All @@ -216,10 +224,15 @@ defmodule Diffo.Provider.Assigner do
characteristic =
Enum.find(instance.characteristics, fn %{name: name} -> name == things end)

{_free, assignable_value} =
Map.get_and_update(characteristic.value, :free, fn free -> {free + 1, free + 1} end)
assignable_value = Diffo.Unwrap.unwrap(characteristic.value)

{_free, updated} =
Map.get_and_update(assignable_value, :free, fn free -> {free + 1, free + 1} end)

{:ok, new_struct} = Ash.Type.cast_input(AssignableValue, Map.from_struct(updated), AssignableValue.subtype_constraints())
new_value = Value.dynamic(AssignableValue, new_struct)

case Diffo.Provider.update_characteristic(characteristic, %{value: assignable_value}) do
case Diffo.Provider.update_characteristic(characteristic, %{value: new_value}) do
{:ok, _characteristic} ->
:ok

Expand Down
5 changes: 3 additions & 2 deletions lib/diffo/provider/assigner/assignment.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ defmodule Diffo.Provider.Assignment do
use Ash.TypedStruct, extensions: [AshJason.TypedStruct]

jason do
pick [:id, :assignee_id, :operation]
pick [:id, :assignee_id, :assignable_type, :operation]
compact true
rename assignable_type: :type
end

typed_struct do
field :id, :integer,
constraints: [min: 0],
description: "the id of the assigned thing"

field :type, :atom, description: "the type of the assigned thing"
field :assignable_type, :string, description: "the type of the assigned thing"

field :assignee_id, :uuid, description: "the id of the assignee Ash resource"

Expand Down
13 changes: 1 addition & 12 deletions lib/diffo/provider/components/base_instance.ex
Original file line number Diff line number Diff line change
Expand Up @@ -504,18 +504,7 @@ defmodule Diffo.Provider.BaseInstance do
end

calculations do
calculate :href,
:string,
expr(
type <>
"InventoryManagement/v" <>
specification.tmf_version <>
"/" <>
type <>
"/" <>
specification.name <>
"/" <> id
) do
calculate :href, :string, Diffo.Provider.Calculations.InstanceHref do
description "the inventory href of the service or resource instance"
end
end
Expand Down
32 changes: 32 additions & 0 deletions lib/diffo/provider/components/calculations/instance_href.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# SPDX-FileCopyrightText: 2025 diffo contributors <https://github.com/diffo-dev/diffo/graphs.contributors>
#
# SPDX-License-Identifier: MIT

defmodule Diffo.Provider.Calculations.InstanceHref do
@moduledoc """
Diffo - TMF Service and Resource Management with a difference

InstanceHref - Ash Resource Calculation for generating instance href

"""
use Ash.Resource.Calculation

@impl true
def load(_query, _opts, _context), do: [:specification]

@impl true
def calculate(records, _opts, _context) do
Enum.map(records, fn record ->
case record.specification do
%{tmf_version: tmf_version, type: :serviceSpecification} ->
"serviceInventoryManagement/v#{tmf_version}/service/#{record.id}"

%{tmf_version: tmf_version, type: :resourceSpecification} ->
"resourceInventoryManagement/v#{tmf_version}/resource/#{record.id}"

_ ->
nil
end
end)
end
end
31 changes: 31 additions & 0 deletions lib/diffo/provider/components/calculations/specification_href.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# SPDX-FileCopyrightText: 2025 diffo contributors <https://github.com/diffo-dev/diffo/graphs.contributors>
#
# SPDX-License-Identifier: MIT

defmodule Diffo.Provider.Calculations.SpecificationHref do
use Ash.Resource.Calculation

@moduledoc """
Diffo - TMF Service and Resource Management with a difference

SpecificationHref - Ash Resource Calculation for generating specification href

"""

@impl true
def load(_query, _opts, _context), do: [:type, :tmf_version, :id]

@impl true
def calculate(records, _opts, _context) do
Enum.map(records, fn
%{type: :serviceSpecification, tmf_version: tmf_version, id: id} ->
"serviceCatalogManagement/v#{tmf_version}/serviceSpecification/#{id}"

%{type: :resourceSpecification, tmf_version: tmf_version, id: id} ->
"resourceCatalogManagement/v#{tmf_version}/resourceSpecification/#{id}"

_ ->
nil
end)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: 2025 diffo contributors <https://github.com/diffo-dev/diffo/graphs.contributors>
#
# SPDX-License-Identifier: MIT

defmodule Diffo.Provider.Calculations.SpecificationInstanceType do
@moduledoc """
Diffo - TMF Service and Resource Management with a difference

SpecificationInstanceType - Ash Resource Calculation for generating the instance type a specification specifies

"""
use Ash.Resource.Calculation

@impl true
def load(_query, _opts, _context), do: [:type]

@impl true
def calculate(records, _opts, _context) do
Enum.map(records, fn record ->
case record.type do
:serviceSpecification -> :service
:resourceSpecification -> :resource
_ -> nil
end
end)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: 2025 diffo contributors <https://github.com/diffo-dev/diffo/graphs.contributors>
#
# SPDX-License-Identifier: MIT

defmodule Diffo.Provider.Calculations.SpecificationVersion do
@moduledoc """
Diffo - TMF Service and Resource Management with a difference

SpecificationVersion - Ash Resource Calculation for generating the version of a specification

"""
use Ash.Resource.Calculation

@impl true
def load(_query, _opts, _context), do: [:major_version, :minor_version, :patch_version]

@impl true
def calculate(records, _opts, _context) do
Enum.map(records, fn
%{major_version: maj, minor_version: min, patch_version: patch} ->
"v#{maj}.#{min}.#{patch}"

_ ->
nil
end)
end
end
Loading
Loading