# Resource Registry — Data Representation (Schemas)

## Context Representation

Contexts represent isolated multi-tenant environments (Venn diagrams) within the infrastructure. They are structured hierarchically, which dictates boundaries for cascading configurations and instance sharing.

### Example: Context Hierarchy

The JSON representation of a single Context explicitly includes its hierarchy, encapsulating `parent` and `children` Contexts as nested objects. When requesting a specific **`HTTP resource`** for a Context, the system serializes these logical boundaries.

```json
{
    "type": "Context",
    "id": "4eb849d5-efbb-4430-9eb6-1968123921b4",
    "metadata": {
        "createdBy": "luca.frosini",
        "creationTime": "2025-02-24 14:46:39.330 +0000",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2025-02-24 14:46:39.330 +0000"
    },
    "name": "gcube",
    "path": "/gcube",
    "previousPaths": [],
    "state": "active",
    "effectiveState": "active",
    "parent": null,
    "children": [
        {
            "type": "Context",
            "id": "a7bc333f-84df-498d-ae9d-748b358267b5",
            "name": "devsec",
            "path": "/gcube/devsec",
            "state": "active",
            "effectiveState": "active"
        }
    ]
}
```

#### Field Explanations

```eval_rst
- ``type``: The literal string identifying the schema. In this case, **Context**.
- ``id``: The unique system-managed identifier for this specific Context. *(REST Profile Note: While the abstract IS-Model allows for implementation-specific ID formats, the REST API strictly mandates the use of UUIDs for all ``id`` fields to guarantee global uniqueness and predictable addressing across the federated graph).*
- ``metadata``: An embedded field of type **``Metadata``** handling provenance tracking. It contains:
  - ``createdBy`` (String): The principal who created the Context representation. *(Note: To comply with privacy policies, this field may be returned as ``"[REDACTED]"`` depending on the caller's authorization role).*
  - ``creationTime`` (Date): Creation time.
  - ``lastUpdateBy`` (String): The principal who last updated the instance. *(Note: To comply with privacy policies, this field may be returned as ``"[REDACTED]"`` depending on the caller's authorization role).*
  - ``lastUpdateTime`` (Date): Last Update time.
- ``name``: A simple string defining the descriptive name of the Context. Must consist of alphanumeric characters, dashes, underscores, and dots (matching pattern ``^(?!.*[._-]{2})[a-zA-Z0-9]([a-zA-Z0-9_.-]*[a-zA-Z0-9])?$``). It must start and end with an alphanumeric character, and cannot contain consecutive symbols (such as ``__``, ``--``, or ``..``). Special characters like ``/`` (slash) or spaces are strictly forbidden.
- ``path``: The absolute hierarchical path of the Context from the Root down to the current node (e.g., ``/gcube/devsec/devVRE``). Read-only — clients cannot set or modify this field. ``path`` is **not computed on the fly at read time**: it is **persistently stored** in the database and in the Redis cache. The system recomputes and persists it automatically whenever the Context's ``name`` or ``parent`` is changed (rename / reparent operations). All descendant Contexts are updated accordingly in the same database transaction.
- ``previousPaths``: The ordered set of former ``path`` values that still resolve to this Context. It is always present in a standard Context representation, including as an empty array. Values are unique, do not expire automatically, and can be replaced or cleared only through the tracked-update endpoint; path reuse during creation removes a colliding retained value. This field is not included in compact ``parent`` or ``children`` summaries.
- ``state``: The physical operational state of the Context (e.g., ``ACTIVE``, ``SUSPENDED``, ``CREATED``, ``DELETED``), as configured locally by an administrator.
- ``effectiveState``: A read-only field that reflects the true operational state of the Context by evaluating its ascendance. For example, ``effectiveState`` yields ``SUSPENDED`` if the local ``state`` is ``ACTIVE`` while an ancestor state is ``SUSPENDED``. Operations within the Context are strictly governed by this value. Like ``path``, ``effectiveState`` is **not computed on the fly at read time**: it is **persistently stored** in the database and in the Redis cache. The system recomputes and persists it automatically whenever the Context's own ``state`` or any ancestor's ``state`` is changed. All descendant Contexts are updated accordingly in the same database transaction. (See the *State Evaluation Matrix* in the [API Authorization Reference](08-api-contexts-and-types.md#inherited-operational-state-effectivestate) for all cases).
- ``parent``: If this Context is a child, it contains the nested representation of its parent Context. The root Context explicitly specifies ``null``. *(Note: To prevent infinite recursion and reduce payload bloat during serialization, nested Context representations within ``parent`` and ``children`` fields act as depth-limited summaries. These summaries are stripped down to the essential fields (``type``, ``id``, ``name``, ``path``, ``state``, ``effectiveState``), intentionally omitting their own ``parent`` and ``children`` fields as well as ``metadata`` and ``history``).*
- ``children``: An array of nested objects representing the immediate child Contexts. Leaf Contexts explicitly return an empty array. In this example, the ``gcube`` Context has a child ``devsec`` Context, forming the hierarchy.
```

