Current section

Files

Jump to
diffo lib diffo provider components specification.ex
Raw

lib/diffo/provider/components/specification.ex

# SPDX-FileCopyrightText: 2025 diffo contributors <https://github.com/diffo-dev/diffo/graphs.contributors>
#
# SPDX-License-Identifier: MIT
defmodule Diffo.Provider.Specification do
@moduledoc """
Diffo - TMF Service and Resource Management with a difference
Specification - Ash Resource for a TMF Service or Resource Specification
"""
require Ash.Resource.Change.Builtins
use Ash.Resource,
otp_app: :diffo,
domain: Diffo.Provider,
data_layer: AshNeo4j.DataLayer,
extensions: [AshOutstanding.Resource, AshJason.Resource]
resource do
description "An Ash Resource for a TMF Service or Resource Specification"
plural_name :specifications
end
neo4j do
guard [
{:SPECIFIED_BY, :incoming, :Instance}
]
end
jason do
pick [:id, :href, :name, :version]
end
outstanding do
expect [:name, :major_version]
end
actions do
defaults [:read, :destroy]
create :create do
description "creates a major version of a named serviceSpecification or resourceSpecification"
accept [:id, :type, :name, :major_version, :description, :category]
change load [:version, :href, :instance_type]
upsert? true
upsert_identity :unique_major_version_per_name
end
read :list do
description "lists all serviceSpecification and resourceSpecification"
end
read :find_by_name do
description "finds specifications by name"
get? false
argument :query, :ci_string do
description "Return only specifications with names including the given value."
end
filter expr(contains(name, ^arg(:query)))
end
read :find_by_category do
description "finds specifications by category"
get? false
argument :query, :ci_string do
description "Return only specifications with category including the given value."
end
prepare build(sort: [name: :asc])
filter expr(contains(category, ^arg(:query)))
end
read :get_latest do
description "gets the serviceSpecification or resourceSpecification by name with highest major version"
get? true
argument :query, :ci_string do
description "Return only specifications with names including the given value."
end
prepare build(limit: 1, sort: [major_version: :desc])
filter expr(contains(name, ^arg(:query)))
end
update :describe do
description "updates the description"
accept [:description]
end
update :categorise do
description "updates the category"
accept [:category]
end
update :next_minor do
description "increments the minor version and resets the patch version"
change increment(:minor_version)
change set_attribute(:patch_version, 0)
change load [:version, :href, :instance_type]
end
update :next_patch do
transaction? false
description "increments the patch version"
change increment(:patch_version)
change load [:version, :href, :instance_type]
end
end
attributes do
attribute :id, :uuid do
description "a uuid4, unique to a major version of this specification and common across all environments, generated by default"
primary_key? true
allow_nil? false
public? true
default &Diffo.Uuid.uuid4/0
end
attribute :type, :atom do
description "indicates whether a serviceSpecification or resourceSpecification, defaults serviceSpecification"
allow_nil? false
public? false
default :serviceSpecification
constraints one_of: [:serviceSpecification, :resourceSpecification]
end
attribute :name, :string do
description "the generic name of the service or resource specified by any version of this specification, e.g. adslAccess"
allow_nil? false
public? true
constraints match: ~r/^[a-z][a-zA-Z0-9]*$/
end
attribute :major_version, :integer do
description "the major version, defaults 1"
allow_nil? false
public? false
default 1
constraints min: 0
end
attribute :minor_version, :integer do
description "the minor version, defaults 0"
allow_nil? false
public? false
default 0
constraints min: 0
end
attribute :patch_version, :integer do
description "the patch version, defaults 0"
allow_nil? false
public? false
default 0
constraints min: 0
end
attribute :description, :string do
description "a description of the service or resource specified by a major version of this specification"
allow_nil? true
public? true
end
attribute :category, :string do
description "the category of the service or resource specified by a major version of this specification"
allow_nil? true
public? true
end
attribute :tmf_version, :integer do
description "the TMF version of the specified service or resource, e.g. v4"
allow_nil? false
public? false
default 4
constraints min: 1
end
create_timestamp :created_at
update_timestamp :updated_at
end
identities do
identity :unique_major_version_per_name, [:name, :major_version]
end
validations do
validate {Diffo.Validations.IsUuid4OrNil, attribute: :id}, on: :create
end
calculations do
calculate :version, :string, Diffo.Provider.Calculations.SpecificationVersion
calculate :href, :string, Diffo.Provider.Calculations.SpecificationHref
calculate :instance_type, :atom, Diffo.Provider.Calculations.SpecificationInstanceType
end
preparations do
prepare build(
load: [:version, :href, :instance_type],
sort: [name: :asc, major_version: :desc]
)
end
@doc """
Derives the catalog prefix from the type
## Examples
iex> Diffo.Provider.Specification.catalog(:serviceSpecification)
:serviceCatalogManagement
iex> Diffo.Provider.Specification.catalog(:resourceSpecification)
:resourceCatalogManagement
"""
def catalog(type) do
case type do
:serviceSpecification -> :serviceCatalogManagement
:resourceSpecification -> :resourceCatalogManagement
end
end
end