diff --git a/images/adapter.svg b/images/adapter.svg new file mode 100644 index 00000000..0fe7361d --- /dev/null +++ b/images/adapter.svg @@ -0,0 +1,2 @@ +
Tool
Tool
Adapter
Adapter +
Message Broker
Message Broker
Consumer
Consumer
Consumer
Consumer
Subscription
Subscription
Subscription
Subscription
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/images/cdevents.drawio b/images/cdevents.drawio new file mode 100644 index 00000000..cd9d0484 --- /dev/null +++ b/images/cdevents.drawio @@ -0,0 +1,457 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/consumer-adapter.svg b/images/consumer-adapter.svg new file mode 100644 index 00000000..1c33c151 --- /dev/null +++ b/images/consumer-adapter.svg @@ -0,0 +1,3 @@ +
Tool
Tool
Message Broker
Message Broker
Consumer
Consumer
Consumer
Consumer
Subscription
Subscription
Subscription
Subscription
Adapter
Adapter +
Subscription
Subscription
Adapter
Adapter +
Consumer
Consumer
Invoke
API
Invoke...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/images/multiple-produced.svg b/images/multiple-produced.svg new file mode 100644 index 00000000..3a17883f --- /dev/null +++ b/images/multiple-produced.svg @@ -0,0 +1 @@ +
Tool
Tool
Message Broker
Message Broker
Consumer
Consumer
Consumer
Consumer
Subscription
Subscription
Subscription
Subscription
Consumer
Consumer
Subscription
Subscription
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/images/multiple-received.svg b/images/multiple-received.svg new file mode 100644 index 00000000..06088cf0 --- /dev/null +++ b/images/multiple-received.svg @@ -0,0 +1 @@ +
Tool
Tool
Message Broker
Message Broker
Consumer
Consumer
Subscription
Subscription
Subscription
Subscription
Tool
Tool
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/images/original-adapter.svg b/images/original-adapter.svg new file mode 100644 index 00000000..9aa015a8 --- /dev/null +++ b/images/original-adapter.svg @@ -0,0 +1 @@ +
Tool
Tool
Watcher / Adapter
Watcher / Ada...
Message Broker
Message Broker
Consumer
Consumer
Consumer
Consumer
Subscription
Subscription
Subscription
Subscription
Subscription
Subscription
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/images/watcher-producer.svg b/images/watcher-producer.svg new file mode 100644 index 00000000..d21ddecd --- /dev/null +++ b/images/watcher-producer.svg @@ -0,0 +1 @@ +
Tool
Tool
Watch
Watch
Watcher / Producer
Watcher / Produc...
Message Broker
Message Broker
Consumer
Consumer
Consumer
Consumer
Subscription
Subscription
Subscription
Subscription
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/primer.md b/primer.md index 75dbf25d..c48b197e 100644 --- a/primer.md +++ b/primer.md @@ -24,16 +24,34 @@ document is updated accordingly to reflect the design decisions behind the chang - [History](#history) - [Design reflections](#design-reflections) - - [How does CDEvents enable tools to communicate in an interoperable - way?](#how-does-cdevents-enable-tools-to-communicate-in-an-interoperable-way) + - [How does CDEvents enable tools to communicate in an interoperable way?](#how-does-cdevents-enable-tools-to-communicate-in-an-interoperable-way) - [Why use events?](#why-use-events) - - [Why not point-to-point - communication?](#why-not-point-to-point-communication) + - [Why not point-to-point communication?](#why-not-point-to-point-communication) + - [Declarative vs. imperative events](#declarative-vs-imperative-events) - [Relations to CloudEvents](#relations-to-cloudevents) +- [Versioning](#versioning) + - [Versioning of CDEvents](#versioning-of-cdevents) + - [Versioning of the CDEvents specification](#versioning-of-the-cdevents-specification) + - [Development of a new version](#development-of-a-new-version) +- [Extending CDEvents](#extending-cdevents) + - [Adding new data to CDEvents](#adding-new-data-to-cdevents) + - [Adding new event types](#adding-new-event-types) +- [Adopting CDEvents](#adopting-cdevents) + - [Producer-side architectures](#producer-side-architectures) + - [External event producer](#external-event-producer) + - [External event adapter](#external-event-adapter) + - [Multiple event formats produced](#multiple-event-formats-produced) + - [Consumer-side architectures](#consumer-side-architectures) + - [Multiple event formats through adapter](#multiple-event-formats-through-adapter) + - [Consumer-side adapters](#consumer-side-adapters) + - [Multiple event formats consumed](#multiple-event-formats-consumed) - [Acknowledgments](#acknowledgments) - [Use Cases](#use-cases) - [Design Decisions](#design-decisions) - [Keys, Values and Types](#keys-values-and-types) + - [Simplified data model](#simplified-data-model) + - [Artifacts](#artifacts) +- [Whitepaper](#whitepaper) ## History @@ -89,17 +107,29 @@ create a system that will: * Create a coupled architecture - using point-to-point communication creates a tightly intertwined architecture difficult to expand and monitor. -### Simplified data model +### Declarative vs. imperative events -In the initial version of CDEvents we tackled a simple scenario in which -each artifact is built from a single repository and each service is deployed -from a single artifact. +CDEvents are declarative events. With "declarative" we refer to event through +which the producer sends information about an occurrence, but it does not know +how the event will be used on the receiving side or even who will receive it. -This data model is somewhat limited, but is has allowed us to put more focus -on the overall structure of the protocol in the first release. +With imperative events we refer to events that are sent with the intent of +triggering a specific reaction, like "start a pipeline" or "deploy an +application". CDEvents do not support imperative events today; the specification +may include imperative events in future to foster interoperability in systems +that rely on imperative events today. -We plan to extend the data model to support more complex scenarios in upcoming -releases. +Imperative events create coupling between producer and consumer as they +typically require some form of acknowledgement to be send back by the +consumer of the original event back to the producer. Imperative events are +useful to implement workflows where the orchestration logic is centrally +managed by a single component. + +A behavior similar to that of imperative events can be achieved by moving part +of the business logic to an adapter that listens for specific declarative events +and decides based on a set of policy to trigger actions in a downstream system, +similarly to what is described in the [receiving +adapters](#consumer-side-adapters) scenario. ## Relations to CloudEvents @@ -189,15 +219,163 @@ Once a specification is ready for release, its number if updated, the event vers are finalized (`-draft` is removed), schemas are updated and a git tag is created for this last commit. -### Artifacts +## Extending CDEvents -The specification has chosen for v0.1.0 to adopt [package-urls][purl] (or purls) -as the format for any artifact identifier included in the spec. Purls provide a -consistent format for artifact identifiers across different package types. +The CDEvents specification is designed to evolve over time, to accommodate the +need of CDEvents users and cover a growing number of use cases. +In all cases we prefer backward compatible changes, which could be new fields in +existing events or new event types. +[Versioning](#versioning) of messages is used for producers to validate messages +before they are sent, and for consumer to know how to parse them. -CDEvents wishes for a format that can be used to reference to an artifact, or -package, that is independent from the hosting storage, which is a property which -purls satisfy for several artifact types. +### Adding new data to CDEvents + +If the data model of a CDEvent is not sufficient, events producers may choose to +pass extra data through the `customData` field. Using `customData` can be an +effective interim step, as it's easy to implement and can be used to help the +migration process from existing events to CDEvents. + +In most cases though `customData` should not be considered as a permanent +solution, since consumers don't know how to process this extra data, unless they +implement producer specific logic and sacrifice part of the interoperability +benefit of using CDEvents. + +Adding a new field to an existing CDEvent type is considered a backward +compatible change - see the [versioning](#versioning) for more details. +Aspects to consider when proposing a new field are: + +- is the field generally useful to the CD community? Data that is unique to a + single platform is likely to be rejected +- what are the use cases where this field will be used? +- what is the format for the new field? Please be as specific as possible +- what is the name of the new field? Check the [SIG interoperability + vocabulary][sig-interop-vocabulary] if a standard name exists. If not + propose the new field name for the vocabulary as well. + +### Adding new event types + +If a new event type is needed, it's good practice to contribute the new type +into the CDEvents specification. Custom events can be used, but they should not +use the "dev.cdevents" namespace for their type. + +Custom events are not interoperable, so existing CDEvents consumers won't be +able to handle them. Introducing a custom event is simple enough on the producer +side but it doesn't scale well with the number of consumers. + +Adding a new event to an existing CDEvents bucket is a backward compatible +change. Aspects to consider when proposing a new event type are: + +- is the event generally useful to the CD community? Events that are very + specific to a single platform are likely to be rejected. If the event + represents a functionality that is currently only implemented in one platform, + but nonetheless generally useful, it can still be introduced in CDEvents +- what are the use cases where this event will be used? +- what are the sources of these events? +- if the event includes a new kind of subject, what is the data model of the + subject? What is the format of its ID? Please be as specific as possible +- what is the name of the new type? Check the [SIG interoperability + vocabulary][sig-interop-vocabulary] if a standard name exists. If not + consider proposing the new field name for the vocabulary as well. + +## Adopting CDEvents + +When adopting CDEvents, producers and consumers alike may adopt different +strategies to support existing event producers and consumers that want to +consider existing messaging systems, formats and event producers and consumers +that are in place. +CDEvents is a new specification, but neither CloudEvents nor events in general +are a new idea, and several tools may already be using events or webhooks with a +tool specific data model. + +Below we consider a set of common scenarios and how CDEvents may be +incrementally introduced in an existing system. + +### Producer-side architectures + +In the first three scenarios, CDEvents are introduced in the producer side, +either directly in the tool or through some external component. + +#### External event producer + +If a tool does not produce events, it may be possible to use an external +component to "watch" a tool output (for instance logs) and produce CDEvents. + +If the output does not contain all information required for the events, this +limitation can be worked-around by adding the missing data in the tool output. + +This solution may be brittle, because the tool output may not be a stable +interface for the tool, and it may change over time without notice. + +![watcher-producer](images/watcher-producer.svg) + +This approach is certainly valid to build a proof-of-concept or to experiment +with events in an existing environment. + +If the output of the tool is structured and part of the tool API, this may also +be adopted as a permanent solution, to keep separation of concerns between the +tool itself and the process of generating events. + +#### External event adapter + +If a tool does produce events, it may be possible to use an external adapter +component to convert the existing events into CDEvents. + +![adapter](images/adapter.svg) + +Similar to the [previous case](#external-event-producer), incoming events may be +missing data required by CDEvents. If the events come from a tool that we do not +control, we cannot alter the content of the events, so we may request the tool +maintainers to either add the extra data or, like in the next scenario, start +producing CDEvents natively. + +#### Multiple event formats produced + +A tool may start producing CDEvents natively. If the tool previously produced +events, some consumers may expect the pre-existing event format. This can be +solved on the producer side by sending both format of events in parallel. + +In some cases it may be possible to use a single broker for both event types, +for instance if both formats are CloudEvents based. + +![multiple-produced](images/multiple-produced.svg) + +### Consumer-side architectures + +Typically it won't be possible for all existing event consumers to switch to +CDEvents at the same time. The following scenarios show how an incremental +approach can be used to migrate consumers towards CDEvents gradually. + +#### Multiple event formats through adapter + +In a variation of the previously mentioned producer-side architectures, the tool +produces only one format of events, which is sent to the broker. The adapter +subscribes to the events, converts them and publishes them back to the broker. +Consumer may then subscribe to the type of events that they prefer. + +![original-adapter](images/original-adapter.svg) + +With this architecture, the adapter may even be able to convert messages from +different tools, instead of just one. + +#### Consumer-side adapters + +In this scenario, the tool and some consumers use CDEvents. New consumers are +added that do not understand CDEvents, or that do not support events in general. +An adapter can be used to convert a CDEvent into the consumer specific format or +to extract data from a CDEvent and use it to invoke an API for the receiving +side. + +![consumer-adapter](images/consumer-adapter.svg) + +#### Multiple event formats consumed + +In this scenario, a new tool is added that produces CDEvents. An existing +consumer wants to benefit from existing events as well as the events from the +new tool. + +![multiple-received](images/multiple-received.svg) + +A single consumer may receive events from heterogenous sources. ## Acknowledgments @@ -211,7 +389,7 @@ There are two root use cases that we are considering: - *Interoperability through CDEvents*: In this use case, platforms from the CD landscape either produce or consume CDEvents. On the producing side, a system broadcasts that certain value has been produced, like a code change, an - artifact or a test result. On the consumer side, a system takes an action that + artifact or a test result. On the consumer-side, a system takes an action that takes advantage of that value that has been produced. - *Observability & Metrics*: In this use case, platforms from the CD landscape @@ -245,6 +423,28 @@ Keys and ENUM values are always written in [lowerCamelCase](https://en.wikipedia.org/wiki/Camel_case) for readability purposes. +### Simplified data model + +In the initial version of CDEvents we tackled a simple scenario in which +each artifact is built from a single repository and each service is deployed +from a single artifact. + +This data model is somewhat limited, but is has allowed us to put more focus +on the overall structure of the protocol in the first release. + +We plan to extend the data model to support more complex scenarios in upcoming +releases. + +### Artifacts + +The specification has chosen for v0.1.0 to adopt [package-urls][purl] (or purls) +as the format for any artifact identifier included in the spec. Purls provide a +consistent format for artifact identifiers across different package types. + +CDEvents wishes for a format that can be used to reference to an artifact, or +package, that is independent from the hosting storage, which is a property which +purls satisfy for several artifact types. + ## Whitepaper The [CDEvents whitepaper](./CDEvents_Whitepaper.pdf) has been originally @@ -259,4 +459,7 @@ created and its mission. [whitepaper]: https://cd.foundation/blog/2022/06/07/cdevents-publishes-first-whitepaper/ [ce-design-goals]: https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/primer.md#design-goals [ce-partitioning]: https://github.com/cloudevents/spec/blob/v1.0.1/extensions/partitioning.md -[purl]: https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst \ No newline at end of file +[purl]: + https://github.com/package-url/purl-spec/blob/master/PURL-SPECIFICATION.rst +[sig-interop-vocabulary]: + https://github.com/cdfoundation/sig-interoperability/blob/main/docs/vocabulary.md