Normal Context representations use the stable property order `type`, `id`, `metadata` (when requested), `name`, `path`, `previousPaths`, `state`, `effectiveState`, `parent`, `children`. The `history` property is never included in these representations and is available only through the dedicated Context history endpoint.

## Type Schema Representation (Self-Describing API)

Because the Information System exposes its own schema definitions, clients can dynamically discover how to interact with new instances without requiring out-of-band documentation. The IS-Model relies on 5 public extensible base Types: **Resource**, **Facet**, **IsRelatedTo**, **ConsistsOf**, and **`Property`**. 

The `type` field in the schema definition explicitly declares the structural category of the schema (e.g., `"type": "ResourceSchema"` indicates it defines the blueprint for a **Resource** instance, while `"type": "FacetSchema"` indicates it defines a **Facet** instance). The actual inheritance lineage is declared separately via the `extendedTypes` array.

### Resource Type Schema

A **Resource** schema dictates the allowed **ConsistsOf** types and the target **Facet** types for its instances, and which other **Resource** types can be related to it.

```json
{
    "type": "ResourceSchema",
    "id": "e5680fc8-5590-41ab-9d3f-b7e1556d1338",
    "metadata": {
        "createdBy": "luca.frosini",
        "creationTime": "2025-02-24 14:23:26.890 +0000",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2025-02-24 14:23:26.890 +0000"
    },
    "name": "EService",
    "description": "EService is any running service that is registered in the infrastructure...",
    "version": "1.0.0",
    "changelog": { "1.0.0": "First Version" },
    "abstract": false,
    "final": false,
    "extendedTypes": ["Service"],
    "consistsOf": [
        {
            "source": "EService",
            "relation": "IsIdentifiedBy",
            "target": "SoftwareFacet",
            "description": "The main software enabling the EService capabilities.",
            "min": 1,
            "max": 1
        },
        {
            "source": "EService",
            "relation": "ConsistsOf",
            "target": "AccessPointFacet",
            "description": "Identify the endpoints of the EService.",
            "min": 1
        }
    ],
    "isRelatedTo": [
        {
            "source": "EService",
            "relation": "Uses",
            "target": "EService",
            "description": "A reference to any other EService the EService instance is invoking.",
            "min": 0
        },
        {
            "source": "HostingNode",
            "relation": "Hosts",
            "target": "EService",
            "description": "An advisory constraint: EServices running inside a SmartGears container should be hosted by 1 and only one HostingNode. Since not all EServices are deployed in this manner, this is treated as an advisory guideline.",
            "min": 1,
            "max": 1
        }
    ]
}
```

#### Field Explanations

```eval_rst
- ``type``: Declares the schema category. ``"ResourceSchema"`` means this schema defines a **Resource**.
- ``id``: The unique identifier for this schema definition.
- ``metadata``: Provenance and tracking metadata for the schema itself.
- ``name``: The formal name of the Type (e.g., **EService**).
- ``description``: The human-readable description of what this Type represents.
- ``version`` & ``changelog``: Track the evolutionary history of the schema.
- ``abstract``: If ``true``, you cannot create a direct instance of this Type (it only exists to be inherited from). If ``false`` (like **EService**), concrete instances can be created. *(Note: A Type cannot be simultaneously ``abstract: true`` and ``final: true``).*
- ``final``: If ``true``, this Type cannot be further extended by other Types.
- ``locked``: If ``true``, this Type belongs to the Information System model itself and its definition is served read-only: ``PUT`` and ``DELETE`` on it return ``409 Conflict``. The server assigns this field; a value supplied in a write payload is ignored.
- ``extendedTypes``: A list of the **direct** parent Types this schema inherits from (e.g., **EService** directly extends **Service**). Through polymorphism, the defined Type inherits all structural constraints of its direct parents, which in turn transitively inherit the constraints of all their ancestors.
- ``properties``: The fields this Type declares; a subtype declares only its own and inherits the rest. The descriptive data of a **Resource** lives in its **Facet**s, reached through ``consistsOf``.
- ``consistsOf``: Dictates the allowed pairing of **ConsistsOf** types and target **Facet** types, along with their cardinality (``min``/``max``). A ``min: n`` means that at least :math:`n` concrete **ConsistsOf** instances (of the specified Type or its subtypes) pointing to **Facet** instances (of the specified Type or its subtypes) must necessarily exist on the **Resource** instance. Conversely, ``max: m`` enforces that at most :math:`m` such instances can exist; an absent ``max`` means no upper bound, and ``min: 0`` no lower one. Both ``consistsOf`` and ``isRelatedTo`` are always present, empty when the Type declares no pairing. *(Note: The dictated **ConsistsOf** or **Facet** Type can be an abstract Type. Thanks to polymorphism, this simply means any concrete instance of their subtypes is structurally valid).* For the strict polymorphic evaluation rules of these pairings, see [Resource Structural Cardinality](03-is-model-core-topology.md#resource-structural-cardinality).
- ``isRelatedTo``: Dictates the allowed pairing of **IsRelatedTo** types and target **Resource** types linked to this **Resource** instance (explicitly documenting both outbound and inbound relation signatures from the schema owner's perspective), along with their advisory cardinality (``min``/``max``). *(Note: Unlike **ConsistsOf** constraints, **IsRelatedTo** cardinalities (``min`` and ``max``) are explicitly treated as purely **advisory constraints** (First-Class Documentation) rather than hard backend validation rules. Rigidly forcing the Infrastructure Topology would contradict the Open-World Extensibility Paradigm of the system. These fields exist to document the intended business logic to client applications).* The dictated **IsRelatedTo** or **Resource** Type can be an abstract Type. Thanks to polymorphism, this simply means any concrete instance of their subtypes is structurally valid. For the strict polymorphic evaluation rules of these pairings, see [Resource Structural Cardinality](03-is-model-core-topology.md#resource-structural-cardinality).
  - > **Architectural Note on Dual Perspective Cardinality:** The ``min`` and ``max`` constraints in ``isRelatedTo`` evaluate cardinality from the perspective of the schema owner. In the example above (defined within the **EService** schema), ``min: 1`` and ``max: 1`` mean that *this* specific **EService** instance should have exactly one **Hosts** relation pointing to it from a **HostingNode**. Conversely, the schema definition for **HostingNode** would contain the exact same topological signature, but its cardinalities would be evaluated from its own perspective (e.g., ``min: 1`` and no ``max``), meaning a single **HostingNode** can host an unlimited number of **EService** instances, and it is advised to host at least one (since an empty node serves no business purpose).
```

### Facet Type Schema

A **Facet** schema defines a data structure by specifying a set of custom fields (either primitive fields or complex **`Property`** types) that characterize an aspect of a **Resource** instance.

```json
{
    "type": "FacetSchema",
    "id": "0c0ebac7-ee9b-4325-bedd-c89ff52e6cf2",
    "metadata": {
        "createdBy": "luca.frosini",
        "creationTime": "2025-02-24 14:20:56.606 +0000",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2025-02-24 14:20:56.606 +0000"
    },
    "name": "SoftwareFacet",
    "description": "SoftwareFacet captures information on any software associated with the resource.",
    "version": "1.0.0",
    "changelog": { "1.0.0": "First Version" },
    "abstract": false,
    "final": false,
    "extendedTypes": ["Facet"],
    "properties": [
        {
            "name": "group",
            "description": "The name of 'group' the software artifact belongs to, e.g., groupId in maven coordinates...",
            "mandatory": true,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "name",
            "description": "The name of the software artifact being described, e.g., artifactId in maven coordinates...",
            "mandatory": true,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "version",
            "description": "The particular release of the software artifact, e.g., version in maven coordinates...",
            "mandatory": true,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "optional",
            "description": "Used to indicate the software optionality...",
            "mandatory": false,
            "readonly": false,
            "regexp": "",
            "propertyType": "Boolean"
        },
        {
            "name": "qualifier",
            "description": "A qualifier for the software, e.g., packaging or scope in maven coordinates...",
            "mandatory": false,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "description",
            "description": "A human oriented description of the software artifact being described.",
            "mandatory": false,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        }
    ]
}
```

