Skip to content

Improve CloudEvents Compliance and Consolidate Subscription API Design Across CAMARA Subprojects #556

@gmuratk

Description

@gmuratk

Problem description

The current CAMARA event subscription and notification design (as defined in CAMARA-API-Event-Subscription-and-Notification-Guide.md) provides a consistent pattern for subscription-based APIs across CAMARA subprojects, but it deviates from CloudEvents Working Group specifications and results in redundant endpoint definitions across multiple subprojects.

1. CloudEvents compliance gaps

  • Several CAMARA attributes (e.g., protocol, sinkCredential, config) extend CloudEvents without formally using the extension attribute mechanism.
  • The required CloudEvents specversion field is not consistently enforced.
  • The current subscription schema merges CloudEvents metadata with subscription lifecycle management, while the CloudEvents model separates event metadata, transport binding, and subscription semantics.
  • sink (callback URL) handling diverges from the CloudEvents HTTP Webhook binding, where routing and authentication belong to the transport layer rather than the event payload.

2. Duplication across CAMARA subprojects

  • Each subproject (device-roaming-subscriptions, geofencing-subscriptions, etc.) defines its own /subscriptions endpoints and lifecycle operations.
  • This leads to repetitive maintenance, inconsistent examples, and redundant validation logic whenever CloudEvents evolves.

3. Limited interoperability

  • The current approach makes it difficult to exchange or process CAMARA events through CloudEvents-native brokers and tools.
  • CAMARA-specific fields (e.g., subscriptionExpireTime, subscriptionMaxEvents) are not represented as proper CloudEvents extensions, reducing reusability and compatibility.

Possible evolution

1. Define a CAMARA Base Class extending CloudEvents

  • Create a base specification (CAMARA-subscriptions-openapi.yaml) that:
    • Conforms fully to CloudEvents 1.0 structured mode (application/cloudevents-batch+json).
    • Defines shared /subscriptions operations and response models.
    • Adds CAMARA-specific extensions CamaraExtendedSubscriptionRequest, CamaraExtendedCloudEventsAttribute, CamaraConfigChangeEventJsonPatch, CamaraConfigChangeEventMergePatch, and CamaraConfigChangeEventSnapshot.

2. Possible Way of Introducing New CloudEvents Based Subscription APIs

  • Create a new “CAMARA Subscriptions” repository that:

    • Maintains the base subscription specification (paths, errors, examples, and CE compliance).

    Hosts domain-contributed component files for each CAMARA API domain.
    Each domain contributes:

    • components.schemas defining its event types and data payloads.

    • No paths — all lifecycle endpoints are defined in the shared base.

    • Maintains a template 'root' yaml for allowing a composite Subscription file with multiple domain event support.

  • This separation ensures:

    • The /subscriptions paths exist once, centrally.
    • Domain APIs only define their event semantics and data.

Example layout of Subscriptions repository:

subscriptions/
  code/
    API_definitions/
      CAMARA-subscriptions-openapi-v0.6.yaml <--base-->
      root.yaml <--input template for composite file generation-->

3. Use an Open Composition Flow with root.yaml

API Consumers and Providers can use open tooling such as Redocly CLI and OpenAPI Generator.

A lightweight root.yaml file serves as an entry point declaring which subscription domains to include.

Example — root.yaml

openapi: 3.0.3
info:
  title: MyApp Subscriptions API
  version: 1.0.0
  description: |
    Composite API combining Device Roaming and Geofencing subscriptions.
