Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ For a roadmap including expected timeline, please refer to [ROADMAP.md](./ROADMA

## [unreleased]

### Added

- Added **Push Transport** mode documentation and schema support
- Push transport allows ORD providers to push ORD documents directly to aggregators via HTTP POST
- Introduced `definitions` property on ORD Document for embedding resource definitions inline
- The key is the URL path (matching `resourceDefinitions[].url`), the value is the raw content as a string
- Content is treated as an opaque text blob, preserving original formatting for all formats (OpenAPI, AsyncAPI, WSDL, etc.)
- Added `embedded` access strategy type for resource definitions that are inline rather than fetched
- Added [embedded access strategy documentation](docs/spec-extensions/access-strategies/embedded.md)
- Added [push transport example document](examples/documents/document-push-transport.json)
- Added draft proposal for [Aggregator Configuration](docs/spec-v1/concepts/aggregator-configuration.md) including validation results endpoint concept

## [1.14.0]

### Added
Expand Down
95 changes: 95 additions & 0 deletions docs/spec-extensions/access-strategies/embedded.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
title: Embedded Access Strategy
description: Resource definition is embedded inline in the ORD document (push transport).
sidebar_position: 1
---

# Embedded Access Strategy

> **Status**: Draft Proposal (WIP)
>
> This access strategy is part of the [Push Transport](../../spec-v1/index.md#push-transport) proposal.

## Description

The `embedded` access strategy indicates that the resource definition content is provided inline within the ORD document itself, rather than being fetched from an external URL.

This is specifically designed for [push transport](../../spec-v1/index.md#push-transport) scenarios where:

- The ORD provider pushes the complete ORD document including all resource definitions to an aggregator
- The aggregator does not need to make additional requests to fetch resource definitions
- All metadata is self-contained in a single push request

The `accessStrategy`.`type` value for it is: `embedded`.

## How It Works

When a `resourceDefinition` uses the `embedded` access strategy:

1. The `url` field still contains the logical path/identifier for the resource definition
2. The actual content is provided in the document-level `definitions` property
3. The `url` value is used as the key to look up the content in `definitions`

### Example

```json
{
"openResourceDiscovery": "1.15",
"apiResources": [
{
"ordId": "sap.foo:apiResource:myApi:v1",
"resourceDefinitions": [
{
"type": "openapi-v3",
"mediaType": "application/json",
"url": "/api/my-api/openapi.json",
"accessStrategies": [
{
"type": "embedded"
}
]
}
]
}
],
"definitions": {
"/api/my-api/openapi.json": "{\"openapi\":\"3.0.0\",\"info\":{\"title\":\"My API\",\"version\":\"1.0.0\"},\"paths\":{}}"
}
}
```

## Provider Implementation

The ORD provider MUST:

- Set `accessStrategies[].type` to `embedded` for any resource definition whose content is included inline
- Include the resource definition content in the top-level `definitions` property
- Use the same URL path as the key in `definitions` that is referenced in `resourceDefinitions[].url`
- Encode the content as a string (preserving original formatting)

## Aggregator / Consumer Implementation

The ORD aggregator or consumer MUST:

- Recognize `embedded` as an access strategy type
- Look up the content in the `definitions` property using the `url` as the key
- NOT attempt to fetch the URL externally when `embedded` is specified
- Parse the string content according to the `mediaType` specified

## When to Use

Use the `embedded` access strategy when:

- Pushing ORD documents to an aggregator (push transport)
- Integrating ORD publishing into CI/CD pipelines
- The provider cannot or does not want to host resource definitions at accessible URLs
- You want to ensure atomic updates of metadata and definitions together

## Comparison with `open`

| Aspect | `open` | `embedded` |
|--------|--------|------------|
| Content location | External URL | Inline in document |
| Fetch required | Yes | No |
| Transport mode | Pull | Push |
| Self-contained | No | Yes |
191 changes: 183 additions & 8 deletions docs/spec-v1/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,18 +193,193 @@ Manual import of the [ORD document](#ord-document) as a JSON file into an intere
- The ORD document alone is sufficient for this type of consumption
- All URLs in the document MUST be resolvable (e.g. through `baseUrl` or full URLs)

#### Push Transport
### Push Transport

In push transport mode, [ORD information](#ord-information) is pushed directly to an [ORD aggregator](#ord-aggregator) via HTTP POST requests.
This mode eliminates the need for an [ORD Provider](#ord-provider) to implement the [ORD Provider API](#ord-provider-api) with its configuration and document endpoints.

Push transport is particularly suitable for:

- Static metadata that is known at design-time or deploy-time
- CI/CD pipeline integration where metadata is pushed as part of the build/deployment process
- Providers that cannot or prefer not to host a runtime ORD Provider API

##### Push Transport - Pros

- No need to implement and host an ORD Provider API (simpler provider implementation)
- Can be integrated into CI/CD pipelines (design-time or deploy-time)
- Changes are pushed immediately when they occur (no polling delay)
Comment thread
Fannon marked this conversation as resolved.
Outdated
- Direct feedback channel for validation errors from the aggregator: validation issues can be returned as part of the push response, making it easier for providers to detect and fix problems immediately (compared to pull where issues may go unnoticed)
- More efficient for tenant-specific (system-instance-aware) metadata: the provider knows exactly when changes occur and can push updates selectively, avoiding the need for aggregators to poll all tenants repeatedly

##### Push Transport - Cons

- Every provider needs to know where to push (aggregator endpoint must be known)
- Provider must actively push updates (compared to passive pull)
- Additional authentication/authorization setup between provider and aggregator
- Centralized approach (aggregator must be available to receive pushes)

##### Push Transport Implementation

###### ORD Push Document

For push transport, the standard [ORD document](#ord-document) format is used with one addition: a `definitions` property that allows inline [resource definitions](#resource-definition).

When using pull transport, resource definitions are referenced via URLs and fetched separately by the aggregator.
In push transport, these definitions can be provided inline within the ORD document itself using the `definitions` property.

When embedding definitions, the resource definition's access strategy SHOULD be set to [`embedded`](../spec-extensions/access-strategies/embedded.md) to explicitly indicate that the content is inline rather than fetched from a URL.

The `definitions` property is a dictionary where:
- The **key** is the URL path (as referenced by resources via `resourceDefinitions[].url`)
- The **value** is the raw content of the resource definition as a **string**

The content is treated as an opaque text blob, preserving original formatting and whitespace.
This works uniformly for all definition formats (OpenAPI JSON/YAML, AsyncAPI, WSDL, JSON Schema, etc.).

This enables the aggregator to correlate inline definitions with the resources that reference them, keeping all metadata self-contained in a single push request.

Example structure:
```json
{
"openResourceDiscovery": "1.14",
"describedSystemInstance": {
"baseUrl": "https://example.com"
},
"apiResources": [
{
"ordId": "sap.example:apiResource:my-api:v1",
"resourceDefinitions": [
{
"type": "openapi-v3",
"url": "/api/my-api/openapi.json",
"mediaType": "application/json",
"accessStrategies": [
{ "type": "embedded" }
]
}
]
}
],
"definitions": {
"/api/my-api/openapi.json": "{\"openapi\":\"3.0.0\",\"info\":{\"title\":\"My API\",\"version\":\"1.0.0\"}}"
}
}
```

> 🚧 The specification currently does not cover this mode.
###### ORD Aggregator Push API

An [ORD aggregator](#ord-aggregator) that supports push transport MUST provide a dedicated push API endpoint for receiving ORD documents.

<!-- The aggregator MAY advertise its push API capabilities via its own ORD configuration endpoint at `/.well-known/open-resource-discovery`.
The aggregator configuration MAY include:
- The URL of the push API endpoint
- Supported access strategies for authenticating providers
- Description and documentation links for onboarding

> For a more detailed draft proposal of the aggregator configuration schema, see [Aggregator Configuration (Draft)](./concepts/aggregator-configuration.md).
Comment thread
Fannon marked this conversation as resolved.
Outdated

Example aggregator configuration:
```json
{
"openResourceDiscoveryAggregator": {
"supportedVersions": ["1.14", "1.15"],
"supportedTransportModes": {
"push": {
"publishDocumentEndpoint": "/ord-publishing-api/v1/documents",
"validationResultsEndpoint": "/ord-publishing-api/v1/validationResults",
"accessStrategies": [
{
"type": "sap:oauth-client-credentials:v1",
"description": "Contact ord-support@example.com to request push credentials.",
"documentationLink": "https://help.example.com/ord/push-onboarding"
}
]
}
}
}
}
``` -->

###### Push API Contract

The push API endpoint MUST:
- Accept HTTP `POST` requests with `Content-Type: application/json`
- Expect the request body to be a valid [ORD document](#ord-document)
- Support the `definitions` property for inline resource definitions
- Return appropriate HTTP status codes:
- `200 OK` or `201 Created` on success
- `400 Bad Request` for any client error (malformed JSON, invalid ORD document, validation failures). Details SHOULD be provided in the response body.
- `401 Unauthorized` or `403 Forbidden` for authentication/authorization failures
- **TODO**: The exact response format for validation errors is not yet formally specified, it's up to the aggregator to define it.

Example request:
```http
POST /ord/v1/push HTTP/1.1
Host: aggregator.example.com
Content-Type: application/json
Authorization: Bearer <token>

{
"openResourceDiscovery": "1.14",
"describedSystemInstance": { ... },
"apiResources": [ ... ],
"definitions": { ... }
}
```

###### Validation Results Endpoint (Draft)

> **Status**: Draft Proposal - See [Aggregator Configuration (Draft)](./concepts/aggregator-configuration.md) for details.

Some validations can only be performed after the aggregator has processed multiple documents (e.g., cross-document reference checks, namespace consistency).
To support deferred validation feedback, aggregators MAY provide a validation results endpoint where providers can retrieve errors, warnings, and info messages.

This enables:
- Async validation that doesn't block the push request
- Aggregated feedback across multiple pushed documents
- Scoped queries by namespace or package

###### Provider Authorization

The aggregator MUST ensure that providers can only push content they are authorized to manage.
Authorization rules depend on the aggregator implementation but typically include:
- Validating that the provider is allowed to describe the claimed [system instance](#system-instance), e.g. by verifying ownership of the `baseUrl` and/or other identifiers in the ORD document
- Validating that the provider owns the [namespaces](#namespace) used in the pushed ORD IDs
- Validating that the push credentials match the expected provider identity

###### Push Transport Sequence Diagram

```mermaid
sequenceDiagram
participant Provider as ORD Provider
participant CI as CI/CD Pipeline
participant Aggregator as ORD Aggregator

Provider->>CI: Trigger build/deployment
CI->>CI: Generate ORD document with inline definitions
CI->>Aggregator: POST ORD document (using access strategy)
Aggregator->>Aggregator: Validate document and authorization
Aggregator-->>CI: Response (success/errors)

opt On validation errors
CI->>CI: Handle errors, notify developers
end
```

The Document can be pushed to the interested ORD aggregator, e.g. via a webhook, a known HTTP POST endpoint, or via file upload.
#### Other Modes of Transport

- Every system instance needs to know where the ORD documents need to be pushed to.
- An ORD aggregator might provide a dedicated HTTP POST endpoint for this.
- Changes can be pushed faster and more efficiently compared to the [pull transport](#pull-transport).
- The specification currently does not cover this mode.
Other modes of transport have not yet been standardized/specified.
They are only listed here to outline potential modes that we anticipate.

##### Import Transport

Manual import of the [ORD document](#ord-document) as a JSON file into an interested system or tool (offline mode):

- The system instances do not need to know each other or be integrated in any way
- The ORD document alone is sufficient for this type of consumption, it should include all necessary information and definitions inline (via the `definitions` property as described in the push transport section)

#### Event-Driven Transport
##### Event-Driven Transport

> 🚧 The specification currently does not cover this mode.

Expand Down
47 changes: 47 additions & 0 deletions examples/documents/document-push-transport.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"$schema": "https://open-resource-discovery.org/spec-v1/interfaces/Document.schema.json",
"openResourceDiscovery": "1.14",
"description": "Minimal example for push transport with inline resource definition",
"describedSystemInstance": {
"baseUrl": "https://example.com"
},
"packages": [
{
"ordId": "sap.example:package:push-demo:v1",
"title": "Push Transport Demo",
"shortDescription": "Demonstrates push transport with inline definitions",
"description": "This package demonstrates push transport with inline resource definitions.",
"version": "1.0.0",
"vendor": "sap:vendor:SAP:"
}
],
"apiResources": [
{
"ordId": "sap.example:apiResource:hello-api:v1",
"title": "Hello API",
"shortDescription": "Simple greeting API",
"description": "A simple greeting API that demonstrates push transport.",
"version": "1.0.0",
"visibility": "public",
"releaseStatus": "active",
"partOfPackage": "sap.example:package:push-demo:v1",
"apiProtocol": "rest",
"resourceDefinitions": [
{
"type": "openapi-v3",
"mediaType": "application/json",
"url": "/api/hello/openapi.json",
"accessStrategies": [
{
"type": "embedded"
}
]
}
],
"entryPoints": ["/api/hello"]
}
],
"definitions": {
"/api/hello/openapi.json": "{\"openapi\":\"3.0.3\",\"info\":{\"title\":\"Hello API\",\"version\":\"1.0.0\"},\"paths\":{\"/hello\":{\"get\":{\"summary\":\"Get greeting\",\"responses\":{\"200\":{\"description\":\"A greeting message\",\"content\":{\"application/json\":{\"schema\":{\"type\":\"object\",\"properties\":{\"message\":{\"type\":\"string\"}}}}}}}}}}}"
}
}
Loading
Loading