#### Field Explanations

- `type`: Declares the schema category. `"FacetSchema"` means this schema defines a **Facet** Type.
- `name`, `description`, `version`, `changelog`, `abstract`, `final`, `locked`, `extendedTypes`: Standard schema fields sharing identical semantics with the **Resource** schema.
- `properties`: An array defining the exact structural requirements for the data fields that a **Facet** instance of this Type will hold. It dictates field names, descriptions, constraints (like `mandatory`, `readonly`, `regexp`, `min`/`max`), and the exact `propertyType` (e.g., `String`, `Integer`, or a complex **`Property`** Type). *(Note on Constraints: a `mandatory` field MUST be present with a non-`null` value; an optional one may be omitted. An explicit `null` means the same as an omitted field, at any depth, so no separate constraint on `null` exists. An empty `regexp` means no pattern; an absent `min` or `max` means no bound. A `notnull` in a submitted definition is ignored).* See [Elimination of `notnull`](12-is-architectural-decisions.html#elimination-of-notnull-as-an-independent-property-constraint).

#### Property Naming Constraints (Normative)

To ensure robust parsing, prevent HTTP Header Injection vulnerabilities (such as when rendering `X-Warning` headers), and avoid namespace collisions with internal query semantics, the names of all properties (whether statically declared in the schema via the `properties` array or dynamically injected via Schema-Mixed Mode) **MUST strictly adhere to the following regular expression:**

```regex
^[a-zA-Z][a-zA-Z0-9_-]*$
```
```eval_rst
In plain English, this dictates that:
- The **first character** must always be an unaccented ASCII letter (uppercase ``A-Z`` or lowercase ``a-z``).
- **Subsequent characters** can be unaccented ASCII letters, digits (``0-9``), underscores (``_``), or hyphens (``-``).
- *(Note: The ``^`` and \$ symbols in the expression above are standard regex anchors representing the strict start and end of the string, they are not allowed characters within the name itself).*
```

```eval_rst
By establishing this pattern, this universal rule explicitly forbids:
1. **System/Query prefixes:** Property names starting with ``@`` or ``_``.
2. **Special/Unicode characters:** Blank spaces, accented letters (e.g., ``à``, ``è``), or currency symbols (e.g., ``€``, \$).
3. **Delimiter/Control characters:** Characters such as ``\r``, ``\n``, ``,``, ``;``, ``=``, or ``"``.
4. **The ``"type"`` keyword:** The exact string ``"type"`` is globally reserved by the system. In a dynamic and hierarchical model, this field is fundamentally required to recognize the exact schema type of an object. This explicit recognition subsequently enables polymorphic deserialization and dynamic class instantiation. It is strictly forbidden to use it as a custom property name anywhere in the payload.
```

Property names that violate these constraints are not valid IS-Model fields. Any attempt to register a new Type Schema defining an invalid property name will be strictly rejected with a `400 Bad Request`. *(Note: The behavior when encountering invalid property names dynamically injected into instances is governed by the lenient payload processing rules detailed in the REST API Foundations chapter).*

### IsRelatedTo Type Schema

An **IsRelatedTo** schema dictates the exact allowed source **Resource** type and target **Resource** type for its **Relation** instances.

```json
{
    "type": "IsRelatedToSchema",
    "id": "bc8e6b37-5c90-4bcf-be89-3db3792b168b",
    "metadata": {
        "createdBy": "luca.frosini",
        "creationTime": "2025-02-24 14:24:13.041 +0000",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2025-02-24 14:24:13.041 +0000"
    },
    "name": "Uses",
    "description": "The Uses relation indicates that the source EService invokes the target EService. It specializes the semantics of CallsFor.",
    "version": "1.0.0",
    "changelog": { "1.0.0": "First Version" },
    "abstract": false,
    "final": false,
    "extendedTypes": [ "CallsFor" ],
    "source": "EService",
    "target": "EService",
    "properties": []
}
```

#### Field Explanations

- `type`: Declares the schema category. `"IsRelatedToSchema"` means this schema defines an **IsRelatedTo** Type.
- `name`, `description`, `version`, `changelog`, `abstract`, `final`, `locked`, `extendedTypes`: Standard schema fields.
- `source`: Strictly dictates the allowed Type for the **Resource** instance acting as the source.
- `target`: Strictly dictates the allowed Type for the **Resource** instance acting as the target.
- `properties`: An array defining any custom property fields associated with **IsRelatedTo** instances of this Type (using the same strict structure and constraints as the `properties` array in a **Facet** or **`Property`** schema).

### ConsistsOf Type Schema

A **ConsistsOf** schema dictates the allowed source **Resource** type and target **Facet** type for its **Relation** instances.

```json
{
    "type": "ConsistsOfSchema",
    "id": "fda4eb23-0d84-4364-a976-8ff0565043f0",
    "metadata": {
        "createdBy": "luca.frosini",
        "creationTime": "2025-02-24 14:24:53.292 +0000",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2025-02-24 14:24:53.292 +0000"
    },
    "name": "HasContact",
    "description": "HasContact is a base relation type to capture the diverse points of contact associated with a resource.",
    "version": "1.0.0",
    "changelog": { "1.0.0": "First Version" },
    "abstract": true,
    "final": false,
    "extendedTypes": ["ConsistsOf"],
    "source": "Resource",
    "target": "ContactFacet",
    "properties": []
}
```

#### Field Explanations

- `type`: Declares the schema category. `"ConsistsOfSchema"` means this schema defines a **ConsistsOf** Type.
- `name`, `description`, `version`, `changelog`, `abstract`, `final`, `locked`, `extendedTypes`: Standard schema fields.
- `source`: Dictates the allowed **Resource** type.
- `target`: Dictates the allowed **Facet** type that can be attached.
- `properties`: An array defining any custom property fields associated with **ConsistsOf** instances of this Type (using the same strict structure and constraints as the `properties` array in a **Facet** or **`Property`** schema).

### Property Type Schema

A **`Property`** schema defines a complex data structure that can be embedded directly within a **Facet** instance or **Relation** instance. It does not have an independent graph ID.

```json
{
    "type": "PropertySchema",
    "id": "369e3c7f-b490-43b9-b924-c13aad63bf77",
    "metadata": {
        "createdBy": "luca.frosini",
        "creationTime": "2025-02-24 14:19:38.008 +0000",
        "lastUpdateBy": "luca.frosini",
        "lastUpdateTime": "2025-02-24 14:19:38.008 +0000"
    },
    "name": "Event",
    "description": "This type provides information regarding an event using the Five Ws (checklist) https://en.wikipedia.org/wiki/Five_Ws + How",
    "version": "1.0.0",
    "changelog": { "1.0.0": "First Version" },
    "abstract": false,
    "final": false,
    "extendedTypes": ["Property"],
    "properties": [
        {
            "name": "who",
            "description": "WHO triggered the event.",
            "mandatory": false,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "what",
            "description": "WHAT happened.",
            "mandatory": true,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "when",
            "description": "WHEN the event occurred. It is represented in the format yyyy-MM-dd HH:mm:ss.SSS Z.",
            "mandatory": true,
            "readonly": true,
            "regexp": "",
            "propertyType": "Date"
        },
        {
            "name": "where",
            "description": "The location (can be virtual) WHERE the event occurred.",
            "mandatory": false,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "why",
            "description": "The reason WHY the event occurred.",
            "mandatory": false,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "name": "how",
            "description": "How the event occurred.",
            "mandatory": false,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        }
    ]
}
```

#### Field Explanations

- `type`: Declares the schema category. `"PropertySchema"` means this schema defines a **Property** block.
- `name`, `description`, `version`, `changelog`, `abstract`, `final`, `locked`, `extendedTypes`: Standard schema fields.
- `properties`: Defines the specific nested fields (e.g., `who`, `what`, `when`, `where`, `why` and `how`) that compose this reusable complex block (like **`Event`**).
