feat: add x-plan-decomposition Service Plan metadata extension #212

Closed
roque.caballero wants to merge 1 commit from feat/x-iaas-decomposition into main

Proposal — x-plan-decomposition Service Plan metadata extension

This PR enhances the broker schema with the x-plan-decomposition vendor extension. A Service Plan may declare the other Service Plans it is composed of and how many units of each it consumes per one unit of the plan. The extension is generic — the referenced plans are most commonly IaaS plans, but it is not restricted to them.

The composition is informational and platform-internal — consumed by the platform (principally the invoicing module) and not surfaced to end users.

Refs: phoenix/tenant-portal#515

Specification basis

The extension is an extra key inside the Service Plan metadata object, which the specification explicitly allows:

  • spec.md § Service Plan Object: metadata is "an opaque object of metadata … Platforms will treat this as a blob."
  • profile.md § Service Metadata: "the specification does not mandate the property names used in the metadata objects" — the listed names are only RECOMMENDED.
  • spec.md § Vendor Extension Fields: a unique prefix (x-) reduces clashes, and receivers MUST ignore unknown fields.

Shape

services[].plans[].metadata.x-plan-decomposition

"metadata": {
  "displayName": "Chat",
  "bullets": ["Dedicated chat", "8 vCPU", "16 GB memory"],
  "x-plan-decomposition": [
    { "planId": "PHOENIQS_INFRA.STORAGE",     "quantity": 100 },
    { "planId": "PHOENIQS_INFRA.COMPUTE_CPU", "quantity": 8 },
    { "planId": "PHOENIQS_INFRA.MEMORY",      "quantity": 16 }
  ]
}
Field Type Required Description
x-plan-decomposition array of objects no The Service Plans this plan is composed of and the units of each consumed per one unit of this plan.
[].planId string yes A Service Plan id (SERVICE.PLAN convention), e.g. PHOENIQS_INFRA.COMPUTE_CPU.
[].quantity number yes Units consumed per one unit of this plan; > 0; fractional allowed.

Changes

  • open-service-broker-model — new PlanDecomposition record; ServicePlanMetadata gains the optional x-plan-decomposition component. A backward-compatible constructor is kept, so existing positional callers (osb-core, osb-catalog, osb-maas, kvant-api, …) keep compiling.
  • open-service-broker-api — no production code change: the extension flows through the shared model. Integration tests added: GET /v2/catalog exposes the extension, and it appears in the generated OpenAPI schema.
  • docs — new proposal docs/proposals/x-plan-decomposition.md, linked from the README.

Module impact

Module Impact
open-service-broker-model New PlanDecomposition record + x-plan-decomposition on ServicePlanMetadata.
open-service-broker-api None (shared model); integration tests assert exposure in the catalog JSON and OpenAPI.
open-service-broker-client None — the client decodes Catalog through the shared model and carries the extension transparently.
open-service-broker-schema-validator Not impacted — it validates the JSON schemas exposed for Service Instance / Binding parameters (schemas.*.parameters), not plan metadata.

Compatibility

  • Optional and additive: a plan that omits the key is unchanged.
  • Opaque container: platforms that do not know the key ignore it.
  • Source compatible for downstream callers (backward-compatible constructor).

Testing

./mvnw verify is green across all modules. New coverage: PlanDecompositionTest (4), ServicePlanMetadataTest (+2 — serialize/deserialize with the extension, fractional quantity), CatalogResourceTest (+2 — catalog exposure and OpenAPI documentation).