components:
  securitySchemes:
    openId:
      $ref: ./CAMARA_common.yaml#/components/securitySchemes/openId

  schemas:
    # CAMARA subscriptions extensions
    CamaraExtendedCloudEventsAttribute:
      $ref: ./CAMARA-subscriptions-openapi.yaml#/components/schemas/CamaraExtendedCloudEventsAttribute

    # geofencing-subscriptions
    org.camaraproject.geofencing-subscriptions.v1.detail:
      $ref: ./geofencing-subscriptions.yaml#/components/schemas/org.camaraproject.geofencing-subscriptions.v1.detail
    org.camaraproject.geofencing-subscriptions.v1.area-left:
      $ref: ./geofencing-subscriptions.yaml#/components/schemas/org.camaraproject.geofencing-subscriptions.v1.area-left
    org.camaraproject.geofencing-subscriptions.v1.area-entered:
      $ref: ./geofencing-subscriptions.yaml#/components/schemas/org.camaraproject.geofencing-subscriptions.v1.area-entered
    org.camaraproject.geofencing-subscriptions.v1.subscription-ends:
      $ref: ./geofencing-subscriptions.yaml#/components/schemas/org.camaraproject.geofencing-subscriptions.v1.subscription-ends

    # quality-on-demand-subscriptions
    org.camaraproject.quality-on-demand.v1.detail:
      $ref: ./quality-on-demand.yaml#/components/schemas/org.camaraproject.quality-on-demand.v1.detail
    org.camaraproject.quality-on-demand.v1.qos-status-changed:
      $ref: ./quality-on-demand.yaml#/components/schemas/org.camaraproject.quality-on-demand.v1.qos-status-changed

4. High-level flow for generating a single subscription SDK

+-------------------+      +--------------------------+       +-------------------------+       +-------------------------+
|base.yaml          |      |                          |       |                         |       |                         |
|domain1-events.yaml|      |  root.yaml               |       |     Redocly CLI         |       | Generic Code Generator  |
|domain2-events.yaml| +--->|  File with references to |+----->|  (or other) tool outputs|+----->|(e.g., OpenAPI Generator)|
|...                |      |  selected domain specific|       |subscriptions-onesdk.yaml|       |                         |
|domainN-events.yaml|      |  event definitions       |       |                         |       |                         |
+-------------------+      +--------------------------+       +-------------------------+       +-------------------------+

This process allows:

  • Developers to control which domain subscriptions are included.
  • Reuse of open, transparent tooling.
  • Output of a single composite YAML that can be passed to SDK generators in any language.

Alternative solution

Additional context

  • The proposal directly aligns with the CloudEvents Primer separation of event definition, binding, and subscription semantics.
  • It simplifies maintenance across CAMARA subprojects while ensuring interoperability with event-driven ecosystems.
  • The process supports incremental adoption—existing APIs can migrate their subscriptions.yaml gradually to component-only form without breaking backward compatibility.
  • The CAMARA-CE-IMPROVEMENTS directory in the respective fork, provides a complete example with base subscription file and 2 subscriptions examples for explicit subscriptions (geofencing and connected network type) and one example of implicit subscription (quality-on-demand.yaml) along with the respective root.yaml file and the composite-subscriptions.yaml file generated.

Benefits

  • Single lifecycle definition: /subscriptions paths defined once.
  • Domain autonomy: Each API contributes only event definitions.
  • CloudEvents alignment: Fully compliant with CloudEvents 1.0.
  • Open ecosystem tooling: No proprietary composition; uses Redoc and OpenAPI Generator.
  • Developer-friendly: Consumers can generate domain-specific or combined SDKs from a simple root.yaml.

Transition plan (example)

Phase 1 — Experimental (within Commonalities)

  • Publish the base spec (CAMARA-subscriptions-openapi.yaml) under Commonalities.
  • Create a 'root.yaml' template
  • Encourage subprojects (e.g., Geofencing, Device Roaming) to provide component-only YAML files referencing the base.
  • Showcase an example with at least 2 different domain events using base to generate composite subscriptions yaml using open-tooling such as Redocly CLI

Phase 2 — Dedicated Subscriptions Repository

  • Create a new “Subscriptions” repository under the CAMARA organization.
  • Assign maintainers and establish a contribution model for domain APIs.
  • Adopt root.yaml composition via Redoc as the standard mechanism for generating unified specifications.

Phase 3 — Domain Adoption

  • Domains deprecate their standalone -subscriptions.yaml files.
  • Each domain maintains only its component definitions and event type enums.

Phase 4 — SDK and Consumer Experience

  • API Consumers use root.yaml + Redoc workflow to generate a unified subscriptions-onesdk.yaml, then run OpenAPI Generator (or other compatible tools) to produce SDKs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions