From e3181feb18ec084a16f87c5e98b9c7f523ef234e Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Fri, 1 Aug 2025 16:32:44 +0200 Subject: [PATCH 01/14] First draft --- object_design.md | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 object_design.md diff --git a/object_design.md b/object_design.md new file mode 100644 index 0000000..1e2d8a4 --- /dev/null +++ b/object_design.md @@ -0,0 +1,89 @@ +# RFC: DCM API Object Design Guidelines + +**Feature Name:** DCM API Object Design Guidelines + +**Type:** feature + +**Start Date:** 2025-08-01 + +**Status:** Draft + +## Abstract +This document defines the conventions and principles for designing DCM API objects, both built-in and custom resources. + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/rfc2119/). + +## Motivation +DCM APIs evolve over time and must remain backward compatible while accommodating new features. A consistent design approach ensures: + +* Predictability for users +* Stability of contracts across versions +* Extensibility for new use cases without breaking existing ones + +## Terminology +* **Built-in Resource Definition**: A top-level DCM API object that is defined within the DCM project. +* **Custom Resource Definition**: An API object that is a user-defined extension of the DCM API. +* **Spec**: The desired state of the object. +* **Status**: The observed state of the object. +* **Metadata**: Common fields such as `name`, `namespace`, `labels`, `annotations`. + +## API Object Structure +### Top-Level Structure +All DCM API objects MUST include: + +* `apiVersion`: API group and version. +* `kind`: Resource kind name (PascalCase). +* `metadata`: Object metadata (name, namespace, labels, annotations). +* `spec`: Desired state (optional for read-only resources). +* `status`: Observed state (read-only, updated by controllers). + +### API version +* API versions MUST follow the DCM versioning convention: `v1alpha1`, `v1beta1`, `v1`. +* Breaking changes MUST only occur between major version bumps (e.g., `v1` → `v2`). +* Alpha versions MAY introduce breaking changes; Beta and GA versions MUST preserve compatibility. +* Deprecation MUST be announced at least two releases before removal. + +## Kind +* The `kind` MUST be a valid URI resolvable to the documentation of the oject itself. +* Resource names MUST be lowercase, plural, and in English. +* Field names MUST be in `camelCase`. +* Enumerated values MUST be in `PascalCase`. + +### Spec vs Status +* **Spec** MUST be declarative and idempotent. +* **Status** MUST be system-populated and reflect actual runtime state. +* **Spec** changes SHALL NOT directly mutate **Status**; controllers MUST mediate changes. + +## Validation and Defaulting +* All fields MUST be validated using OpenAPI v3 schema. +* Default values SHOULD be applied using defaulting mechanisms in the controller. +* Validation errors MUST be explicit and descriptive. + +## Extensibility +* Optional fields SHOULD be added in a backward-compatible way. +* New capabilities SHOULD be introduced as optional fields, feature gates, or separate resources. +* Labels and annotations MAY be used for opaque, non-critical extensions. This approach SHOULD be avoided, preferring the creation of new fields within the Resource Definition itself. +* Implementations MUST NOT embed arbitrary JSON in fields; structured schema SHALL be preferred. + +## Field Design Principles +* Fields MUST be consistent in naming and type across APIs. +* Boolean fields MUST be prefixed with verbs like `enable`, `allow`, `require`. +* Duration values MUST use standard time units (e.g., `30s`, `5m`). +* Lists SHALL be treated as sets, thus disregarding the order of the items. + +## Abstraction Level +* API objects MUST operate at an appropriate level of abstraction for their intended audience. +* User-facing APIs SHOULD abstract implementation details and expose only necessary configuration parameters. +* Low-level APIs MAY expose more granular configuration but MUST remain portable across different environments. +* APIs MUST avoid exposing internal controller logic or cluster-specific implementation details that could break portability. +* Resource Definitions SHOULD define clear boundaries of abstraction to avoid overloading users with unnecessary complexity. + +## API Evolution +* Fields MUST NOT be removed from GA APIs; they MAY be deprecated and ignored. +* Renamed fields MUST preserve compatibility via aliasing or conversion. +* Changes MUST be additive to preserve backward compatibility. + +## Security and Multi-Tenancy +* Sensitive fields MUST NOT appear in plain text in `status`. +* API access MUST be controlled via RBAC. +* Multi-tenant Resource Definition MUST isolate data per tenant. From d7b4102dbf5ea73e9b8b3b1ff504bcda8e1f6bde Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Wed, 13 Aug 2025 14:50:36 +0200 Subject: [PATCH 02/14] Try to use more standard naming --- object_design.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/object_design.md b/object_design.md index 1e2d8a4..c1bb511 100644 --- a/object_design.md +++ b/object_design.md @@ -1,6 +1,6 @@ -# RFC: DCM API Object Design Guidelines +# RFC: DCM Service Spec Design Guidelines -**Feature Name:** DCM API Object Design Guidelines +**Feature Name:** DCM Service Spec Design Guidelines **Type:** feature @@ -9,27 +9,27 @@ **Status:** Draft ## Abstract -This document defines the conventions and principles for designing DCM API objects, both built-in and custom resources. +This document defines the conventions and principles for designing DCM Service Specs, both built-in and custom resources. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/rfc2119/). ## Motivation -DCM APIs evolve over time and must remain backward compatible while accommodating new features. A consistent design approach ensures: +DCM Service Spec evolve over time and must remain backward compatible while accommodating new features. A consistent design approach ensures: * Predictability for users * Stability of contracts across versions * Extensibility for new use cases without breaking existing ones ## Terminology -* **Built-in Resource Definition**: A top-level DCM API object that is defined within the DCM project. -* **Custom Resource Definition**: An API object that is a user-defined extension of the DCM API. +* **Built-in Resource Definition**: A top-level DCM Service Spec that is defined within the DCM project. +* **Custom Resource Definition**: A Service Spec that is a user-defined extension of the DCM Service Specs. * **Spec**: The desired state of the object. * **Status**: The observed state of the object. * **Metadata**: Common fields such as `name`, `namespace`, `labels`, `annotations`. -## API Object Structure +## Service Spec Structure ### Top-Level Structure -All DCM API objects MUST include: +All DCM Service Specs MUST include: * `apiVersion`: API group and version. * `kind`: Resource kind name (PascalCase). @@ -66,7 +66,7 @@ All DCM API objects MUST include: * Implementations MUST NOT embed arbitrary JSON in fields; structured schema SHALL be preferred. ## Field Design Principles -* Fields MUST be consistent in naming and type across APIs. +* Fields MUST be consistent in naming and type across Specs. * Boolean fields MUST be prefixed with verbs like `enable`, `allow`, `require`. * Duration values MUST use standard time units (e.g., `30s`, `5m`). * Lists SHALL be treated as sets, thus disregarding the order of the items. From 41866be1997201025c16ca403008e0fac8fd3d71 Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Wed, 27 Aug 2025 15:26:10 +0200 Subject: [PATCH 03/14] Add first draft of the interoperabilityAPI --- api/interoperabilityAPI.yaml | 249 +++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 api/interoperabilityAPI.yaml diff --git a/api/interoperabilityAPI.yaml b/api/interoperabilityAPI.yaml new file mode 100644 index 0000000..5d04ace --- /dev/null +++ b/api/interoperabilityAPI.yaml @@ -0,0 +1,249 @@ +openapi: 3.0.4 +info: + title: DCM Interoperability API + description: |- + This API is used to define and manage the services provided by the Services Providers. + version: 0.0.1 +paths: + /service: + get: + tags: + - service + summary: List all services. + description: Returns a list of services. + operationId: getServices + responses: + '200': + description: successful operation + content: + application/yaml: + schema: + type: array + items: + $ref: '#/components/schemas/Service' + '400': + description: Invalid ID supplied + '404': + description: Service not found + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + security: + - api_key: [] + - servicestore_auth: + - write:services + - read:services + post: + tags: + - service + summary: Add a new service. + description: Add a new service to the catalog. + operationId: addService + requestBody: + description: Create a new service in the catalog + content: + application/yaml: + schema: + $ref: '#/components/schemas/Service' + required: true + responses: + '200': + description: Successful operation + content: + application/yaml: + schema: + $ref: '#/components/schemas/Service' + '400': + description: Invalid input + '422': + description: Validation exception + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + security: + - servicestore_auth: + - write:services + - read:services + /service/{serviceId}: + get: + tags: + - service + summary: Find service by ID. + description: Returns a single service. + operationId: getServiceById + parameters: + - name: serviceId + in: path + description: ID of service to return + required: true + schema: + type: string + format: uuid + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Service' + application/xml: + schema: + $ref: '#/components/schemas/Service' + '400': + description: Invalid ID supplied + '404': + description: Service not found + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + security: + - api_key: [] + - servicestore_auth: + - write:services + - read:services + post: + tags: + - service + summary: Updates a service in the store with form data. + description: Updates a service resource based on the form data. + operationId: updateServiceWithForm + parameters: + - name: serviceId + in: path + description: ID of service that needs to be updated + required: true + schema: + type: string + format: uuid + - name: name + in: query + description: Name of service that needs to be updated + schema: + type: string + - name: status + in: query + description: Status of service that needs to be updated + schema: + type: string + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Service' + application/xml: + schema: + $ref: '#/components/schemas/Service' + '400': + description: Invalid input + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + security: + - servicestore_auth: + - write:services + - read:services + delete: + tags: + - service + summary: Deletes a service. + description: Delete a service. + operationId: deleteService + parameters: + - name: api_key + in: header + description: '' + required: false + schema: + type: string + - name: serviceId + in: path + description: Service id to delete + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: Service deleted + '400': + description: Invalid service value + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + security: + - servicestore_auth: + - write:services + - read:services +components: + schemas: + Service: + required: + - name + - photoUrls + type: object + properties: + id: + type: string + format: uuid + apiVersion: + type: string + description: version of the service definition + kind: + type: string + description: resource kind name (PascalCase)) + spec: + type: object + description: openAPI object of the service specs object + status: + type: object + description: openAPI object of the service status object + Error: + type: object + properties: + code: + type: string + message: + type: string + required: + - code + - message + requestBodies: + Service: + description: Service object that needs to be added to the store + content: + application/json: + schema: + $ref: '#/components/schemas/Service' + application/xml: + schema: + $ref: '#/components/schemas/Service' + securitySchemes: + servicestore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: https://servicestore3.swagger.io/oauth/authorize + scopes: + "write:services": modify services in your account + "read:services": read your services + api_key: + type: apiKey + name: api_key + in: header From bd0c3963ca91114dc5a29bdfdd38dd2bbf4f5347 Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Wed, 1 Oct 2025 12:52:53 +0200 Subject: [PATCH 04/14] Improve Error structure --- api/interoperabilityAPI.yaml | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/api/interoperabilityAPI.yaml b/api/interoperabilityAPI.yaml index 5d04ace..e175a83 100644 --- a/api/interoperabilityAPI.yaml +++ b/api/interoperabilityAPI.yaml @@ -217,13 +217,23 @@ components: Error: type: object properties: - code: + type: type: string - message: + description: The error code identifying the type of error + title: type: string + description: A human-readable description of the generic problem + detail: + type: string + description: A human-readable explanation specific to this occurrence of the problem + instance: + type: string + format: uuid + description: A unique identifier for the specific occurrence of the problem required: - - code - - message + - type + - title + - instance requestBodies: Service: description: Service object that needs to be added to the store From c29a7aef0dc018593ab3314dac1c8662dee3cdaa Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Mon, 6 Oct 2025 15:57:15 +0200 Subject: [PATCH 05/14] Add GH AEP validation --- .github/workflows/openapi.yml | 20 ++++++++++++++++++++ api/.spectral.yaml | 2 ++ 2 files changed, 22 insertions(+) create mode 100644 .github/workflows/openapi.yml create mode 100644 api/.spectral.yaml diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml new file mode 100644 index 0000000..cc8fc54 --- /dev/null +++ b/.github/workflows/openapi.yml @@ -0,0 +1,20 @@ +--- +name: OpenAPI +on: # yamllint disable-line rule:truthy + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + check-aep-compliance: + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v4 + - name: Set up Go + uses: actions/setup-go@v5 + - name: Install Spectral + run: npm i @stoplight/spectral-cli -g + - name: Check that OpenAPI conforms to AEP guidelines + run: spectral lint api/.spectral.yaml api/*.yaml diff --git a/api/.spectral.yaml b/api/.spectral.yaml new file mode 100644 index 0000000..799442c --- /dev/null +++ b/api/.spectral.yaml @@ -0,0 +1,2 @@ +extends: + - https://raw.githubusercontent.com/aep-dev/aep-openapi-linter/main/spectral.yaml From 23ad84e97b85023ab412fb868cc04ef3003687ef Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Mon, 6 Oct 2025 16:02:09 +0200 Subject: [PATCH 06/14] Make it work for all branches and PRs --- .github/workflows/openapi.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml index cc8fc54..61b4df5 100644 --- a/.github/workflows/openapi.yml +++ b/.github/workflows/openapi.yml @@ -2,9 +2,7 @@ name: OpenAPI on: # yamllint disable-line rule:truthy push: - branches: [main] pull_request: - branches: [main] jobs: check-aep-compliance: From 529c212a1cdf2f548096f42072e4918db9fc1469 Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Mon, 6 Oct 2025 16:03:38 +0200 Subject: [PATCH 07/14] Fix commnad --- .github/workflows/openapi.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml index 61b4df5..ca85437 100644 --- a/.github/workflows/openapi.yml +++ b/.github/workflows/openapi.yml @@ -15,4 +15,4 @@ jobs: - name: Install Spectral run: npm i @stoplight/spectral-cli -g - name: Check that OpenAPI conforms to AEP guidelines - run: spectral lint api/.spectral.yaml api/*.yaml + run: spectral lint -r api/.spectral.yaml api/*.yaml From 2c2178026f073bca908bf0ac139d65d62df01db0 Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Mon, 6 Oct 2025 16:42:24 +0200 Subject: [PATCH 08/14] Improve AEP compatibility --- api/interoperabilityAPI.yaml | 38 ++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/api/interoperabilityAPI.yaml b/api/interoperabilityAPI.yaml index e175a83..4f7cbc2 100644 --- a/api/interoperabilityAPI.yaml +++ b/api/interoperabilityAPI.yaml @@ -11,16 +11,38 @@ paths: - service summary: List all services. description: Returns a list of services. - operationId: getServices + operationId: ListService + parameters: + - in: query + name: max_page_size + schema: + type: integer + - in: query + name: page_token + schema: + type: string + - in: query + name: skip + schema: + type: integer + - in: query + name: filter + schema: + type: string responses: '200': description: successful operation content: application/yaml: schema: - type: array - items: - $ref: '#/components/schemas/Service' + properties: + next_page_token: + type: string + results: + items: + $ref: '#/components/schemas/Service' + type: array + type: object '400': description: Invalid ID supplied '404': @@ -41,7 +63,7 @@ paths: - service summary: Add a new service. description: Add a new service to the catalog. - operationId: addService + operationId: CreateService requestBody: description: Create a new service in the catalog content: @@ -76,7 +98,7 @@ paths: - service summary: Find service by ID. description: Returns a single service. - operationId: getServiceById + operationId: GetService parameters: - name: serviceId in: path @@ -115,7 +137,7 @@ paths: - service summary: Updates a service in the store with form data. description: Updates a service resource based on the form data. - operationId: updateServiceWithForm + operationId: UpdateService parameters: - name: serviceId in: path @@ -161,7 +183,7 @@ paths: - service summary: Deletes a service. description: Delete a service. - operationId: deleteService + operationId: DeleteService parameters: - name: api_key in: header From db57e64c5e2cc67e08486583e9e0260eaf0eb864 Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Mon, 6 Oct 2025 16:56:38 +0200 Subject: [PATCH 09/14] Add x-aep-resource definiton --- api/interoperabilityAPI.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/api/interoperabilityAPI.yaml b/api/interoperabilityAPI.yaml index 4f7cbc2..228b6e9 100644 --- a/api/interoperabilityAPI.yaml +++ b/api/interoperabilityAPI.yaml @@ -220,6 +220,7 @@ components: - name - photoUrls type: object + x-aep-resource: true properties: id: type: string From 695969ec9ccf57d8bbf7244afa82c96d7b74f2cf Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Fri, 17 Oct 2025 12:53:48 +0200 Subject: [PATCH 10/14] Improve specs --- api/interoperabilityAPI.yaml | 179 ++++++++++++++++++----------------- 1 file changed, 93 insertions(+), 86 deletions(-) diff --git a/api/interoperabilityAPI.yaml b/api/interoperabilityAPI.yaml index 228b6e9..a2822c5 100644 --- a/api/interoperabilityAPI.yaml +++ b/api/interoperabilityAPI.yaml @@ -2,17 +2,23 @@ openapi: 3.0.4 info: title: DCM Interoperability API description: |- - This API is used to define and manage the services provided by the Services Providers. + This API is used to define and manage the resources provided by the Resources Providers. version: 0.0.1 paths: - /service: + /resource: get: tags: - - service - summary: List all services. - description: Returns a list of services. - operationId: ListService + - resource + summary: List all resources. + description: Returns a list of resources. + operationId: ListResource parameters: + - name: api_key + in: header + description: API key to identify the requester + required: true + schema: + type: string - in: query name: max_page_size schema: @@ -40,13 +46,9 @@ paths: type: string results: items: - $ref: '#/components/schemas/Service' + $ref: '#/components/schemas/Resource' type: array type: object - '400': - description: Invalid ID supplied - '404': - description: Service not found default: description: Unexpected error content: @@ -55,21 +57,27 @@ paths: $ref: "#/components/schemas/Error" security: - api_key: [] - - servicestore_auth: - - write:services - - read:services + - resourcestore_auth: + - read:resources post: tags: - - service - summary: Add a new service. - description: Add a new service to the catalog. - operationId: CreateService + - resource + summary: Add a new resource. + description: Add a new resource to the catalog. + operationId: CreateResource + parameters: + - name: api_key + in: header + description: API key to identify the requester + required: true + schema: + type: string requestBody: - description: Create a new service in the catalog + description: Create a new resource in the catalog content: application/yaml: schema: - $ref: '#/components/schemas/Service' + $ref: '#/components/schemas/Resource' required: true responses: '200': @@ -77,7 +85,7 @@ paths: content: application/yaml: schema: - $ref: '#/components/schemas/Service' + $ref: '#/components/schemas/Resource' '400': description: Invalid input '422': @@ -89,20 +97,25 @@ paths: schema: $ref: "#/components/schemas/Error" security: - - servicestore_auth: - - write:services - - read:services - /service/{serviceId}: + - resourcestore_auth: + - write:resources + /resource/{resourceId}: get: tags: - - service - summary: Find service by ID. - description: Returns a single service. - operationId: GetService + - resource + summary: Find resource by ID. + description: Returns a single resource. + operationId: GetResource parameters: - - name: serviceId + - name: api_key + in: header + description: API key to identify the requester + required: true + schema: + type: string + - name: resourceId in: path - description: ID of service to return + description: ID of resource to return required: true schema: type: string @@ -113,14 +126,14 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/Service' + $ref: '#/components/schemas/Resource' application/xml: schema: - $ref: '#/components/schemas/Service' + $ref: '#/components/schemas/Resource' '400': description: Invalid ID supplied '404': - description: Service not found + description: Resource not found default: description: Unexpected error content: @@ -129,43 +142,38 @@ paths: $ref: "#/components/schemas/Error" security: - api_key: [] - - servicestore_auth: - - write:services - - read:services - post: + - resourcestore_auth: + - read:resources + put: tags: - - service - summary: Updates a service in the store with form data. - description: Updates a service resource based on the form data. - operationId: UpdateService + - resource + summary: Updates a resource in the store with form data. + description: Updates a resource resource based on the form data. + operationId: UpdateResource parameters: - - name: serviceId - in: path - description: ID of service that needs to be updated + - name: api_key + in: header + description: API key to identify the requester required: true schema: type: string - format: uuid - - name: name - in: query - description: Name of service that needs to be updated - schema: - type: string - - name: status - in: query - description: Status of service that needs to be updated + - name: resourceId + in: path + description: ID of resource that needs to be updated + required: true schema: type: string + format: uuid responses: '200': description: successful operation content: application/json: schema: - $ref: '#/components/schemas/Service' + $ref: '#/components/schemas/Resource' application/xml: schema: - $ref: '#/components/schemas/Service' + $ref: '#/components/schemas/Resource' '400': description: Invalid input default: @@ -175,34 +183,34 @@ paths: schema: $ref: "#/components/schemas/Error" security: - - servicestore_auth: - - write:services - - read:services + - resourcestore_auth: + - write:resources + - read:resources delete: tags: - - service - summary: Deletes a service. - description: Delete a service. - operationId: DeleteService + - resource + summary: Deletes a resource. + description: Delete a resource. + operationId: DeleteResource parameters: - name: api_key in: header - description: '' - required: false + description: API key to identify the requester + required: true schema: type: string - - name: serviceId + - name: resourceId in: path - description: Service id to delete + description: ID of the resource to be deleted required: true schema: type: integer format: int64 responses: '200': - description: Service deleted + description: Resource deleted '400': - description: Invalid service value + description: Invalid resource value default: description: Unexpected error content: @@ -210,15 +218,14 @@ paths: schema: $ref: "#/components/schemas/Error" security: - - servicestore_auth: - - write:services - - read:services + - resourcestore_auth: + - write:resources + - read:resources components: schemas: - Service: + Resource: required: - - name - - photoUrls + - id type: object x-aep-resource: true properties: @@ -227,16 +234,16 @@ components: format: uuid apiVersion: type: string - description: version of the service definition + description: version of the resource definition kind: type: string description: resource kind name (PascalCase)) spec: type: object - description: openAPI object of the service specs object + description: openAPI object of the resource specs object status: type: object - description: openAPI object of the service status object + description: openAPI object of the resource status object Error: type: object properties: @@ -258,24 +265,24 @@ components: - title - instance requestBodies: - Service: - description: Service object that needs to be added to the store + Resource: + description: Resource object that needs to be added to the store content: application/json: schema: - $ref: '#/components/schemas/Service' + $ref: '#/components/schemas/Resource' application/xml: schema: - $ref: '#/components/schemas/Service' + $ref: '#/components/schemas/Resource' securitySchemes: - servicestore_auth: + resourcestore_auth: type: oauth2 flows: implicit: - authorizationUrl: https://servicestore3.swagger.io/oauth/authorize + authorizationUrl: https://resourcestore3.swagger.io/oauth/authorize scopes: - "write:services": modify services in your account - "read:services": read your services + "write:resources": modify resources in your account + "read:resources": read your resources api_key: type: apiKey name: api_key From bb4d0bbfd223387cc6524d436659312b9392f5f3 Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Wed, 22 Oct 2025 17:35:18 +0200 Subject: [PATCH 11/14] Api Key already defined --- api/interoperabilityAPI.yaml | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/api/interoperabilityAPI.yaml b/api/interoperabilityAPI.yaml index a2822c5..416d0db 100644 --- a/api/interoperabilityAPI.yaml +++ b/api/interoperabilityAPI.yaml @@ -13,12 +13,6 @@ paths: description: Returns a list of resources. operationId: ListResource parameters: - - name: api_key - in: header - description: API key to identify the requester - required: true - schema: - type: string - in: query name: max_page_size schema: @@ -65,13 +59,6 @@ paths: summary: Add a new resource. description: Add a new resource to the catalog. operationId: CreateResource - parameters: - - name: api_key - in: header - description: API key to identify the requester - required: true - schema: - type: string requestBody: description: Create a new resource in the catalog content: @@ -107,12 +94,6 @@ paths: description: Returns a single resource. operationId: GetResource parameters: - - name: api_key - in: header - description: API key to identify the requester - required: true - schema: - type: string - name: resourceId in: path description: ID of resource to return @@ -151,12 +132,6 @@ paths: description: Updates a resource resource based on the form data. operationId: UpdateResource parameters: - - name: api_key - in: header - description: API key to identify the requester - required: true - schema: - type: string - name: resourceId in: path description: ID of resource that needs to be updated @@ -193,12 +168,6 @@ paths: description: Delete a resource. operationId: DeleteResource parameters: - - name: api_key - in: header - description: API key to identify the requester - required: true - schema: - type: string - name: resourceId in: path description: ID of the resource to be deleted From 8b9841ef56205c63ff30dc8f01b3dc9b2782051e Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Wed, 22 Oct 2025 17:49:36 +0200 Subject: [PATCH 12/14] Fix request body? --- api/interoperabilityAPI.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/api/interoperabilityAPI.yaml b/api/interoperabilityAPI.yaml index 416d0db..9a55bd1 100644 --- a/api/interoperabilityAPI.yaml +++ b/api/interoperabilityAPI.yaml @@ -131,6 +131,14 @@ paths: summary: Updates a resource in the store with form data. description: Updates a resource resource based on the form data. operationId: UpdateResource + requestBody: + content: + 'application/json': + schema: + type: object + 'x-aep-resource': + singular: Resource + plural: Resources parameters: - name: resourceId in: path From ed4fec16b606394ffc2215c2284d82a5851d553f Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Wed, 22 Oct 2025 17:52:12 +0200 Subject: [PATCH 13/14] Fix operationId --- api/interoperabilityAPI.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/interoperabilityAPI.yaml b/api/interoperabilityAPI.yaml index 9a55bd1..1ba81d3 100644 --- a/api/interoperabilityAPI.yaml +++ b/api/interoperabilityAPI.yaml @@ -130,7 +130,7 @@ paths: - resource summary: Updates a resource in the store with form data. description: Updates a resource resource based on the form data. - operationId: UpdateResource + operationId: ApplyResourceUpdate requestBody: content: 'application/json': From 4d4d233187a31a0d3e7d2b204c482ae7246bb554 Mon Sep 17 00:00:00 2001 From: Fabio Alessandro Locati Date: Mon, 27 Oct 2025 15:50:33 +0100 Subject: [PATCH 14/14] Add the concept of multiple providers being associated with a single resource kind --- api/interoperabilityAPI.yaml | 275 +++++++++++++++++++++++++++++++++-- 1 file changed, 259 insertions(+), 16 deletions(-) diff --git a/api/interoperabilityAPI.yaml b/api/interoperabilityAPI.yaml index 1ba81d3..002dba0 100644 --- a/api/interoperabilityAPI.yaml +++ b/api/interoperabilityAPI.yaml @@ -86,21 +86,21 @@ paths: security: - resourcestore_auth: - write:resources - /resource/{resourceId}: + /resource/{resourceKind}: get: tags: - resource - summary: Find resource by ID. + summary: Find resource by Kind. description: Returns a single resource. operationId: GetResource parameters: - - name: resourceId + - name: resourceKind in: path - description: ID of resource to return + description: Kind of resource to return required: true schema: type: string - format: uuid + format: uri responses: '200': description: successful operation @@ -112,7 +112,7 @@ paths: schema: $ref: '#/components/schemas/Resource' '400': - description: Invalid ID supplied + description: Invalid Kind supplied '404': description: Resource not found default: @@ -140,13 +140,13 @@ paths: singular: Resource plural: Resources parameters: - - name: resourceId + - name: resourceKind in: path - description: ID of resource that needs to be updated + description: Kind of resource that needs to be updated required: true schema: type: string - format: uuid + format: uri responses: '200': description: successful operation @@ -176,13 +176,242 @@ paths: description: Delete a resource. operationId: DeleteResource parameters: - - name: resourceId + - name: resourceKind in: path - description: ID of the resource to be deleted + description: Kind of the resource to be deleted required: true + schema: + type: string + format: uri + responses: + '200': + description: Resource deleted + '400': + description: Invalid resource value + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + security: + - resourcestore_auth: + - write:resources + - read:resources + /resource/{resourceKind}/provider: + get: + tags: + - resource + summary: List all providers for a specific resource type. + description: Returns a list of providers. + operationId: ListProvider + parameters: + - name: resourceKind + in: path + description: Kind of resource to consider + required: true + schema: + type: string + format: uri + - in: query + name: max_page_size + schema: + type: integer + - in: query + name: page_token + schema: + type: string + - in: query + name: skip schema: type: integer - format: int64 + - in: query + name: filter + schema: + type: string + responses: + '200': + description: successful operation + content: + application/yaml: + schema: + properties: + next_page_token: + type: string + results: + items: + $ref: '#/components/schemas/Provider' + type: array + type: object + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + security: + - api_key: [] + - resourcestore_auth: + - read:providers + post: + tags: + - resource + summary: Add a new provider to a resource kind. + description: Add a new provider to a resource kind. + operationId: CreateProvider + parameters: + - name: resourceKind + in: path + description: Kind of resource to consider + required: true + schema: + type: string + format: uri + requestBody: + description: Create a new resource in the catalog + content: + application/yaml: + schema: + $ref: '#/components/schemas/Provider' + required: true + responses: + '200': + description: Successful operation + content: + application/yaml: + schema: + $ref: '#/components/schemas/Resource' + '400': + description: Invalid input + '422': + description: Validation exception + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + security: + - resourcestore_auth: + - write:providers + /resource/{resourceKind}/provider/{providerId}: + get: + tags: + - resource + summary: Find partner by ID from by Kind. + description: Returns a single resource. + operationId: GetResourceProvider + parameters: + - name: resourceKind + in: path + description: Kind of resource to consider + required: true + schema: + type: string + format: uri + - name: providerId + in: path + description: ID of the provider to consider + required: true + schema: + type: string + format: uurl + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Provider' + application/xml: + schema: + $ref: '#/components/schemas/Provider' + '400': + description: Invalid Kind supplied + '404': + description: Resource not found + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + security: + - api_key: [] + - resourcestore_auth: + - read:resources + put: + tags: + - resource + summary: Updates a provider for a resource in the store with form data. + description: Updates a provider for a resource in the store with form data. + operationId: ApplyResourceProviderUpdate + requestBody: + content: + 'application/json': + schema: + type: object + 'x-aep-resource': + singular: Resource + plural: Resources + parameters: + - name: resourceKind + in: path + description: Kind of resource to consider + required: true + schema: + type: string + format: uri + - name: providerId + in: path + description: ID of the provider to update + required: true + schema: + type: string + format: uurl + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Resource' + application/xml: + schema: + $ref: '#/components/schemas/Resource' + '400': + description: Invalid input + default: + description: Unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + security: + - resourcestore_auth: + - write:resources + - read:resources + delete: + tags: + - resource + summary: Deletes a resource provider. + description: Delete a resource provider. + operationId: DeleteResourceProvider + parameters: + - name: resourceKind + in: path + description: Kind of the resource to be deleted + required: true + schema: + type: string + format: uri + - name: providerId + in: path + description: ID of the provider to be deleted + required: true + schema: + type: string + format: uurl responses: '200': description: Resource deleted @@ -202,18 +431,18 @@ components: schemas: Resource: required: - - id + - apiVersion + - kind + - spec type: object x-aep-resource: true properties: - id: - type: string - format: uuid apiVersion: type: string description: version of the resource definition kind: type: string + format: uri description: resource kind name (PascalCase)) spec: type: object @@ -221,6 +450,20 @@ components: status: type: object description: openAPI object of the resource status object + Provider: + required: + - name + - id + type: object + x-aep-resource: true + properties: + name: + type: string + description: name of the provider + id: + type: string + format: uuid + description: provider's ID Error: type: object properties: