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.

{
    "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

  • 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. It changes only when the Context’s name or parent is changed (rename / reparent operations); the paths of all descendant Contexts change in the same atomic operation.

  • 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. Across live Contexts, a path string may be owned only once, either as a current path or as a retained previousPaths entry. Values do not expire automatically and can be replaced or cleared only through the tracked-update endpoint. A newly established current path—through creation, rename, reparent, or descendant recomputation—removes the same value from every retained set, while an explicit historical-path addition that conflicts with another live owner returns 409 Conflict. This field is not included in compact parent or children summaries.

  • state: The physical operational state of the Context, as configured locally by an administrator. Allowed values: active, suspended, created, deleted.

  • 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. It changes only when the Context’s own state or an ancestor’s state is changed; the effectiveState of all descendant Contexts changes in the same atomic operation. (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, cannot be used in a Context query (400 Bad Request in _emit as in a predicate), and is available only through the dedicated Context history endpoint. A Context can be created with fields other than these by IS-M and Infra-M, the only roles they are returned to; from any other role they are ignored and reported through X-Warning. They are stored as submitted, follow the listed properties in the representation, and cannot be changed afterwards, because a Tracked Update changes the tracked fields only.

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 declares cardinality-constrained ConsistsOf and target Facet pairings for its instances, and documents which other Resource types are expected to be related to it. Pairings omitted from the schema remain valid under the Open-World Assumption. ResourceSchema does not expose or accept a properties member: descriptive data belongs to Facet instances, while the Resource schema defines topology. Supplying properties, including an empty array, is an invalid Resource schema representation and returns 400 Bad Request.

{
    "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": [
        {
            "type": "LinkedEntity",
            "source": "EService",
            "relation": "IsIdentifiedBy",
            "target": "SoftwareFacet",
            "description": "The main software enabling the EService capabilities.",
            "min": 1,
            "max": 1
        },
        {
            "type": "LinkedEntity",
            "source": "EService",
            "relation": "ConsistsOf",
            "target": "AccessPointFacet",
            "description": "Identify the endpoints of the EService.",
            "min": 1
        }
    ],
    "isRelatedTo": [
        {
            "type": "LinkedEntity",
            "source": "EService",
            "relation": "Uses",
            "target": "EService",
            "description": "A reference to any other EService the EService instance is invoking.",
            "min": 0
        },
        {
            "type": "LinkedEntity",
            "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

  • 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. Both are mandatory. version has the form major.minor.patch and matches ^[1-9][0-9]*\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$; changelog maps each version to a non-empty description of its change, and version must be its highest entry. A definition that violates these rules returns 400 Bad Request.

  • 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: a PUT that would change it, and any DELETE, return 409 Conflict; an identical resubmission is the usual 200 OK no-op. The server assigns this field; a value supplied in a write payload is ignored and does not take part in the comparison.

  • 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.

  • consistsOf: Declares ConsistsOf Type and target Facet Type pairings whose cardinality (min/max) the backend enforces. A min: n means that at least \(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 \(m\) such instances can exist; an absent max means no upper bound, and min: 0, or an absent min, no lower one. min and max are non-negative integers: a negative value returns 400 Bad Request. Undeclared pairings remain valid under the Open-World Assumption and carry no schema cardinality constraint. Both consistsOf and isRelatedTo are always present, empty when the Type declares no pairing. Each of their elements has exactly these members: type (always LinkedEntity), source, relation, target, description, min, and max. (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: Documents IsRelatedTo Type and target Resource Type pairings linked to this Resource instance (including outbound and inbound relation signatures from the schema owner’s perspective), along with advisory cardinality (min/max). These declarations are not an allowlist: undeclared pairings remain valid. Unlike ConsistsOf constraints, IsRelatedTo cardinalities are purely advisory constraints (First-Class Documentation), never hard backend validation rules. Rigidly forcing the Infrastructure Topology would contradict the Open-World Extensibility Paradigm of the system. The dictated IsRelatedTo or Resource Type can be abstract; concrete subtypes remain structurally valid. For the polymorphic interpretation 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.

{
    "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": [
        {
            "type": "PropertyDefinition",
            "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"
        },
        {
            "type": "PropertyDefinition",
            "name": "name",
            "description": "The name of the software artifact being described, e.g., artifactId in maven coordinates...",
            "mandatory": true,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "type": "PropertyDefinition",
            "name": "version",
            "description": "The particular release of the software artifact, e.g., version in maven coordinates...",
            "mandatory": true,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "type": "PropertyDefinition",
            "name": "optional",
            "description": "Used to indicate the software optionality...",
            "mandatory": false,
            "readonly": false,
            "regexp": "",
            "propertyType": "Boolean"
        },
        {
            "type": "PropertyDefinition",
            "name": "qualifier",
            "description": "A qualifier for the software, e.g., packaging or scope in maven coordinates...",
            "mandatory": false,
            "readonly": false,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "type": "PropertyDefinition",
            "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. Each element is a property definition with exactly these members: type (always PropertyDefinition), name, description, mandatory, readonly, propertyType (e.g., String, Integer, or a complex ``Property`` Type), min, max, regexp, and defaultValue. Since a Type definition is closed, any other member returns 400 Bad Request. (Note on Constraints: a ``readonly`` field is set when the instance is created and cannot be changed afterwards: a ``PUT`` or ``PATCH`` that would change its value returns ``409 Conflict``. A ``mandatory`` field MUST be present with a non-``null`` value; when a full representation (``POST``, ``PUT``) omits it, the server sets it to the property’s declared ``defaultValue``, and rejects the request with ``409 Conflict`` when no ``defaultValue`` is declared. An optional one may be omitted. In a full representation (``POST``, ``PUT``) an explicit ``null`` means the same as an omitted field, at any depth, so no separate constraint on ``null`` exists; in a ``PATCH``, an omitted property is left unchanged and ``null`` removes it. An empty ``regexp`` means no pattern, and a non-empty one is satisfied when the pattern matches any part of the value (a pattern that must match the whole value is anchored with ``^`` and ``$``); an absent ``min`` or ``max`` means no bound). See [Elimination of notnull](12-is-architectural-decisions.md#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:

^[a-zA-Z][a-zA-Z0-9_-]*$

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).

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. System field names: type, supertypes, id, metadata, and contexts are reserved for system fields and cannot name a property; a Relation Type cannot redefine propagationConstraint. type in particular 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.

{
    "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.

{
    "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.

{
    "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": [
        {
            "type": "PropertyDefinition",
            "name": "who",
            "description": "WHO triggered the event.",
            "mandatory": false,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "type": "PropertyDefinition",
            "name": "what",
            "description": "WHAT happened.",
            "mandatory": true,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "type": "PropertyDefinition",
            "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"
        },
        {
            "type": "PropertyDefinition",
            "name": "where",
            "description": "The location (can be virtual) WHERE the event occurred.",
            "mandatory": false,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "type": "PropertyDefinition",
            "name": "why",
            "description": "The reason WHY the event occurred.",
            "mandatory": false,
            "readonly": true,
            "regexp": "",
            "propertyType": "String"
        },
        {
            "type": "PropertyDefinition",
            "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).