## Proposal — `x-plan-decomposition` Service Plan metadata extension This PR enhances the broker schema with the **`x-plan-decomposition`** vendor extension. A Service Plan may declare the **other Service Plans it is composed of** and **how many units of each it consumes per one unit of the plan**. The extension is **generic** — the referenced plans are most commonly IaaS plans, but it is not restricted to them. The composition is *informational and platform-internal* — consumed by the platform (principally the **invoicing** module) and **not** surfaced to end users. Refs: phoenix/tenant-portal#515 ### Specification basis The extension is an extra key inside the Service Plan `metadata` object, which the specification explicitly allows: - `spec.md` § *Service Plan Object*: `metadata` is *"an opaque object of metadata … Platforms will treat this as a blob."* - `profile.md` § *Service Metadata*: *"the specification does not mandate the property names used in the `metadata` objects"* — the listed names are only **RECOMMENDED**. - `spec.md` § *Vendor Extension Fields*: a unique prefix (`x-`) reduces clashes, and receivers **MUST** ignore unknown fields. ### Shape `services[].plans[].metadata.x-plan-decomposition` ```json "metadata": { "displayName": "Chat", "bullets": ["Dedicated chat", "8 vCPU", "16 GB memory"], "x-plan-decomposition": [ { "planId": "PHOENIQS_INFRA.STORAGE", "quantity": 100 }, { "planId": "PHOENIQS_INFRA.COMPUTE_CPU", "quantity": 8 }, { "planId": "PHOENIQS_INFRA.MEMORY", "quantity": 16 } ] } ``` | Field | Type | Required | Description | |---|---|---|---| | `x-plan-decomposition` | array of objects | no | The Service Plans this plan is composed of and the units of each consumed per one unit of this plan. | | `[].planId` | string | yes | A Service Plan id (`SERVICE.PLAN` convention), e.g. `PHOENIQS_INFRA.COMPUTE_CPU`. | | `[].quantity` | number | yes | Units consumed per one unit of this plan; `> 0`; **fractional allowed**. | ### Changes - **`open-service-broker-model`** — new `PlanDecomposition` record; `ServicePlanMetadata` gains the optional `x-plan-decomposition` component. A backward-compatible constructor is kept, so existing positional callers (osb-core, osb-catalog, osb-maas, kvant-api, …) keep compiling. - **`open-service-broker-api`** — no production code change: the extension flows through the shared model. Integration tests added: `GET /v2/catalog` exposes the extension, and it appears in the generated OpenAPI schema. - **`docs`** — new proposal [`docs/proposals/x-plan-decomposition.md`](docs/proposals/x-plan-decomposition.md), linked from the README. ### Module impact | Module | Impact | |---|---| | `open-service-broker-model` | New `PlanDecomposition` record + `x-plan-decomposition` on `ServicePlanMetadata`. | | `open-service-broker-api` | None (shared model); integration tests assert exposure in the catalog JSON and OpenAPI. | | `open-service-broker-client` | None — the client decodes `Catalog` through the shared model and carries the extension transparently. | | `open-service-broker-schema-validator` | **Not impacted** — it validates the JSON *schemas* exposed for Service Instance / Binding parameters (`schemas.*.parameters`), not plan `metadata`. | ### Compatibility - Optional and additive: a plan that omits the key is unchanged. - Opaque container: platforms that do not know the key ignore it. - Source compatible for downstream callers (backward-compatible constructor). ### Testing `./mvnw verify` is green across all modules. New coverage: `PlanDecompositionTest` (4), `ServicePlanMetadataTest` (+2 — serialize/deserialize with the extension, fractional quantity), `CatalogResourceTest` (+2 — catalog exposure and OpenAPI documentation).
feat: add x-iaas-decomposition Service Plan metadata extension
All checks were successful
Build / build (pull_request) Successful in 2m58s
30642ed450
Add first-class support for the PHOENIQS x-iaas-decomposition vendor
extension carried inside the Service Plan metadata object: a plan may
declare the IaaS Service Plans it is composed of and the units of each
it consumes per one unit of the plan (fractional allowed).

- model: new IaaSDecomposition record; ServicePlanMetadata gains the
  optional x-iaas-decomposition key (a backward-compatible constructor
  is kept so existing positional callers keep compiling)
- api: integration tests asserting that GET /v2/catalog exposes the
  extension and that it is documented in the generated OpenAPI schema
- docs: proposal describing the extension, its specification basis,
  semantics and per-module impact

Receivers that do not understand the extension ignore it, per the OSB
specification's opaque-metadata and vendor-extension rules.

Refs: phoenix/tenant-portal#515
roque.caballero changed title from feat: add x-iaas-decomposition Service Plan metadata extension to feat: add x-plan-decomposition Service Plan metadata extension 2026-11-04 12:50:30 +00:00
Author
Member

Superseded by #214 — the extension was renamed from x-iaas-decomposition to x-plan-decomposition to make it generic (not IaaS-only). Same content, branch feat/x-plan-decomposition.

Superseded by #214 — the extension was renamed from `x-iaas-decomposition` to `x-plan-decomposition` to make it generic (not IaaS-only). Same content, branch `feat/x-plan-decomposition`.
roque.caballero closed this pull request 2026-11-04 12:50:37 +00:00
All checks were successful
Build / build (pull_request) Successful in 2m58s
Required
Details

Pull request closed

Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
phoenix-oss/open-service-broker!212
No description provided.