diff --git a/Makefile b/Makefile deleted file mode 100644 index 5a9b481c1..000000000 --- a/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -all: verify - -verify: - @echo Running href checker: - @# Use "-x" if you want to skip external links - @tools/verify-links.sh -t -v . - @echo Running the spec phrase checker: - @tools/verify-specs.sh -v \ - amqp-protocol-binding.md \ - avro-format.md \ - documented-extensions.md \ - http-protocol-binding.md \ - http-webhook.md \ - json-format.md \ - kafka-protocol-binding.md \ - mqtt-protocol-binding.md \ - nats-protocol-binding.md \ - protobuf-format.md \ - spec.md \ - websockets-protocol-binding.md - @echo Running the doc phrase checker: - @tools/verify-docs.sh -v . diff --git a/README.md b/README.md index c3a510d41..e90fa327f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # CloudEvents + + ![CloudEvents logo](https://github.com/cncf/artwork/blob/master/projects/cloudevents/horizontal/color/cloudevents-horizontal-color.png) Events are everywhere. However, event producers tend to describe events @@ -22,35 +24,39 @@ a Cloud Native sandbox level project on ## CloudEvents Documents -The following documents are available: +The following documents are available ([Release Notes](misc/RELEASE_NOTES.md)): | | Latest Release | Working Draft | | :---------------------------- | :-----------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------: | | **Core Specification:** | -| CloudEvents | [v1.0.1](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md) | +| CloudEvents | [v1.0.2](cloudevents/spec.md) | [WIP](https://github.com/cloudevents/spec/tree/main/cloudevents/spec.md) | | | | **Optional Specifications:** | -| AMQP Protocol Binding | [v1.0.1](https://github.com/cloudevents/spec/blob/v1.0.1/amqp-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/amqp-protocol-binding.md) | -| AVRO Event Format | [v1.0.1](https://github.com/cloudevents/spec/blob/v1.0.1/avro-format.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/avro-format.md) | -| HTTP Protocol Binding | [v1.0.1](https://github.com/cloudevents/spec/blob/v1.0.1/http-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/http-protocol-binding.md) | -| JSON Event Format | [v1.0.1](https://github.com/cloudevents/spec/blob/v1.0.1/json-format.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/json-format.md) | -| Kafka Protocol Binding | [v1.0.1](https://github.com/cloudevents/spec/blob/v1.0.1/kafka-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/kafka-protocol-binding.md) | -| MQTT Protocol Binding | [v1.0.1](https://github.com/cloudevents/spec/blob/v1.0.1/mqtt-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/mqtt-protocol-binding.md) | -| NATS Protocol Binding | [v1.0.1](https://github.com/cloudevents/spec/blob/v1.0.1/nats-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/nats-protocol-binding.md) | +| AMQP Protocol Binding | [v1.0.2](cloudevents/bindings/amqp-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/amqp-protocol-binding.md) | +| AVRO Event Format | [v1.0.2](cloudevents/formats/avro-format.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/avro-format.md) | +| HTTP Protocol Binding | [v1.0.2](cloudevents/bindings/http-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/http-protocol-binding.md) | +| JSON Event Format | [v1.0.2](cloudevents/formats/json-format.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/json-format.md) | +| Kafka Protocol Binding | [v1.0.2](cloudevents/bindings/kafka-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/kafka-protocol-binding.md) | +| MQTT Protocol Binding | [v1.0.2](cloudevents/bindings/mqtt-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/mqtt-protocol-binding.md) | +| NATS Protocol Binding | [v1.0.2](cloudevents/bindings/nats-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/nats-protocol-binding.md) | | WebSockets Protocol Binding | - | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/websockets-protocol-binding.md) | -| Protobuf Event Format | | [v1.0-rc1](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/protobuf-format.md) | -| Web hook | [v1.0.1](https://github.com/cloudevents/spec/blob/v1.0.1/http-webhook.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/http-webhook.md) | +| Protobuf Event Format | [v1.0.2](cloudevents/formats/protobuf-format.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/protobuf-format.md) | +| Web hook | [v1.0.2](cloudevents/http-webhook.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/http-webhook.md) | | | | **Additional Documentation:** | | CloudEvents Adapters | - | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/adapters.md) | | CloudEvents SDK Requirements | - | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/SDK.md) | | Documented Extensions | - | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/documented-extensions.md) | -| Primer | [v1.0.1](https://github.com/cloudevents/spec/blob/v1.0.1/primer.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/primer.md) | +| Primer | [v1.0.2](cloudevents/primer.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/primer.md) | | Proprietary Specifications | - | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/proprietary-specs.md) | +There might be additional work-in-progress specifications being developed +in the [`main`](https://github.com/cloudevents/spec/tree/main) branch. + If you are new to CloudEvents, it is recommended that you start by reading the -[Primer](primer.md) for an overview of the specification's goals and design -decisions, and then move on to the [core specification](spec.md). +[Primer](cloudevents/primer.md) for an overview of the specification's goals +and design decisions, and then move on to the +[core specification](cloudevents/spec.md). Since not all event producers generate CloudEvents by default, there is documentation describing the recommended process for adapting some popular @@ -60,13 +66,14 @@ events into CloudEvents, see ## SDKs In addition to the documentation mentioned above, there is also an -[SDK proposal](SDK.md). A set of SDKs is also being developed: +[SDK proposal](cloudevents/SDK.md). A set of SDKs is also being developed: - [CSharp](https://github.com/cloudevents/sdk-csharp) - [Go](https://github.com/cloudevents/sdk-go) - [Java](https://github.com/cloudevents/sdk-java) -- [Javascript/TypeScript](https://github.com/cloudevents/sdk-javascript) +- [Javascript](https://github.com/cloudevents/sdk-javascript) - [PHP](https://github.com/cloudevents/sdk-php) +- [PowerShell](https://github.com/cloudevents/sdk-powershell) - [Python](https://github.com/cloudevents/sdk-python) - [Ruby](https://github.com/cloudevents/sdk-ruby) - [Rust](https://github.com/cloudevents/sdk-rust) @@ -85,9 +92,10 @@ native ecosystem by making our systems interoperable with CloudEvents. ## Process -The CloudEvents project is working to formalize the [specification](spec.md) -based on [design goals](primer.md#design-goals) which focus on interoperability -between systems which generate and respond to events. +The CloudEvents project is working to formalize the +[specification](cloudevents/spec.md) based on +[design goals](cloudevents/primer.md#design-goals) which focus on +interoperability between systems which generate and respond to events. In order to achieve these goals, the project must describe: diff --git a/SDK.md b/cloudevents/SDK.md similarity index 97% rename from SDK.md rename to cloudevents/SDK.md index 53085ced9..bbcdfd2b0 100644 --- a/SDK.md +++ b/cloudevents/SDK.md @@ -1,5 +1,7 @@ # CloudEvents SDK Requirements + + The intent of this document to describe a minimum set of requirements for new Software Development Kits (SDKs) for CloudEvents. These SDKs are designed and implemented to enhance and speed up CloudEvents integration. As part of @@ -11,6 +13,7 @@ following SDKs: - [Java SDK](https://github.com/cloudevents/sdk-java) - [JavaScript SDK](https://github.com/cloudevents/sdk-javascript) - [PHP SDK](https://github.com/cloudevents/sdk-php) +- [PowerShell](https://github.com/cloudevents/sdk-powershell) - [Python SDK](https://github.com/cloudevents/sdk-python) - [Ruby SDK](https://github.com/cloudevents/sdk-ruby) - [Rust SDK](https://github.com/cloudevents/sdk-rust) @@ -45,7 +48,7 @@ Each SDK MUST meet these requirements: - Idiomatic usage of the programming language. - Using current language version(s). - Supports HTTP transport renderings in both `structured` and `binary` - encodings. + content mode. ### Object Model Structure Guidelines diff --git a/adapters.md b/cloudevents/adapters.md similarity index 83% rename from adapters.md rename to cloudevents/adapters.md index 499f3b299..61eeb7c33 100644 --- a/adapters.md +++ b/cloudevents/adapters.md @@ -1,10 +1,12 @@ # CloudEvents Adapters + + Not all event producers will produce CloudEvents natively. As a result, some "adapter" might be needed to convert these events into CloudEvents. This will typically mean extracting metadata from the events to be used as CloudEvents attributes. In order to promote interoperability across multiple -implementations of these adpaters, the following documents show the proposed +implementations of these adapters, the following documents show the proposed algorithms that should be used: - [AWS S3](adapters/aws-s3.md) diff --git a/adapters/aws-s3.md b/cloudevents/adapters/aws-s3.md similarity index 95% rename from adapters/aws-s3.md rename to cloudevents/adapters/aws-s3.md index e942c26ba..ac26f297a 100644 --- a/adapters/aws-s3.md +++ b/cloudevents/adapters/aws-s3.md @@ -26,7 +26,8 @@ Comments: - While the "eventSource" value will always be static (`aws:s3`) when the event is coming from S3, if some other cloud provider is supporting the S3 event format it is expected that this value will not be - `aws:s3` for them - it should be something specific to their environment. + `aws:s3` for them - it is expected to be something specific to their + environment. - Consumers of these events will therefore be able to know if the event is an S3 type of event (regardless of whether it is coming from S3 or an S3-compatible provider) by detecting the `com.amazonaws.s3` prefix diff --git a/adapters/couchdb.md b/cloudevents/adapters/couchdb.md similarity index 100% rename from adapters/couchdb.md rename to cloudevents/adapters/couchdb.md diff --git a/adapters/github.md b/cloudevents/adapters/github.md similarity index 100% rename from adapters/github.md rename to cloudevents/adapters/github.md diff --git a/adapters/gitlab.md b/cloudevents/adapters/gitlab.md similarity index 100% rename from adapters/gitlab.md rename to cloudevents/adapters/gitlab.md diff --git a/amqp-protocol-binding.md b/cloudevents/bindings/amqp-protocol-binding.md similarity index 95% rename from amqp-protocol-binding.md rename to cloudevents/bindings/amqp-protocol-binding.md index 48c8b0df9..038122381 100644 --- a/amqp-protocol-binding.md +++ b/cloudevents/bindings/amqp-protocol-binding.md @@ -1,4 +1,4 @@ -# AMQP Protocol Binding for CloudEvents - Version 1.0.1 +# AMQP Protocol Binding for CloudEvents - Version 1.0.2 ## Abstract @@ -309,8 +309,8 @@ content-type: application/cloudevents+json; charset=utf-8 - [OASIS-AMQP-1.0][oasis-amqp-1.0] OASIS Advanced Message Queuing Protocol (AMQP) Version 1.0 -[ce]: ./spec.md -[json-format]: ./json-format.md +[ce]: ../spec.md +[json-format]: ../formats/json-format.md [content-type]: https://tools.ietf.org/html/rfc7231#section-3.1.1.5 [json-value]: https://tools.ietf.org/html/rfc7159#section-3 [rfc2046]: https://tools.ietf.org/html/rfc2046 @@ -323,3 +323,8 @@ content-type: application/cloudevents+json; charset=utf-8 [message-format]: http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-messaging-v1.0-os.html#section-message-format [data]: http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-messaging-v1.0-os.html#type-data [app-properties]: http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-messaging-v1.0-os.html#type-application-properties +[amqp-boolean]: http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-types-v1.0-os.html#type-boolean +[amqp-long]: http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-types-v1.0-os.html#type-long +[amqp-binary]: http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-types-v1.0-os.html#type-binary +[amqp-string]: http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-types-v1.0-os.html#type-string +[amqp-timestamp]: http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-types-v1.0-os.html#type-timestamp diff --git a/http-protocol-binding.md b/cloudevents/bindings/http-protocol-binding.md similarity index 80% rename from http-protocol-binding.md rename to cloudevents/bindings/http-protocol-binding.md index 3a084ea6b..41fe070bd 100644 --- a/http-protocol-binding.md +++ b/cloudevents/bindings/http-protocol-binding.md @@ -1,4 +1,4 @@ -# HTTP Protocol Binding for CloudEvents - Version 1.0.1 +# HTTP Protocol Binding for CloudEvents - Version 1.0.2 ## Abstract @@ -95,7 +95,7 @@ can be used with the _batched_ content mode. This specification does not introduce any new security features for HTTP, or mandate specific existing features to be used. This specification applies -identically to [HTTP over TLS]([RFC2818][RFC2818]). +identically to [HTTP over TLS][rfc2818]. ## 2. Use of CloudEvents Attributes @@ -209,16 +209,75 @@ and per [RFC7230, section 3][rfc7230-section-3], HTTP headers MUST only use printable characters from the US-ASCII character set, and are terminated by a CRLF sequence with OPTIONAL whitespace around the header value. -String values MUST be percent-encoded as described in [RFC3986, section -2.4][rfc3986-section-2-4] before applying the header encoding rules described in -[RFC7230, section 3.2.6][rfc7230-section-3-2-6]. - -When decoding an HTTP message into a CloudEvent, these rules MUST be applied in -reverse -- [RFC7230, section 3.2.6][rfc7230-section-3-2-6] decoding to an ASCII -string, and then a **single round** of percent-decoding as described in -[RFC3986, section 2.4][rfc3986-section-2-4] to produce a valid UTF-8 String. -(Note that applying percent-decoding an incorrect number of times can result in -message corruption or security issues.) +When encoding a CloudEvent as an HTTP message, string values +represented as HTTP header values MUST be percent-encoded as +described below. This is compatible with [RFC3986, section +2.1][rfc3986-section-2-1] but is more specific about what needs +encoding. The resulting string SHOULD NOT be further encoded. +(Rationale: quoted string escaping is unnecessary when every space +and double-quote character is already percent-encoded.) + +When decoding an HTTP message into a CloudEvent, any HTTP header +value MUST first be unescaped with respect to double-quoted strings, +as described in [RFC7230, section 3.2.6][rfc7230-section-3-2-6]. A single +round of percent-decoding MUST then be performed as described +below. HTTP headers for CloudEvent attribute values do not support +parenthetical comments, so the initial unescaping only needs to handle +double-quoted values, including processing backslash escapes within +double-quoted values. Header values produced via the +percent-encoding described here will never include double-quoted +values, but they MUST be supported when receiving events, for +compatibility with older versions of this specification which did +not require double-quote and space characters to be percent-encoded. + +Percent encoding is performed by considering each Unicode character +within the attribute's canonical string representation. Any +character represented in memory as a [Unicode surrogate +pair][surrogate-pair] MUST be treated as a single Unicode character. +The following characters MUST be percent-encoded: + +- Space (U+0020) +- Double-quote (U+0022) +- Percent (U+0025) +- Any characters outside the printable ASCII range of U+0021-U+007E + inclusive + +Attribute values are already constrained to prohibit characters in +the range U+0000-U+001F inclusive and U+007F-U+009F inclusive; +however for simplicity and to account for potential future changes, +it is RECOMMENDED that any HTTP header encoding implementation treats +such characters as requiring percent-encoding. + +Space and double-quote are encoded to avoid requiring any further +quoting. Percent is encoded to avoid ambiguity with percent-encoding +itself. + +Steps to encode a Unicode character: + +- Encode the character using UTF-8, to obtain a byte sequence. +- Encode each byte within the sequence as `%xy` where `x` is a + hexadecimal representation of the most significant 4 bits of the byte, + and `y` is a hexadecimal representation of the least significant 4 + bits of the byte. + +Percent-encoding SHOULD be performed using upper-case for values A-F, +but decoding MUST accept lower-case values. + +When performing percent-decoding (when decoding an HTTP message to a +CloudEvent), values that have been unncessarily percent-encoded MUST be +accepted, but encoded byte sequences which are invalid in UTF-8 MUST be +rejected. (For example, "%C0%A0" is an overlong encoding of U+0020, and +MUST be rejected.) + +Example: a header value of "Euro € 😀" SHOULD be encoded as follows: + +- The characters, 'E', 'u', 'r', 'o' do not require encoding +- Space, the Euro symbol, and the grinning face emoji require encoding. + They are characters U+0020, U+20AC and U+1F600 respectively. +- The encoded HTTP header value is therefore "Euro%20%E2%82%AC%20%F0%9F%98%80" + where "%20" is the encoded form of space, "%E2%82%AC" is the encoded form + of the Euro symbol, and "%F0%9F%98%80" is the encoded form of the + grinning face emoji. #### 3.1.4. Examples @@ -458,11 +517,11 @@ Content-Length: nnnn Content - [RFC7540][rfc7540] Hypertext Transfer Protocol Version 2 (HTTP/2) -[ce]: ./spec.md -[ce-message]: ./spec.md#message -[ce-types]: ./spec.md#type-system -[json-format]: ./json-format.md -[json-batch-format]: ./json-format.md#4-json-batch-format +[ce]: ../spec.md +[ce-message]: ../spec.md#message +[ce-types]: ../spec.md#type-system +[json-format]: ../formats/json-format.md +[json-batch-format]: ../formats/json-format.md#4-json-batch-format [content-type]: https://tools.ietf.org/html/rfc7231#section-3.1.1.5 [json-value]: https://tools.ietf.org/html/rfc7159#section-3 [json-array]: https://tools.ietf.org/html/rfc7159#section-5 @@ -471,7 +530,7 @@ Content-Length: nnnn [rfc2818]: https://tools.ietf.org/html/rfc2818 [rfc3629]: https://tools.ietf.org/html/rfc3629 [rfc3986]: https://tools.ietf.org/html/rfc3986 -[rfc3986-section-2-4]: https://tools.ietf.org/html/rfc3986#section-2.4 +[rfc3986-section-2-1]: https://tools.ietf.org/html/rfc3986#section-2.1 [rfc4627]: https://tools.ietf.org/html/rfc4627 [rfc4648]: https://tools.ietf.org/html/rfc4648 [rfc6839]: https://tools.ietf.org/html/rfc6839#section-3.1 @@ -483,3 +542,4 @@ Content-Length: nnnn [rfc7231]: https://tools.ietf.org/html/rfc7231 [rfc7231-section-4]: https://tools.ietf.org/html/rfc7231#section-4 [rfc7540]: https://tools.ietf.org/html/rfc7540 +[surrogate-pair]: http://unicode.org/glossary/#surrogate_pair diff --git a/kafka-protocol-binding.md b/cloudevents/bindings/kafka-protocol-binding.md similarity index 77% rename from kafka-protocol-binding.md rename to cloudevents/bindings/kafka-protocol-binding.md index 9fa2f4039..7db074a47 100644 --- a/kafka-protocol-binding.md +++ b/cloudevents/bindings/kafka-protocol-binding.md @@ -1,4 +1,4 @@ -# Kafka Protocol Binding for CloudEvents - Version 1.0.1 +# Kafka Protocol Binding for CloudEvents - Version 1.0.2 ## Abstract @@ -30,9 +30,9 @@ mapped to [Kafka messages][kafka-message-format]. ## 1. Introduction [CloudEvents][ce] is a standardized and protocol-agnostic definition of the -structure and metadata description of events. This specification defines how -the elements defined in the CloudEvents specification are to be used in the -Kafka protocol as [Kafka messages][kafka-message-format] (aka Kafka records). +structure and metadata description of events. This specification defines how the +elements defined in the CloudEvents specification are to be used in the Kafka +protocol as [Kafka messages][kafka-message-format] (aka Kafka records). ### 1.1. Conformance @@ -43,8 +43,8 @@ interpreted as described in [RFC2119][rfc2119]. ### 1.2. Relation to Kafka This specification does not prescribe rules constraining transfer or settlement -of event messages with Kafka; it solely defines how CloudEvents are expressed -in the Kafka protocol as [Kafka messages][kafka-message-format]. +of event messages with Kafka; it solely defines how CloudEvents are expressed in +the Kafka protocol as [Kafka messages][kafka-message-format]. The Kafka documentation uses "message" and "record" somewhat interchangeably and therefore the terms are to be considered synonyms in this specification as well. @@ -55,7 +55,18 @@ record is typically chosen based on the key's value. Kafka clients accomplish this by using a hash function. This binding specification defines how attributes and data of a CloudEvent is -mapped to the value, key, and headers sections of a Kafka message. +mapped to the value and headers sections of a Kafka record. + +Generally, the user SHOULD configure the key and/or the partition of the Kafka +record in a way that makes more sense for his/her use case (e.g. streaming +applications), in order to co-partition values, define relationships between +events, etc. This spec provides an OPTIONAL definition to map the key section of +the Kafka record, without constraining the user to implement it nor use it. An +example use case of this definition is when the sink of the event is a Kafka +topic, but the source is another transport (e.g. HTTP), and the user needs a way +to key the record. As a counter example, it doesn't make sense to use it when +the sink and source are Kafka topics, because this might cause the re-keying of +the records. ### 1.3. Content Modes @@ -68,8 +79,8 @@ placed into the Kafka message value section using an In the _binary_ content mode, the value of the event `data` MUST be placed into the Kafka message's value section as-is, with the `content-type` header value -declaring its media type; all other event attributes MUST be mapped to the -Kafka message's [header section][kafka-message-header]. +declaring its media type; all other event attributes MUST be mapped to the Kafka +message's [header section][kafka-message-header]. Implementations that use Kafka 0.11.0.0 and above MAY use either _binary_ or _structured_ modes. Implementations that use Kafka 0.10.x.x and below MUST only @@ -95,16 +106,16 @@ attributes. ### 2.1. data -`data` is assumed to contain opaque application data that is -encoded as declared by the `datacontenttype` attribute. +`data` is assumed to contain opaque application data that is encoded as declared +by the `datacontenttype` attribute. An application is free to hold the information in any in-memory representation of its choosing, but as the value is transposed into Kafka as defined in this specification, core Kafka provides data available as a sequence of bytes. For instance, if the declared `datacontenttype` is -`application/json;charset=utf-8`, the expectation is that the `data` -value is made available as [UTF-8][rfc3629] encoded JSON text. +`application/json;charset=utf-8`, the expectation is that the `data` value is +made available as [UTF-8][rfc3629] encoded JSON text. ## 3. Kafka Message Mapping @@ -114,16 +125,15 @@ particular content mode might be defined by an application, but are not defined here. The receiver of the event can distinguish between the two content modes by -inspecting the `content-type` [Header][kafka-message-header] of the -Kafka message. If the header is present and its value is prefixed with the -CloudEvents media type `application/cloudevents`, indicating the use of a known +inspecting the `content-type` [Header][kafka-message-header] of the Kafka +message. If the header is present and its value is prefixed with the CloudEvents +media type `application/cloudevents`, indicating the use of a known [event format](#14-event-formats), the receiver uses _structured_ mode, otherwise it defaults to _binary_ mode. If a receiver finds a CloudEvents media type as per the above rule, but with an -event format that it cannot handle, for instance -`application/cloudevents+avro`, it MAY still treat the event as binary and -forward it to another party as-is. +event format that it cannot handle, for instance `application/cloudevents+avro`, +it MAY still treat the event as binary and forward it to another party as-is. When the `content-type` header value is not prefixed with the CloudEvents media type, knowing when the message ought to be parsed as a CloudEvent can be a @@ -136,17 +146,20 @@ language of this specification then it is not a valid CloudEvent. ### 3.1. Key Mapping -The 'key' of the Kafka message is populated by a "Key Mapper" function, which -might map the key directly from one of the CloudEvent's attributes, but might -also use information from the application environment, from the CloudEvent's -data or other sources. +Every implementation MUST, by default, map the user provided record key to the +Kafka record key. + +The 'key' of the Kafka message MAY be populated by a "Key Mapper" function, +which might map the key directly from one of the CloudEvent's attributes, but +might also use information from the application environment, from the +CloudEvent's data or other sources. The shape and configuration of the "Key Mapper" function is implementation specific. -Every implementation SHOULD provide a default "Key Mapper" implementation that -maps the [Partitioning](extensions/partitioning.md) `partitionkey` attribute -value to the 'key' of the Kafka message as-is, if present. +Every implementation SHOULD provide an opt-in "Key Mapper" implementation that +maps the [Partitioning](../extensions/partitioning.md) `partitionkey` attribute +value to the 'key' of the Kafka message as-is, if present. A mapping function MUST NOT modify the CloudEvent. This means that the aforementioned `partitionkey` attribute MUST still be included with the @@ -172,7 +185,7 @@ message. #### 3.2.3. Metadata Headers All [CloudEvents][ce] attributes and -[CloudEvent Attributes Extensions](primer.md#cloudevent-attribute-extensions) +[CloudEvent Attributes Extensions](../primer.md#cloudevent-attribute-extensions) with exception of `data` MUST be individually mapped to and from the Header fields in the Kafka message. Both header keys and header values MUST be encoded as UTF-8 strings. @@ -190,18 +203,18 @@ Examples: ##### 3.2.4.2 Property Values -The value for each Kafka header is constructed from the respective -header's Kafka representation, compliant with the [Kafka message +The value for each Kafka header is constructed from the respective header's +Kafka representation, compliant with the [Kafka message format][kafka-message-format] specification. #### 3.2.5 Example -This example shows the _binary_ mode mapping of an event into the -Kafka message. All other CloudEvents attributes -are mapped to Kafka Header fields with prefix `ce_`. +This example shows the _binary_ mode mapping of an event into the Kafka message. +All other CloudEvents attributes are mapped to Kafka Header fields with prefix +`ce_`. -Mind that `ce_` here does refer to the event `data` -content carried in the payload. +Mind that `ce_` here does refer to the event `data` content carried in the +payload. ```text ------------------ Message ------------------- @@ -248,12 +261,12 @@ content-type: application/cloudevents+json; charset=UTF-8 #### 3.3.2. Event Data Encoding -The chosen [event format](#14-event-formats) defines how all attributes, -and `data`, are represented. +The chosen [event format](#14-event-formats) defines how all attributes, and +`data`, are represented. -The event metadata and data are then rendered in accordance with the [event -format](#14-event-formats) specification and the resulting data becomes the -Kafka application [data](#21-data) section. +The event metadata and data are then rendered in accordance with the +[event format](#14-event-formats) specification and the resulting data becomes +the Kafka application [data](#21-data) section. #### 3.3.3. Metadata Headers @@ -308,8 +321,8 @@ content-type: application/cloudevents+json; charset=UTF-8 - [RFC7159][rfc7159] The JavaScript Object Notation (JSON) Data Interchange Format -[ce]: ./spec.md -[json-format]: ./json-format.md +[ce]: ../spec.md +[json-format]: ../formats/json-format.md [kafka]: https://kafka.apache.org [kafka-message-format]: https://kafka.apache.org/documentation/#messageformat [kafka-message-header]: https://kafka.apache.org/documentation/#recordheader diff --git a/mqtt-protocol-binding.md b/cloudevents/bindings/mqtt-protocol-binding.md similarity index 96% rename from mqtt-protocol-binding.md rename to cloudevents/bindings/mqtt-protocol-binding.md index 9e2962475..0fceb7880 100644 --- a/mqtt-protocol-binding.md +++ b/cloudevents/bindings/mqtt-protocol-binding.md @@ -1,4 +1,4 @@ -# MQTT Protocol Binding for CloudEvents - Version 1.0.1 +# MQTT Protocol Binding for CloudEvents - Version 1.0.2 ## Abstract @@ -315,12 +315,14 @@ Topic Name: mytopic - [RFC7159][rfc7159] The JavaScript Object Notation (JSON) Data Interchange Format -[ce]: ./spec.md -[ce-types]: ./spec.md#type-system -[json-format]: ./json-format.md +[ce]: ../spec.md +[ce-types]: ../spec.md#type-system +[json-format]: ../formats/json-format.md [oasis-mqtt-3.1.1]: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html [oasis-mqtt-5]: http://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html +[3-publish]: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html#_Toc442180850 [5-content-type]: http://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html#_Toc502667341 +[5-publish]: https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901100 [json-value]: https://tools.ietf.org/html/rfc7159#section-3 [rfc2046]: https://tools.ietf.org/html/rfc2046 [rfc2119]: https://tools.ietf.org/html/rfc2119 diff --git a/nats-protocol-binding.md b/cloudevents/bindings/nats-protocol-binding.md similarity index 94% rename from nats-protocol-binding.md rename to cloudevents/bindings/nats-protocol-binding.md index e31bc28dd..565cc356c 100644 --- a/nats-protocol-binding.md +++ b/cloudevents/bindings/nats-protocol-binding.md @@ -1,4 +1,4 @@ -# NATS Protocol Binding for CloudEvents - Version 1.0.1 +# NATS Protocol Binding for CloudEvents - Version 1.0.2 ## Abstract @@ -151,11 +151,11 @@ Subject: mySubject - [RFC7159][rfc7159] The JavaScript Object Notation (JSON) Data Interchange Format -[ce]: ./spec.md -[json-format]: ./json-format.md +[ce]: ../spec.md +[json-format]: ../formats/json-format.md [nats]: https://nats.io -[nats-pub-proto]: https://nats.io/documentation/internals/nats-protocol/#PUB -[nats-msg-proto]: https://nats.io/documentation/internals/nats-protocol/#MSG +[nats-pub-proto]: https://docs.nats.io/reference/reference-protocols/nats-protocol#pub +[nats-msg-proto]: https://docs.nats.io/reference/reference-protocols/nats-protocol#protocol-messages [json-value]: https://tools.ietf.org/html/rfc7159#section-3 [rfc2046]: https://tools.ietf.org/html/rfc2046 [rfc2119]: https://tools.ietf.org/html/rfc2119 diff --git a/websockets-protocol-binding.md b/cloudevents/bindings/websockets-protocol-binding.md similarity index 91% rename from websockets-protocol-binding.md rename to cloudevents/bindings/websockets-protocol-binding.md index c3df8a783..3c20f2c4d 100644 --- a/websockets-protocol-binding.md +++ b/cloudevents/bindings/websockets-protocol-binding.md @@ -1,4 +1,4 @@ -# WebSockets Protocol Binding for CloudEvents - Version 1.0.1 +# WebSockets Protocol Binding for CloudEvents - Version 1.0.2 ## Abstract @@ -150,15 +150,17 @@ format specification and the resulting data becomes the payload. - [RFC2119][rfc2119] Key words for use in RFCs to Indicate Requirement Levels - [RFC6455][rfc6455] The WebSocket Protocol -[ce]: ./spec.md -[ce-message]: ./spec.md#message -[ce-event-format]: ./spec.md#event-format -[json-format]: ./json-format.md -[json-batch-format]: ./json-format.md#4-json-batch-format -[avro-format]: ./avro-format.md -[proto-format]: ./protobuf-format.md +[ce]: ../spec.md +[ce-message]: ../spec.md#message +[ce-event-format]: ../spec.md#event-format +[json-format]: ../formats/json-format.md +[json-batch-format]: ../formats/json-format.md#4-json-batch-format +[avro-format]: ../formats/avro-format.md +[proto-format]: ../formats/protobuf-format.md [rfc2119]: https://tools.ietf.org/html/rfc2119 [rfc6455]: https://tools.ietf.org/html/rfc6455 [rfc6455-section-1-3]: https://tools.ietf.org/html/rfc6455#section-1.3 [rfc6455-section-4]: https://tools.ietf.org/html/rfc6455#section-4 [rfc6455-section-1-9]: https://tools.ietf.org/html/rfc6455#section-1.9 +[rfc7230-section-5-1]: https://datatracker.ietf.org/doc/html/rfc7230#section-5.1 +[rfc6455-section-5-1]: https://datatracker.ietf.org/doc/html/rfc6455#section-5.1 diff --git a/documented-extensions.md b/cloudevents/documented-extensions.md similarity index 52% rename from documented-extensions.md rename to cloudevents/documented-extensions.md index 06748b9fe..3349bf8cd 100644 --- a/documented-extensions.md +++ b/cloudevents/documented-extensions.md @@ -1,28 +1,30 @@ # CloudEvents Extension Attributes -The [CloudEvents specification](spec.md) defines a set of metadata attributes -than can be used when transforming a generic event into a CloudEvent. The list -of attributes specified in that document represent the minimal set that the -specification authors deemed most likely to be used in a majority of situations. +The [CloudEvents specification](spec.md) defines a set of metadata +attributes that can be used when transforming a generic event into a +CloudEvent. The list of attributes specified in that document represent the +minimal set that the specification authors deemed most likely to be used in a +majority of situations. This document defines some addition attributes that, while not as commonly used -as the ones specified in the [CloudEvents specification](spec.md), could still -benefit from being formally specified in the hopes of providing some degree of -interoperability. This also allows for attributes to be defined in an +as the ones specified in the [CloudEvents specification](spec.md), could +still benefit from being formally specified in the hopes of providing some +degree of interoperability. This also allows for attributes to be defined in an experimental manner and tested prior to being considered for inclusion in the [CloudEvents specification](spec.md). -Implementations of the [CloudEvents specification](spec.md) are not mandated to -limit their use of extension attributes to just the ones specified in this -document. The attributes defined in this document have no official standing and -might be changed, or removed, at any time. As such, inclusion of an attribute in -this document does not need to meet the same level of maturity, or popularity, -as attributes defined in the [CloudEvents specification](spec.md). To be +Implementations of the [CloudEvents specification](spec.md) are not +mandated to limit their use of extension attributes to just the ones specified +in this document. The attributes defined in this document have no official +standing and might be changed, or removed, at any time. As such, inclusion of +an attribute in this document does not need to meet the same level of maturity, +or popularity, as attributes defined in the +[CloudEvents specification](spec.md). To be included in this document, aside from the normal PR review process, the attribute needs to have at least two -[Voting](community/GOVERNANCE.md#membership) member organizations stating their -support for its inclusion as comments in the PR. If the author of the PR is -also a Voting member, then they are allowed to be one of two. +[Voting](../community/GOVERNANCE.md#membership) member organizations stating +their support for its inclusion as comments in the PR. If the author of the PR +is also a Voting member, then they are allowed to be one of two. ## Usage @@ -33,13 +35,13 @@ MAY), this usage only applies to events that use the extension. Extensions attributes, while not defined by the core CloudEvents specifications, MUST follow the same serialization rules as defined by the format and protocol binding specifications. See -[Extension Context Attributes](spec.md#extension-context-attributes) for more -information. +[Extension Context Attributes](spec.md#extension-context-attributes) +for more information. ## Known Extensions - [Dataref (Claim Check Pattern)](extensions/dataref.md) - [Distributed Tracing](extensions/distributed-tracing.md) - [Partitioning](extensions/partitioning.md) -- [Sampling](extensions/sampled-rate.md) +- [Sampling](extensions/sampledrate.md) - [Sequence](extensions/sequence.md) diff --git a/extensions/dataref.md b/cloudevents/extensions/dataref.md similarity index 87% rename from extensions/dataref.md rename to cloudevents/extensions/dataref.md index 692e477c5..0a42c897e 100644 --- a/extensions/dataref.md +++ b/cloudevents/extensions/dataref.md @@ -24,15 +24,15 @@ attribute by using the `dataref` attribute. Known as the "Claim Check Pattern", this attribute MAY be used for a variety of purposes, including: - - If the [Data](../spec.md#data) is too large to be included in the message, - the `data` is not present, and the consumer can retrieve it using + - If the [Data](../spec.md#data) is too large to be included in the + message, the `data` is not present, and the consumer can retrieve it using this attribute. - - If the consumer wants to verify that the [Data](../spec.md#data) has not - been tampered with, it can retrieve it from a trusted source using this - attribute. - - If the [Data](../spec.md#data) MUST only be viewed by trusted consumers - (e.g. personally identifiable information), only a trusted consumer can - retrieve it using this attribute and a pre-shared secret. + - If the consumer wants to verify that the [Data](../spec.md#data) + has not been tampered with, it can retrieve it from a trusted source using + this attribute. + - If the [Data](../spec.md#data) MUST only be viewed by trusted + consumers (e.g. personally identifiable information), only a trusted + consumer can retrieve it using this attribute and a pre-shared secret. If this attribute is used, the information SHOULD be accessible long enough for all consumers to retrieve it, but MAY not be stored for an extended period diff --git a/extensions/distributed-tracing.md b/cloudevents/extensions/distributed-tracing.md similarity index 100% rename from extensions/distributed-tracing.md rename to cloudevents/extensions/distributed-tracing.md diff --git a/extensions/partitioning.md b/cloudevents/extensions/partitioning.md similarity index 100% rename from extensions/partitioning.md rename to cloudevents/extensions/partitioning.md diff --git a/extensions/sampled-rate.md b/cloudevents/extensions/sampledrate.md similarity index 87% rename from extensions/sampled-rate.md rename to cloudevents/extensions/sampledrate.md index bf8394585..7635eb87f 100644 --- a/extensions/sampled-rate.md +++ b/cloudevents/extensions/sampledrate.md @@ -1,4 +1,4 @@ -# Sampling extension +# Sampled Rate Extension There are many cases in an Event's life when a system (either the system creating the event or a system transporting the event) might wish to only emit a @@ -17,13 +17,15 @@ emitted event represents a given number of other similar events. It also provides a place for intermediary transport systems to modify the event when they impose additional sampling. -## Value +## Attributes + +### sampledrate - Type: `Integer` - Description: The rate at which this event has already been sampled. Represents the number of similar events that happened but were not sent plus this event. - For example, if a system sees 30 occurrences and emits a single event, `rate` - would be 30 (29 not sent and 1 sent). A value of `1` is the equivalent of this - extension not being used at all. + For example, if a system sees 30 occurrences and emits a single event, + `sampledrate` would be 30 (29 not sent and 1 sent). A value of `1` is the + equivalent of this extension not being used at all. - Constraints - The rate MUST be greater than zero. diff --git a/extensions/sequence.md b/cloudevents/extensions/sequence.md similarity index 100% rename from extensions/sequence.md rename to cloudevents/extensions/sequence.md diff --git a/avro-format.md b/cloudevents/formats/avro-format.md similarity index 97% rename from avro-format.md rename to cloudevents/formats/avro-format.md index fcecbcfa1..0a3aab08f 100644 --- a/avro-format.md +++ b/cloudevents/formats/avro-format.md @@ -1,4 +1,4 @@ -# Avro Event Format for CloudEvents - Version 1.0.1 +# Avro Event Format for CloudEvents - Version 1.0.2 ## Abstract @@ -71,7 +71,7 @@ Example: ### 2.4 Definition Users of Avro MUST use a message whose binary encoding is identical to the one -described by the [CloudEvent Avro Schema](./spec.avsc): +described by the [CloudEvent Avro Schema](cloudevents.avsc): ```json { @@ -173,7 +173,7 @@ The following table shows exemplary mappings: [avro-primitives]: http://avro.apache.org/docs/1.9.0/spec.html#schema_primitive [avro-logical-types]: http://avro.apache.org/docs/1.9.0/spec.html#Logical+Types [avro-unions]: http://avro.apache.org/docs/1.9.0/spec.html#Unions -[ce]: ./spec.md +[ce]: ../spec.md [rfc2119]: https://tools.ietf.org/html/rfc2119 [rfc3986-section41]: https://tools.ietf.org/html/rfc3986#section-4.1 [rfc3986-section43]: https://tools.ietf.org/html/rfc3986#section-4.3 diff --git a/spec.avsc b/cloudevents/formats/cloudevents.avsc similarity index 100% rename from spec.avsc rename to cloudevents/formats/cloudevents.avsc diff --git a/spec.json b/cloudevents/formats/cloudevents.json similarity index 100% rename from spec.json rename to cloudevents/formats/cloudevents.json diff --git a/spec.proto b/cloudevents/formats/cloudevents.proto similarity index 89% rename from spec.proto rename to cloudevents/formats/cloudevents.proto index 4bf02f4cf..26c987984 100644 --- a/spec.proto +++ b/cloudevents/formats/cloudevents.proto @@ -13,6 +13,7 @@ package io.cloudevents.v1; import "google/protobuf/any.proto"; import "google/protobuf/timestamp.proto"; +option csharp_namespace = "CloudNative.CloudEvents.V1"; option go_package = "cloudevents.io/genproto/v1"; option java_package = "io.cloudevents.v1.proto"; option java_multiple_files = true; @@ -56,4 +57,13 @@ message CloudEvent { google.protobuf.Timestamp ce_timestamp = 7; } } -} \ No newline at end of file +} + +/** + * CloudEvent Protobuf Batch Format + * + */ + +message CloudEventBatch { + repeated CloudEvent events = 1; +} diff --git a/json-format.md b/cloudevents/formats/json-format.md similarity index 59% rename from json-format.md rename to cloudevents/formats/json-format.md index de5418113..a297cd0bf 100644 --- a/json-format.md +++ b/cloudevents/formats/json-format.md @@ -1,4 +1,4 @@ -# JSON Event Format for CloudEvents - Version 1.0.1 +# JSON Event Format for CloudEvents - Version 1.0.2 ## Abstract @@ -44,7 +44,7 @@ specification defined attributes. This includes their syntax and placement within the JSON object. In particular, extensions are placed as top-level JSON properties. Extensions MUST be serialized as a top-level JSON property. There were many reasons for this design decision and they are covered in more detail -in the [Primer](primer.md#json-extensions). +in the [Primer](../primer.md#json-extensions). ### 2.1. Base Type System @@ -59,7 +59,7 @@ with exceptions noted below. | CloudEvents | JSON | | ------------- | -------------------------------------------------------------- | | Boolean | [boolean][json-bool] | -| Integer | [number][json-number], only the `int` component is permitted | +| Integer | [number][json-number], only the integer component optionally prefixed with a minus sign is permitted | | String | [string][json-string] | | Binary | [string][json-string], [Base64-encoded][base64] binary | | URI | [string][json-string] following [RFC 3986][rfc3986] | @@ -108,7 +108,8 @@ The following table shows exemplary attribute mappings: ### 2.4. JSONSchema Validation The CloudEvents [JSONSchema](http://json-schema.org) for the spec is located -[here](spec.json) and contains the definitions for validating events in JSON. +[here](cloudevents.json) and contains the definitions for validating events in +JSON. ## 3. Envelope @@ -125,34 +126,87 @@ OPTIONAL not omitted attributes MAY be represeted as a `null` JSON value. ### 3.1. Handling of "data" +The JSON representation of the event "data" payload is determined by the runtime +type of the `data` content and the value of the [`datacontenttype` +attribute][datacontenttype]. + +#### 3.1.1. Payload Serialization + Before taking action, a JSON serializer MUST first determine the runtime data type of the `data` content. If the implementation determines that the type of data is `Binary`, the value MUST be represented as a [JSON string][json-string] expression containing the [Base64][base64] encoded binary value, and use the member name `data_base64` to -store it inside the JSON object. - -For any other type, the implementation MUST translate the data value into a -[JSON value][json-value], and use the member name `data` to store it inside the -JSON object. - -Out of this follows that use of the `data` and `data_base64` members is mutually -exclusive in a JSON serialized CloudEvent. +store it inside the JSON representation. If present, the `datacontenttype` MUST +reflect the format of the original binary data. + +If the type of data is not `Binary`, the implementation will next determine +whether the value of the `datacontenttype` attribute declares the `data` to +contain JSON-formatted content. Such a content type is defined as one having a +[media subtype][rfc2045-sec5] equal to `json` or ending with a `+json` format +extension. That is, a `datacontenttype` declares JSON-formatted content if its +media type, when stripped of parameters, has the form `*/json` or `*/*+json`. +If the `datacontenttype` is unspecified, processing SHOULD proceed as if the +`datacontenttype` had been specified explicitly as `application/json`. + +If the `datacontenttype` declares the data to contain JSON-formatted content, a +JSON serializer MUST translate the data value to a [JSON value][json-value], and +use the member name `data` to store it inside the JSON representation. The data +value MUST be stored directly as a JSON value, rather than as an encoded JSON +document represented as a string. An implementation MAY fail to serialize the +event if it is unable to translate the runtime value to a JSON value. + +Otherwise, if the `datacontenttype` does not declare JSON-formatted data +content, a JSON serializer MUST store a string representation of the data value, +properly encoded according to the `datacontenttype`, in the `data` member of the +JSON representation. An implementation MAY fail to serialize the event if it is +unable to represent the runtime value as a properly encoded string. + +Out of this follows that the presence of the `data` and `data_base64` members is +mutually exclusive in a JSON serialized CloudEvent. + +Furthermore, unlike attributes, for which value types are restricted by the +[type-system mapping](#22-type-system-mapping), the `data` member +[JSON value][json-value] is unrestricted, and MAY contain any valid JSON if the +`datacontenttype` declares the data to be JSON-formatted. In particular, the +`data` member MAY have a value of `null`, representing an explicit `null` +payload as distinct from the absence of the `data` member. + +#### 3.1.2. Payload Deserialization When a CloudEvents is deserialized from JSON, the presence of the `data_base64` member clearly indicates that the value is a Base64 encoded binary data, which -the serializer MUST decode into a binary runtime data type. When a `data` member -is present, it is decoded using the default JSON type mapping for the used -runtime. - -Unlike attributes, for which value types are restricted to strings per the -[type-system mapping](#22-type-system-mapping), the resulting `data` member -[JSON value][json-value] is unrestricted, and MAY contain any valid JSON. +the deserializer MUST decode into a binary runtime data type. The deserializer +MAY further interpret this binary data according to the `datacontenttype`. + +When a `data` member is present, the decoding behavior is dependent on the value +of the `datacontenttype` attribute. If the `datacontenttype` declares the `data` +to contain JSON-formatted content (that is, its subtype is `json` or has a +`+json` format extension), then the `data` member MUST be treated directly as a +[JSON value][json-value] and decoded using an appropriate JSON type mapping for +the runtime. Note: if the `data` member is a string, a JSON deserializer MUST +interpret it directly as a [JSON String][json-string] value; it MUST NOT further +deserialize the string as a JSON document. + +If the `datacontenttype` does not declare JSON-formatted data content, then the +`data` member SHOULD be treated as an encoded content string. An implementation +MAY fail to deserialize the event if the `data` member is not a string, or if it +is unable to interpret the `data` with the `datacontenttype`. + +When a `data` member is present, if the `datacontenttype` attribute is absent, a +JSON deserializer SHOULD proceed as if it were set to `application/json`, which +declares the data to contain JSON-formatted content. Thus, it SHOULD treat the +`data` member directly as a [JSON value][json-value] as specified above. +Furthermore, if a JSON-formatted event with no `datacontenttype` attribute, is +deserialized and then re-serialized using a different format or protocol +binding, the `datacontenttype` in the re-serialized event SHOULD be set +explicitly to the implied `application/json` content type to preserve the +semantics of the event. ### 3.2. Examples -Example event with `String`-valued `data`: +Example event with `Binary`-valued data: ```JSON { @@ -163,13 +217,28 @@ Example event with `String`-valued `data`: "time" : "2018-04-05T17:31:00Z", "comexampleextension1" : "value", "comexampleothervalue" : 5, - "unsetextension": null, - "datacontenttype" : "text/xml", - "data" : "" + "datacontenttype" : "application/vnd.apache.thrift.binary", + "data_base64" : "... base64 encoded string ..." } ``` -Example event with `Binary`-valued data +The above example re-encoded using [HTTP Binary Content Mode][http-binary]: + +``` +ce-specversion: 1.0 +ce-type: com.example.someevent +ce-source: /mycontext +ce-id: A234-1234-1234 +ce-time: 2018-04-05T17:31:00Z +ce-comexampleextension1: value +ce-comexampleothervalue: 5 +content-type: application/vnd.apache.thrift.binary + +...raw binary bytes... +``` + +Example event with a serialized XML document as the `String` (i.e. non-`Binary`) +valued `data`, and an XML (i.e. non-JSON-formatted) content type: ```JSON { @@ -180,13 +249,29 @@ Example event with `Binary`-valued data "time" : "2018-04-05T17:31:00Z", "comexampleextension1" : "value", "comexampleothervalue" : 5, - "datacontenttype" : "application/vnd.apache.thrift.binary", - "data_base64" : "... base64 encoded string ..." + "unsetextension": null, + "datacontenttype" : "application/xml", + "data" : "" } ``` -Example event with JSON data for the "data" member, either derived from a `Map` -or [JSON data](#31-handling-of-data) data: +The above example re-encoded using [HTTP Binary Content Mode][http-binary]: + +``` +ce-specversion: 1.0 +ce-type: com.example.someevent +ce-source: /mycontext +ce-id: B234-1234-1234 +ce-time: 2018-04-05T17:31:00Z +ce-comexampleextension1: value +ce-comexampleothervalue: 5 +content-type: application/xml + + +``` + +Example event with [JSON Object][json-object]-valued `data` and a content type +declaring JSON-formatted data: ```JSON { @@ -207,6 +292,63 @@ or [JSON data](#31-handling-of-data) data: } ``` +The above example re-encoded using [HTTP Binary Content Mode][http-binary]: + +``` +ce-specversion: 1.0 +ce-type: com.example.someevent +ce-source: /mycontext +ce-id: C234-1234-1234 +ce-time: 2018-04-05T17:31:00Z +ce-comexampleextension1: value +ce-comexampleothervalue: 5 +content-type: application/json + +{ + "appinfoA" : "abc", + "appinfoB" : 123, + "appinfoC" : true +} +``` + +Example event with a literal JSON string as the non-`Binary`-valued `data` and +no `datacontenttype`. The data is implicitly treated as if the `datacontenttype` +were set to `application/json`: + +```JSON +{ + "specversion" : "1.0", + "type" : "com.example.someevent", + "source" : "/mycontext", + "subject": null, + "id" : "D234-1234-1234", + "time" : "2018-04-05T17:31:00Z", + "comexampleextension1" : "value", + "comexampleothervalue" : 5, + "data" : "I'm just a string" +} +``` + +The above example re-encoded using [HTTP Binary Content Mode][http-binary]. +Note that the Content Type is explicitly set to the `application/json` value +that was implicit in JSON format. Note also that the content is quoted to +indicate that it is a literal JSON string. If the quotes were missing, this +would have been an invalid event because the content could not be decoded as +`application/json`: + +``` +ce-specversion: 1.0 +ce-type: com.example.someevent +ce-source: /mycontext +ce-id: D234-1234-1234 +ce-time: 2018-04-05T17:31:00Z +ce-comexampleextension1: value +ce-comexampleothervalue: 5 +content-type: application/json + +"I'm just a string" +``` + ## 4. JSON Batch Format In the _JSON Batch Format_ several CloudEvents are batched into a single JSON @@ -287,10 +429,12 @@ also valid in a request): Format [base64]: https://tools.ietf.org/html/rfc4648#section-4 -[ce]: ./spec.md -[ce-types]: ./spec.md#type-system +[ce]: ../spec.md +[ce-types]: ../spec.md#type-system [content-type]: https://tools.ietf.org/html/rfc7231#section-3.1.1.5 -[json-format]: ./json-format.md +[datacontenttype]: ../spec.md#datacontenttype +[http-binary]: ../bindings/http-protocol-binding.md#31-binary-content-mode +[json-format]: ../formats/json-format.md [json-geoseq]:https://www.iana.org/assignments/media-types/application/geo+json-seq [json-object]: https://tools.ietf.org/html/rfc7159#section-4 [json-seq]: https://www.iana.org/assignments/media-types/application/json-seq @@ -299,6 +443,7 @@ also valid in a request): [json-string]: https://tools.ietf.org/html/rfc7159#section-7 [json-value]: https://tools.ietf.org/html/rfc7159#section-3 [json-array]: https://tools.ietf.org/html/rfc7159#section-5 +[rfc2045-sec5]: https://tools.ietf.org/html/rfc2045#section-5 [rfc2046]: https://tools.ietf.org/html/rfc2046 [rfc2119]: https://tools.ietf.org/html/rfc2119 [rfc3986]: https://tools.ietf.org/html/rfc3986 diff --git a/protobuf-format.md b/cloudevents/formats/protobuf-format.md similarity index 85% rename from protobuf-format.md rename to cloudevents/formats/protobuf-format.md index f25e9bf80..6abe5f2dd 100644 --- a/protobuf-format.md +++ b/cloudevents/formats/protobuf-format.md @@ -1,4 +1,4 @@ -# Protobuf Event Format for CloudEvents - Version 1.0-rc1 +# Protobuf Event Format for CloudEvents - Version 1.0.2 ## Abstract @@ -9,17 +9,14 @@ of that specification. In this document the terms *Protocol Buffers*, *protobuf*, and *proto* are used interchangeably. -## Status of this document - -This document is a release candidate. - ## Table of Contents 1. [Introduction](#1-introduction) 2. [Attributes](#2-attributes) 3. [Data](#3-data) 4. [Transport](#4-transport) -5. [Examples](#5-examples) +5. [Batch Format](#5-batch-format) +6. [Examples](#6-examples) ## 1. Introduction @@ -128,8 +125,6 @@ oneof data { * When the type of the data is binary the value MUST be stored in the `binary_data` property. * `datacontenttype` SHOULD be populated with the appropriate media-type. - - ## 4. Transport Transports that support content identification MUST use the following designation: @@ -138,12 +133,40 @@ Transports that support content identification MUST use the following designatio application/cloudevents+protobuf ``` -## 5. Examples +## 5. Batch Format + +Batch format allows for a set of CloudEvents to be represented, no relationship +between those events is implied. + +Although the _protobuf batch format_ builds on the _protobuf format_ it is considered +seperate, that is to say that support of _protobuf format_ does not indicate support +of the batch representation. The batch format MUST only be used where supported. + +### 5.1 Envelope + +The enveloping container is a _CloudEventBatch_ protobuf message containing a +repeating set of _CloudEvent_ message(s): + +```proto +message CloudEventBatch { + repeated CloudEvent events = 1; +} +``` + +### 5.2 Batch Media Type + +A compliant protobuf batch representation is identifed using the following media-type + +```text + application/cloudevents-batch+protobuf +``` + +## 6. Examples The following code-snippets show how proto representations might be constucted assuming the availability of some convenience methods. -### 5.1 Plain Text event data +### 6.1 Plain Text event data ```java public static CloudEvent plainTextExample() { @@ -169,7 +192,7 @@ public static CloudEvent plainTextExample() { ``` -### 5.2 Proto message as event data +### 6.2 Proto message as event data Where the event data payload is itself a protobuf message (with its own schema) a protocol buffer idiomatic method can be used to carry the data. @@ -213,15 +236,15 @@ private static Spec.CloudEvent protoExample() { * [Protocol Buffer 3 Specification][proto-3] * [CloudEvents Protocol Buffers format schema][proto-schema] -[Proto-3]: https://developers.google.com/protocol-buffers/docs/reference/proto3-spec +[proto-3]: https://developers.google.com/protocol-buffers/docs/reference/proto3-spec [proto-home]: https://developers.google.com/protocol-buffers [proto-scalars]: https://developers.google.com/protocol-buffers/docs/proto3#scalar [proto-wellknown]: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf [proto-timestamp]: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Timestamp -[proto-schema]: ./spec.proto +[proto-schema]: ./cloudevents.proto [json-format]: ./json-format.md -[ce]: ./spec.md -[ce-types]: ./spec.md#type-system +[ce]: ../spec.md +[ce-types]: ../spec.md#type-system [rfc2119]: https://tools.ietf.org/html/rfc2119 [rfc3986-section41]: https://tools.ietf.org/html/rfc3986#section-4.1 [rfc3986-section43]: https://tools.ietf.org/html/rfc3986#section-4.3 diff --git a/http-webhook.md b/cloudevents/http-webhook.md similarity index 98% rename from http-webhook.md rename to cloudevents/http-webhook.md index 05a7718b7..6d75e8d55 100644 --- a/http-webhook.md +++ b/cloudevents/http-webhook.md @@ -1,4 +1,4 @@ -# HTTP 1.1 Web Hooks for Event Delivery - Version 1.0.1 +# HTTP 1.1 Web Hooks for Event Delivery - Version 1.0.2 ## Abstract @@ -306,7 +306,7 @@ WebHook-Allowed-Origin: eventemitter.example.com or ```text -WebHook-Request-Origin: * +WebHook-Allowed-Origin: * ``` #### 4.2.2. WebHook-Allowed-Rate @@ -342,7 +342,7 @@ WebHook-Allowed-Rate: 100 - [RFC7540][rfc7540] Hypertext Transfer Protocol Version 2 (HTTP/2) [ce]: ./spec.md -[webhooks]: http://progrium.com/blog/2007/05/03/web-hooks-to-revolutionize-the-web/ +[webhooks]: https://progrium.github.io/blog/2007/05/03/web-hooks-to-revolutionize-the-web/index.html [content-type]: https://tools.ietf.org/html/rfc7231#section-3.1.1.5 [retry-after]: https://tools.ietf.org/html/rfc7231#section-7.1.3 [authorization]: https://tools.ietf.org/html/rfc7235#section-4.2 diff --git a/primer.md b/cloudevents/primer.md similarity index 94% rename from primer.md rename to cloudevents/primer.md index f7f1bd59e..0b1fe5d73 100644 --- a/primer.md +++ b/cloudevents/primer.md @@ -1,4 +1,6 @@ -# CloudEvents Primer - Version 1.0.1 +# CloudEvents Primer - Version 1.0.2 + + ## Abstract @@ -43,8 +45,8 @@ approved the CloudEvents work as a new stand-alone CNCF sandbox project. ## CloudEvents Concepts An [event](spec.md#event) includes context and data about an -[occurrence](spec.md#occurrence). Each _occurrence_ is uniquely identified by -the data of the _event_. +[occurrence](spec.md#occurrence). Each _occurrence_ is uniquely +identified by the data of the _event_. _Events_ represent facts and therefore do not include a destination, whereas messages convey intent, transporting data from a source to a given destination. @@ -74,7 +76,7 @@ by multiple companies or providers. Events can be delivered through various industry standard protocols (e.g. HTTP, AMQP, MQTT, SMTP), open-source protocols (e.g. Kafka, NATS), or platform/vendor -specific protocols (AWS Kinesis, Azure Event Grid). +specific protocols. An action processes an event defining a behavior or effect which was triggered by a specific _occurrence_ from a specific _source_. While outside of the scope @@ -127,6 +129,19 @@ protocol specification. A batch of CloudEvents carries no semantic meaning and is not ordered. An [Intermediary](spec.md#intermediary) can add or remove batching as well as assign events to different batches. +The purpose, or semantic meaning, of an event is out of scope for the +CloudEvents specification. As long as the message being sent conforms to the +specification, then it is a valid CloudEvent. As an example that might not +be obvious to everyone, errors or exceptions can be tranmitted as CloudEvents. +It would then be up to the event producer to define the CloudEvents attribute +values that would be used, just like any other event it might generate. + +Since not all event producers generate their events as CloudEvents, there are +a set of [adapters](./adapters.md) defined that show how to map events from +some popular event producers into CloudEvents. These adapters are non-normative +but are the specification authors' best guess as to how the CloudEvents +attribute would be populated if the event producer produced them natively. + ### Non-Goals The following are considered beyond the scope of the specification: @@ -144,9 +159,9 @@ by those new to the concepts of CloudEvents. After much deliberation, the working group has come to the conclusion that routing is unnecessary in the spec: any protocol (e.g. HTTP, MQTT, XMPP, or a Pub/Sub bus) already defines semantics for routing. For example, the CloudEvents -[HTTP binding](http-protocol-binding.md) dictates headers and request body -contents. CloudEvents don't need to include a destination URL in the spec to be -HTTP compatible; the HTTP spec already includes one in the +[HTTP binding](bindings/http-protocol-binding.md) dictates headers and request +body contents. CloudEvents don't need to include a destination URL in the spec +to be HTTP compatible; the HTTP spec already includes one in the [Request-Line](https://tools.ietf.org/html/rfc2616#section-5.1). Routing information is not just redundant, it detracts. CloudEvents should @@ -189,17 +204,18 @@ CloudEvent specification. The CloudEvents specification set defines four different kinds of protocol elements that form a layered architecture model. -1. The [base specification](spec.md) defines an abstract information model made - up of attributes (key-value pairs) and associated rules for what constitutes - a CloudEvent. +1. The [base specification](spec.md) defines an abstract information + model made up of attributes (key-value pairs) and associated rules for what + constitutes a CloudEvent. 2. The [extensions](./spec.md#extension-context-attributes) add use-case specific and potentially overlapping sets of extension attributes and associated rules, e.g. to support different tracing standards. -3. The event format encodings, e.g. [JSON](json-format.md), define how the - information model of the base specification together with the chosen +3. The event format encodings, e.g. [JSON](formats/json-format.md), define how + the information model of the base specification together with the chosen extensions is encoded for mapping it to header and payload elements of an application protocol. -4. The protocol bindings, e.g. [HTTP](http-protocol-binding.md), defines how +4. The protocol bindings, e.g. [HTTP](bindings/http-protocol-binding.md), + defines how the CloudEvent is bound to an application protocol's transport frame, in the case of HTTP to the HTTP message. The protocol binding does not constrain how the transport frame is used, meaning that the HTTP binding can be used @@ -217,8 +233,8 @@ specification elsewhere makes it necessary for CloudEvents to define it. As stated in the [Design Goals](#design-goals) section, interoperability is a key objective of the specification. Therefore, there are places in the specification where restrictions are recommended. For example, in the -[Size Limits](./spec.md#size-limits) section it hints that event sizes should -not exceed 64KB. It is important to note that constraints such as these, +[Size Limits](./spec.md#size-limits) section it hints that event sizes +should not exceed 64KB. It is important to note that constraints such as these, where they are not mandated via a "MUST", are recommendations to increase the likelihood of interoperability between multiple implementations and deployments. Specific uses of the specification are free to ignore these @@ -311,7 +327,7 @@ related to one event source (where each event source is uniquely identified by its CloudEvents `source` attribute value). While the exact value used is producer defined, receivers of CloudEvents from a single event source can be assured that no two events will share the same `id` value. We are implicitly -making a claim here that no two events will share the same `id` value, but do +making a claim here that no two events will share the same `id` value, but do not provide an explanation as to how this is guaranteed, since this is out of the scope of this spec. The only exception to this is if some replay of the event is supported, and in those cases, the `id` @@ -370,7 +386,8 @@ Extension attributes should be kept minimal to ensure the CloudEvent can be properly serialized and transported. For example, the Event producers should consider the technical limitations that might be encountered when adding extensions to a CloudEvent. For example, the -[HTTP Binary Mode](http-protocol-binding.md#31-binary-content-mode) uses HTTP +[HTTP Binary Mode](bindings/http-protocol-binding.md#31-binary-content-mode) +uses HTTP headers to transport metadata; most HTTP servers will reject requests with excessive HTTP header data, with limits as low as 8kb. Therefore, the aggregate size and number of extension attributes should be kept minimal. @@ -382,8 +399,10 @@ formally adding them to the specification. ### JSON Extensions -As mentioned in the [Attributes](json-format.md#2-attributes) section of the -[JSON Event Format for CloudEvents](json-format.md) specification, CloudEvent +As mentioned in the [Attributes](formats/json-format.md#2-attributes) section +of the +[JSON Event Format for CloudEvents](formats/json-format.md) specification, +CloudEvent extension attributes are serialized as siblings to the specification defined attributes - meaning, at the top-level of the JSON object. The authors of the specification spent a long time considering all options and decided that this @@ -476,11 +495,11 @@ the incoming CloudEvent. There might exist special cases in which it is necessary to create a CloudEvent that contains another CloudEvent. Although the specification does not define nesting explicitly, it is possible. While the inner event will always be encoded -in a [stand-alone event format](spec.md#event-format), the outer event can be -either binary or structured mode. The `datacontenttype` attribute of the outer -event must not be set to `application/cloudevents+json` or any other media type -that is used to denote the usage of structured mode. A correct example of event -nesting would be: +in a [stand-alone event format](spec.md#event-format), the outer event +can be either binary or structured mode. The `datacontenttype` attribute of +the outer event must not be set to `application/cloudevents+json` or any other +media type that is used to denote the usage of structured mode. A correct +example of event nesting would be: ``` Content-Type: application/json @@ -688,10 +707,10 @@ including being both a producer and a consumer of events. delegation choice of the producer. In practice, middleware can take on the role of a - [Producer](spec.md#producer) when it changes the semantic meaning of an - event, a [Consumer](spec.md#consumer) when it takes action based on an event, - or [Intermediary](spec.md#intermediary) when it routes events without making - semantic changes. + [Producer](spec.md#producer) when it changes the semantic meaning of + an event, a [Consumer](spec.md#consumer) when it takes action based + on an event, or [Intermediary](spec.md#intermediary) when it routes + events without making semantic changes. 4. Frameworks and other abstractions make interactions with the event platform infrastructure simpler, and often expose common API surface areas for @@ -709,9 +728,9 @@ including being both a producer and a consumer of events. in all events from today's game (subject) of a team in a league (topic of interest) but wanting to handle reports of "goal" differently than reports of "substitution". For this, the framework will need a suitable metadata - discriminator that frees it from having to understand the event details. To be - clear, the suitable metadata discriminator should be populated by the producer, - and would not be the responsibility of the framework. + discriminator that frees it from having to understand the event details. To + be clear, the suitable metadata discriminator should be populated by the + producer, and would not be the responsibility of the framework. ### Value Proposition diff --git a/proprietary-specs.md b/cloudevents/proprietary-specs.md similarity index 78% rename from proprietary-specs.md rename to cloudevents/proprietary-specs.md index 45f9cf12e..03826cba1 100644 --- a/proprietary-specs.md +++ b/cloudevents/proprietary-specs.md @@ -1,5 +1,7 @@ # CloudEvent Specs for Proprietary Protocols and Encodings + + Disclaimer: CloudEvents does not endorse these protocols or specs, and does not ensure that they are up to date with the current version of CloudEvents. That is the responsibility of the respective project maintainers. @@ -9,9 +11,9 @@ the responsibility of the respective project maintainers. **Want to add a binding to a proprietary transport?** -- Create a spec that follows the structure of an existing binding specification (e.g. [http](http-protocol-binding.md) or [amqp](amqp-protocol-binding.md)) - this will help SDK development. +- Create a spec that follows the structure of an existing binding specification (e.g. [http](bindings/http-protocol-binding.md) or [amqp](bindings/amqp-protocol-binding.md)) - this will help SDK development. - **NOTES:** - - The spec must be publically accessible and managed by the proposing organization. + - The spec must be publicly accessible and managed by the proposing organization. - The spec must clearly state the version(s) of CloudEvents supported. - Open a pull request against this file. - Respond to any comments on the pull request and potentially join one of the regularly scheduled working group sessions. diff --git a/source-event-action.png b/cloudevents/source-event-action.png similarity index 100% rename from source-event-action.png rename to cloudevents/source-event-action.png diff --git a/spec.md b/cloudevents/spec.md similarity index 96% rename from spec.md rename to cloudevents/spec.md index c994a26b1..bc8cd7ae0 100644 --- a/spec.md +++ b/cloudevents/spec.md @@ -1,4 +1,4 @@ -# CloudEvents - Version 1.0.1 +# CloudEvents - Version 1.0.2 ## Abstract @@ -32,7 +32,7 @@ provide interoperability across services, platforms and systems. Event Formats specify how to serialize a CloudEvent with certain encoding formats. Compliant CloudEvents implementations that support those encodings MUST adhere to the encoding rules specified in the respective event format. All -implementations MUST support the [JSON format](json-format.md). +implementations MUST support the [JSON format](formats/json-format.md). For more information on the history, development and design rationale behind the specification, see the [CloudEvents Primer](primer.md) document. @@ -118,9 +118,9 @@ information. #### Event Format An Event Format specifies how to serialize a CloudEvent as a sequence of bytes. -Stand-alone event formats, such as the [JSON format](json-format.md), specify -serialization independent of any protocol or storage medium. Protocol Bindings -MAY define formats that are dependent on the protocol. +Stand-alone event formats, such as the [JSON format](formats/json-format.md), +specify serialization independent of any protocol or storage medium. Protocol +Bindings MAY define formats that are dependent on the protocol. #### Message @@ -187,8 +187,9 @@ string-encoding for each type that MUST be supported by all implementations. inclusive. This is the range of a signed, 32-bit, twos-complement encoding. Event formats do not have to use this encoding, but they MUST only use `Integer` values in this range. - - String encoding: Integer portion of the JSON Number per + - String encoding: Integer component of the JSON Number per [RFC 7159, Section 6](https://tools.ietf.org/html/rfc7159#section-6) + optionally prefixed with a minus sign. - `String` - Sequence of allowable Unicode characters. The following characters are disallowed: - the "control characters" in the ranges U+0000-U+001F and U+007F-U+009F (both @@ -284,14 +285,14 @@ The following attributes are REQUIRED to be present in all CloudEvents: - An absolute URI is RECOMMENDED - Examples - Internet-wide unique URI with a DNS authority. - - https://github.com/cloudevents - - mailto:cncf-wg-serverless@lists.cncf.io + - `https://github.com/cloudevents` + - `mailto:cncf-wg-serverless@lists.cncf.io` - Universally-unique URN with a UUID: - - urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 + - `urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66` - Application-specific identifiers - - /cloudevents/spec/pull/123 - - /sensors/tn-1234567/alerts - - 1-555-123-4567 + - `/cloudevents/spec/pull/123` + - `/sensors/tn-1234567/alerts` + - `1-555-123-4567` #### specversion @@ -342,17 +343,17 @@ on the definition of OPTIONAL. - Description: Content type of `data` value. This attribute enables `data` to carry any type of content, whereby format and encoding might differ from that of the chosen event format. For example, an event rendered using the - [JSON envelope](./json-format.md#3-envelope) format might carry an XML payload - in `data`, and the consumer is informed by this attribute being set to + [JSON envelope](formats/json-format.md#3-envelope) format might carry an XML + payload in `data`, and the consumer is informed by this attribute being set to "application/xml". The rules for how `data` content is rendered for different `datacontenttype` values are defined in the event format specifications; for example, the JSON event format defines the relationship in - [section 3.1](./json-format.md#31-handling-of-data). + [section 3.1](formats/json-format.md#31-handling-of-data). For some binary mode protocol bindings, this field is directly mapped to the respective protocol's content-type metadata property. Normative rules for the binary mode and the content-type metadata mapping can be found in the - respective protocol + respective protocol. In some event formats the `datacontenttype` attribute MAY be omitted. For example, if a JSON format event has no `datacontenttype` attribute, then it is @@ -409,8 +410,8 @@ on the definition of OPTIONAL. created" event, and the `id` uniquely identifies the event instance to distinguish separate occurrences of a same-named blob having been created; the name of the newly created blob is carried in `subject`: - - `source`: https://example.com/storage/tenant/container - - `subject`: mynewfile.jpg + - `source`: `https://example.com/storage/tenant/container` + - `subject`: `mynewfile.jpg` #### time diff --git a/cloudevents/translated/zh-cn/README_CN.md b/cloudevents/translated/zh-cn/README_CN.md new file mode 100644 index 000000000..b51f03532 --- /dev/null +++ b/cloudevents/translated/zh-cn/README_CN.md @@ -0,0 +1,133 @@ +# CloudEvents 中文规范 + + + +![CloudEvents logo](https://github.com/cncf/artwork/blob/master/projects/cloudevents/horizontal/color/cloudevents-horizontal-color.png) + +## Purpose/规范目的 + +This Chinese spec aims to provide a fast and brief introduction of CloudEvents +in Chinese for people who are new to CloudEvents. +Most of the content is translated from the original English version. +It is strongly recommended to read the English version if you find anything lost in translation. + +这份中文规范是为了让更多刚接触CloudEvents的中国开发者,能在最短时间内对CloudEvents有一个全局的认识。本文档中的大多内容翻译自英文版的CloudEvents规范,如果你在阅读中发现一些难以理解的翻译,请参阅英文版文档。 + +## CloudEvents + +事件(Events)在现代系统中无处不在。但不同的事件生产者往往用不同的规范来描述自己的事件。 + +对事件的统一描述的匮乏意味着开发者必须不断重新学习如何消费不同定义的事件。它同样限制了那些用来帮助事件数据完成跨环境传输的库(如SDKs)、工具(如事件路由器)和基础设施(如事件追踪系统)的发展。总体来看,这种匮乏严重阻碍了事件数据的可移植性和生产力。 + +CloudEvents是一个以通用格式来描述事件数据的标准。它提供了事件在服务、平台和系统中的互操作性。 + +从主流云厂商到SaaS公司,工业界对CloudEvents兴趣浓烈。CloudEvents项目由[云原生计算基金会](https://cncf.io)托管,于[2018/05/15](https://docs.google.com/presentation/d/1KNSv70fyTfSqUerCnccV7eEC_ynhLsm9A_kjnlmU_t0/edit#slide=id.g37acf52904_1_41) 成为云原生沙箱级项目。 + +## CloudEvents 文件 + +现有文件如下: + +| | 最新版本 | 工作草案 | +| :---------------------------- | :-----------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------: | +| **核心标准:** | +| CloudEvents | [v1.0.2](../../spec.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md) | +| | +| **可选标准:** | +| AMQP Protocol Binding | [v1.0.2](../../bindings//amqp-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/amqp-protocol-binding.md) | +| AVRO Event Format | [v1.0.2](../../formats/avro-format.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/avro-format.md) | +| HTTP Protocol Binding | [v1.0.2](../../bindings/http-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/http-protocol-binding.md) | +| JSON Event Format | [v1.0.2](../../formats/json-format.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/json-format.md) | +| Kafka Protocol Binding | [v1.0.2](../../bindings/kafka-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/kafka-protocol-binding.md) | +| MQTT Protocol Binding | [v1.0.2](../../bindings/mqtt-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/mqtt-protocol-binding.md) | +| NATS Protocol Binding | [v1.0.2](../../bindings/nats-protocol-binding.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/nats-protocol-binding.md) | +| WebSockets Protocol Binding | - | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/websockets-protocol-binding.md) | +| Protobuf Event Format | | [v1.0-rc1](https://github.com/cloudevents/spec/blob/main/cloudevents/formats/protobuf-format.md) | +| Web hook | [v1.0.2](../../http-webhook.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/http-webhook.md) | +| | +| **附加文件:** | +| CloudEvents Adapters | - | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/adapters.md) | +| CloudEvents SDK Requirements | - | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/SDK.md) | +| Documented Extensions | - | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/documented-extensions.md) | +| Primer | [v1.0.2](../../primer.md) | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/primer.md) | +| Proprietary Specifications | - | [WIP](https://github.com/cloudevents/spec/blob/main/cloudevents/proprietary-specs.md) | + +推荐先行阅读[入门文档](primer_CN.md)了解CloudEvents规范的目标和设计理念,再阅读[核心规范](spec_CN.md)。 + +由于并非所有事件生产者都默认生产符合CloudEvents规范的事件,因此可以用[CloudEvents适配器](https://github.com/cloudevents/spec/blob/main/cloudevents/adapters.md) +来将现有的事件与CloudEvents做适配。 + +## SDKs + +除了上述文档,我们还提供了[SDK 提议](../../SDK.md)以及一些编程语言的SDK: + +- [CSharp](https://github.com/cloudevents/sdk-csharp) +- [Go](https://github.com/cloudevents/sdk-go) +- [Java](https://github.com/cloudevents/sdk-java) +- [Javascript](https://github.com/cloudevents/sdk-javascript) +- [PHP](https://github.com/cloudevents/sdk-php) +- [PowerShell](https://github.com/cloudevents/sdk-powershell) +- [Python](https://github.com/cloudevents/sdk-python) +- [Ruby](https://github.com/cloudevents/sdk-ruby) +- [Rust](https://github.com/cloudevents/sdk-rust) + +## 社区 + +在社区里,你可以了解到更多致力于搭建一个动态、云原生的生态系统的成员和组织。 +他们不断尝试提升现有系统和CloudEvents间的互操作性和兼容性。 + +- 我们的 [管理](../../../community/GOVERNANCE.md) 文档。 +- 如何通过 issues 和 PR 为我们做[贡献](../../../community/CONTRIBUTING.md) 。 +- [贡献者](../../../community/contributors.md): + 是指那些帮助我们制定规范或是积极活跃在CloudEvents规范相关工作的成员和组织。 +- [Demos & open source](../../../community/README.md) + -- 如果你希望向我们分享关于你对CloudEvents的使用,请通过提交PR让我们看到。 + +## 步骤 + +CloudEvents项目 [旨在](primer_CN.md#design-goals)制定一个能够提升不同事件系统(如生产者和消费者)之间互操作性和兼容性 +的[标准](spec_CN.md)。 + +为了完成这个目标,这个项目必须描述: + +- 一系列能够提升互操作性的用来描述事件的属性 +- 一个或多个通用架构,这些架构必须是当下活跃的或是正在计划被完成的 +- 事件是如何在一种或多种协议下从生产者传输到消费者的 +- 识别并解决任何能提升互操作性的问题 + +## 联系方式 + +邮件联系方式如下: + +- 发送EMail至: [cncf-cloudevents](mailto:cncf-cloudevents@lists.cncf.io) +- 订阅地址: https://lists.cncf.io/g/cncf-cloudevents +- 存档地址: https://lists.cncf.io/g/cncf-cloudevents/topics + +添加一个 #cloudevents Slack 频道: +[CNCF's Slack workspace](http://slack.cncf.io/). + +SDK相关的评论和问题: + +- 发送EMail至: [cncf-cloudevents-sdk](mailto:cncf-cloudevents-sdk@lists.cncf.io) +- 订阅地址: https://lists.cncf.io/g/cncf-cloudevents-sdk +- 存档地址: https://lists.cncf.io/g/cncf-cloudevents-sdk/topics +- Slack: #cloudeventssdk on [CNCF's Slack workspace](http://slack.cncf.io/) + +## 会议时间 + +会议日期请查看[CNCF 公开活动日历](https://www.cncf.io/community/calendar/). +CloudEvents规范由 +[CNCF Serverless Working Group](https://github.com/cncf/wg-serverless) 开发完成。 +这个工作组每周四的上午9点(美国-太平洋时间)通过Zoom开展视频会议。 +([World Time Zone Converter](http://www.thetimezoneconverter.com/?t=9:00%20am&tz=San%20Francisco&)): + +查看 +[meeting minutes doc](https://docs.google.com/document/d/1OVF68rpuPK5shIHILK9JOqlZBbfe91RNzQ7u_P7YCDE/edit#) +获得如何加入会议的最新信息。 + +历史会议录像在 +[here](https://www.youtube.com/playlist?list=PLj6h78yzYM2Ph7YoBIgsZNW_RGJvNlFOt). + +工作组会定期举办与主流会议一致的线下会议。查看 +[meeting minutes doc](https://docs.google.com/document/d/1OVF68rpuPK5shIHILK9JOqlZBbfe91RNzQ7u_P7YCDE/edit#) +了解更多未来计划。 + diff --git a/cloudevents/translated/zh-cn/SDK_CN.md b/cloudevents/translated/zh-cn/SDK_CN.md new file mode 100644 index 000000000..55cf6e5db --- /dev/null +++ b/cloudevents/translated/zh-cn/SDK_CN.md @@ -0,0 +1,103 @@ +# CloudEvents SDK 要求 + +本文档旨在描述对新建CloudEvents软件开发工具(SDKs)的最低要求集。开发者设计并实现这些SDKs来增强并加速CloudEvents的集成。以下SDKs作为社区的重要成果将会被CloudEvents团队支持并维护下去: + +- [CSharp](https://github.com/cloudevents/sdk-csharp) +- [Go SDK](https://github.com/cloudevents/sdk-go) +- [Java SDK](https://github.com/cloudevents/sdk-java) +- [JavaScript SDK](https://github.com/cloudevents/sdk-javascript) +- [PHP SDK](https://github.com/cloudevents/sdk-php) +- [PowerShell](https://github.com/cloudevents/sdk-powershell) +- [Python SDK](https://github.com/cloudevents/sdk-python) +- [Ruby SDK](https://github.com/cloudevents/sdk-ruby) +- [Rust SDK](https://github.com/cloudevents/sdk-rust) + +本文档为CloudEvents 的SDK开发者提供了指导和要求。它将伴随着ClodEvents核心规范不断更新下去。 + +## 贡献被接受的条件 + +CloudEvents团队作为一个开源的社区十分欢迎新的成员以及他们的贡献。但为了确保新贡献的SDK能够被支持和维护,CloudEvents小组要求必须确保以下内容: + +- 每个SDK都需要活跃的联系人或组织支持。 +- 每个SDK都必须支持最新版(N)以及前一(N-1)大版本的[CloudEvents规范](spec_CN.md)\*。 +- 在一个大版本中,SDK只需要支持它最新的小版本即可。 + +我们不强制要求SDK对候选版本提供支持,但强烈建议作者这样做。 + +\* 注意:v1.0是一个特殊的情况,因此我们建议只要v1.0还是最新版本,SDKs在支持它的同时也应该支持v0.3。 + +## 技术性要求 + +每个SDK都必须满足以下要求: + +- 同时支持CloudEvents规范的里程碑版本和正在开发中的版本。 + - 将CloudEvents标准事件经过编码存在特定传输协议的消息中。 + - 将特定的传输层消息解码成为CloudEvents标准格式事件。 +- 使用常用的编程语言实现SDK。 + - 使用这些编程语言的流行版本。 +- 同时支持HTTP传输中的`structured` 和 `binary` 两种模型。 + +### 对象模型结构建议 + +每个SDK都应该提供一种用来表示标准事件的通用格式,这种格式是类/对象/结构这样的形式。 + +SDK应使用户能够绕过 CloudEvents 事件传输协议的特定编码和解码。事件对象的一般传输流程应该是: + +``` +事件 (-> 消息) -> 网络传输 +``` + +以及 + +``` +网络传输 (-> 消息) -> 事件 +``` +开发者不需要为SDK实现一个传输层的包装类,重点应该是实现当前编程语言与高等级的`事件`对象的交互,并提供工具来获取`事件`,以及将`事件`转换为你选择的传输实现能使用的格式。 + +Event作为一个高层级的概念,它的SDK需要能帮助以下任务: + +1. 构造一个事件. +1. 将一个事件以给定的传输协议和编码方式进行编码(如果有需要的话将事件编写入传输消息中)。 +1. 将一个事件以给定传输协议的消息、请求或响应格式进行解码。 + +#### 构建一个事件 + +SDK应该提供一个方便的方法来通过单条或多条消息构建事件。SDK的使用者需要一种方法来快速地构建CloudEvents格式的事件或是将他们的事件数据转换为CloudEvents格式的事件。在实践中事件构建通常有两种形式。 + +1. 事件创建 + +- "我有一些还不是CloudEvent的数据,我希望将它们变成CloudEvent。" +2. 事件转换 + +- "我有一个CloudEvent格式的事件,我希望它变成不同的事件。" +- "我有一个CloudEvent格式的事件,我希望它转换不同的格式。" + +事件的创建是SDK中最常见的用法。 + +事件转换可以通过存取模式实现,比如添加getter或setter方法。 但是直接的key访问或者是named-key访问函数也是可以利用的。 + +无论是那种情况,必须要有一个根据参数集来验证最终事件对象的方法,在参数集中,CloudEvents规范的版本是至关重要的。 + +#### 编码/解码一个事件 + +每个SDK应该支持在传输协议和编码方面对一个事件进行编码和解码。结构化的编码是最容易支持的,因为它就是`json`格式。但是`Binary`对于不同的传输协议而言就可能完全不同了。 + +#### 数据 + +事件数据的访问则有很多种情况需要考虑,比如事件可能被编码为`base64`格式的结构化数据,或是`json`这种传输格式。SDK必须要提供方法将事件数据从这些格式中转换为本地的格式。 + +#### 扩展 + +SDK支持CloudEvents的扩展也是很常见的,但是提供一个能镜像数据访问的方法也可以实现。 + +#### 验证 + +对于每个事件的验证都必须是可行的。同时验证功能必须要将CloudEvents规范的版本考虑在内。对于SDK的所有要求都要根据不同版本的规范一一实现。 + +## 文档 + +每个SDK必须提供不同的例子,最少需要提供一个基于HTTP传输并实现以下功能的例子: + +- 构建一个事件。 +- 编码并发送一个构建好的事件。 +- 接收并解码一个事件。 diff --git a/cloudevents/translated/zh-cn/adapters_CN.md b/cloudevents/translated/zh-cn/adapters_CN.md new file mode 100644 index 000000000..024e2eb43 --- /dev/null +++ b/cloudevents/translated/zh-cn/adapters_CN.md @@ -0,0 +1,7 @@ +# CloudEvents 适配器 + +由于并不是所有事件生产者在本地都以CloudEvents的格式生产事件,因此需要一些"适配器"将这些非CloudEvents格式的事件转换为CloudEvents。要完成这个转换,通常需要将非CloudEvents格式事件的元数据抽取出来,用作CloudEvents的属性。为了能更好地提升适配器间不同实现的互操作性,以下文件列出了推荐使用的算法: + +- [AWS S3](../../adapters/aws-s3.md) +- [GitHub](../../adapters/github.md) +- [GitLab](../../adapters/gitlab.md) diff --git a/cloudevents/translated/zh-cn/documented-extensions_CN.md b/cloudevents/translated/zh-cn/documented-extensions_CN.md new file mode 100644 index 000000000..7f2898643 --- /dev/null +++ b/cloudevents/translated/zh-cn/documented-extensions_CN.md @@ -0,0 +1,21 @@ +# CloudEvents 扩展属性 + +[CloudEvents 规范](spec_CN.md)定义了一系列用来将通用事件转换为CloudEvent的元数据属性。该文档中指定的属性列表代表了作者认为在大多数情况下最可能用到的属性最小集。 + +在本文档中定义了一些额外的属性。这些属性尽管不像[CloudEvents 规范](spec_CN.md)中的属性那样常见,但精准使用这些属性,仍能为提高互操作性的程度提供帮助。这种额外属性的机制,同样允许新属性在被纳入到[CloudEvents 规范](spec_CN.md)之前,能以试验的形式被定义。 + +[CloudEvents 规范](spec_CN.md)的实现中不会限制必须使用本文档中提到的那些扩展属性。本文档中定义的扩展属性并不是正式的、稳定的,相反它们可能随时被修改,甚至删除。因此,引入本文档中的这些属性并不需要满足像[CloudEvents 规范](spec_CN.md)中其它属性那样的成熟度和流行性。要想定义一个收录在本文档中的扩展属性,除了正常的PR检查流程外,还需要至少两名[有投票权的成员](../../../community/GOVERNANCE.md#membership)在PR中留言支持。如果这个PR的作者本身就具有投票权,那么只需要另一名成员投票支持即可。 + +## 使用 + +任何对扩展属性的支持都不是必要的。当一个扩展属性使用了[RFC 2199](https://www.ietf.org/rfc/rfc2119.txt) 中的关键词(如MUST、SHOULD、MAY等)时,对这些关键词的使用仅适用于使用了这个扩展属性的事件。 + +扩展属性尽管没有定义在CloudEvents的核心规范中,它们同样必须遵守格式和协议绑定规范中定义的序列化规则。详情请见[扩展上下文属性](spec_CN.md#extension-context-attributes) + +## 现有的扩展 + +- [Dataref (Claim Check Pattern)](../../extensions/dataref.md) +- [Distributed Tracing](../../extensions/distributed-tracing.md) +- [Partitioning](../../extensions/partitioning.md) +- [Sampling](../../extensions/sampledrate.md) +- [Sequence](../../extensions/sequence.md) diff --git a/cloudevents/translated/zh-cn/http-webhook_CN.md b/cloudevents/translated/zh-cn/http-webhook_CN.md new file mode 100644 index 000000000..6e48f1a5a --- /dev/null +++ b/cloudevents/translated/zh-cn/http-webhook_CN.md @@ -0,0 +1,265 @@ +# 用于事件传输的 HTTP 1.1 Web Hooks - 1.0.2(制作中) + +## 摘要 + +"Webhooks"是一种被广泛应用在应用和HTTP终端间传输通知消息的模式。尽管这种模式已经被广泛使用,但目前仍然没有一个对Web Hooks的正式定义。本规范旨在制定一个用于 [CNCF CloudEvents][ce]的Web Hooks的定义,但本定义仅作用于CloudEvents范围内。 + +## 文档状态 + +这份文档是一份仍在制作中的工作草案。 + +## 目录 + +1. [简介](#1-introduction) + +- 1.1. [一致性](#11-conformance) +- 1.2. [与HTTP的关系](#12-relation-to-httphttp) + +2. [传输通知](#2-delivering-notifications) +3. [认证](#3-authorization) +4. [滥用保护](#4-abuse-protection) +5. [引用](#5-references) + +## 1. Introduction/简介 + +["Webhooks"][webhooks]是一种被广泛应用在应用和HTTP终端间传输通知消息的模式。维护通知可用的服务端应用,允许其它应用注册成为一个接收这些通知的HTTP终端。 + +本规范根据发送者是如何下发通知、在事件传输中保护传输目标的认证模型以及一个保护发送者不被滥用成为HTTP洪水攻击发起者的注册握手机制等内容制定了一套HTTP方法。 + +### 1.1. Conformance/一致性 + +本文档中的关键词 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD","SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 需要按照 [RFC2119][rfc2119] 中的描述来理解。 + +### 1.2. Relation to HTTP/与HTTP的关系 + +本规范规定了一系列规则,以限制具体[HTTP 方法][rfc7231-section-4]和头部的使用以及处理。 + +本规范同样适用于HTTP/2 ([RFC7540][rfc7540]),因为它本身就与HTTP 1.1 的语义兼容。 + +## 2. Delivering notifications/传输通知 + +### 2.1. 传输请求 + +通知是通过HTTP请求的方式传输的,在响应中携带了该传输的状态。 + +在连接中必须使用HTTP-over-TLS (HTTPS) [RFC2818][rfc2818]。 + +用来传输请求的HTTP方法必须是[POST类型][post]. + +在HTTP 头部中[`Content-Type`][content-type]必须被指定,同时每个请求都必须要携带该内容类型下的有效负载(即有效内容)。本规范不允许没有携带有效负载的请求(比如某些通知请求的全部数据都在HTTP头部而没有内容数据)。 + +除上述限制外,本规范不会更多地限制通知的内容,同样不会强制用来传输的[HTTP 目标资源][rfc7230-section-5-1]。 + +如果传输目标支持并要求[滥用保护](#4-abuse-protection)机制,则传输的请求必须包含`WebHook-Request-Origin`头部。`WebHook-Request-Origin`头部的值是一个能标识出发送者的DNS域名表达形式。 + +### 2.2. 传输响应 + +传输响应可能会包含一种提供具体状态信息的负载,这些信息是用来处理错误的。本规范不会去定义这种负载。 + +服务端的响应必须不能包含[3xx HTTP 状态码][3xx]同时客户端也不能使用此类状态码进行跳转。 + +一旦请求被接收、处理了且在响应中包含了处理细节的负载,则响应必须要包含[200 OK][200]或是[201 Created][201]状态码。在这种情形下,该响应必须要包含[`Content-Type`][content-type]头部。 + +如果请求被接收、处理了,但是请求中没有有效负载,则响应中必须包含[201 Created][201] or [204 No Content][204]状态码。 + +如果请求被接收了,但尚未被处理或是处理状态仍是未知的,则响应中必须包含[202 Accepted][202]状态码。 + +如果一个传输目标已经过期了,但HTTP站点仍然存在,则HTTP站点应当返回一个[410 Gone][410]状态码,同时发送者应当不再向该目标发送更多的通知。 + +如果传输目标因为超过请求限制而无法处理请求,它应当返回一个[429 Too Many Requests][429]状态码,同时必须包含[`Retry-After`][retry-after]头部。发送者必须观察Retry-After的值,直到指定时间后再发送后续请求。 + +如果传输因为通知格式不能被理解而被拒绝接收,则响应中必须包含[415 Unsupported Media Type][415]状态码。 + +其它的所有错误处理情形都需要参照[RFC7231][rfc7231]的表述。 + +## 3. Authorization/认证 + +传输请求必须要使用以下两种方式之一进行认证,这两种方法都依赖OAuth 2.0 Bearer 令牌 [RFC6750][rfc6750] 模型。 + +传输目标必须同时支持两种认证方式。 + +客户端可以使用任何基于令牌的认证方案。令牌可以采取任意形式,可以是标准化的令牌格式或是简单的key表达式。 + +禁止使用任何基于挑战的认证方案。 + +### 3.1. 头部请求认证字段 + +访问令牌是在HTTP/1.1中定义的头部[`Authorization`][authorization]字段中携带的。 + +对于[OAuth 2.0 Bearer][bearer] 令牌而言,"Bearer"方案必须被使用。 + +示例: + +```text +POST /resource HTTP/1.1 +Host: server.example.com +Authorization: Bearer mF_9.B5f-4.1JqM +``` + +### 3.2 URI 查询参数 + +当通过HTTP请求URI发送访问令牌时,客户需要按照"统一资源标志符 (URI): 通用句法" [RFC3986][rfc3986]中定义的方式,将"access_token"参数当作请求URI的查询内容进行发送。 + +例如,客户端生成如下的HTTP请求: + +```text +POST /resource?access_token=mF_9.B5f-4.1JqM HTTP/1.1 +Host: server.example.com +``` +HTTP请求URI可能会包含其它特定的参数,此时必须正确地使用"&"(ASCII code 38)字符,将"access_token"参数与其它特定的参数分割开来。 + + +例如: + + https://server.example.com/resource?access_token=mF_9.B5f-4.1JqM&p=q + +使用URI查询查询参数这种形式的客户端,必须要发送一个缓存控制的头部并包含"no-store"选项。服务端成功(2XX 状态)的响应必须包含声明了"private"选项的缓存控制头部。 + +因为URI方法天然的安全弱点(参照[RFC6750, Section 5][rfc6750]),比如包含访问令牌的URI极有可能被记录,除了在无法使用"Authorization"字段的场景下,你都不应该这种方式来发送发送访问令牌。其它在[RFC6750][rfc6750]中告诫在此处同样适用。 + +## 4. Abuse Protection/滥用保护机制 + +任何允许任意HTTP终端注册或是传输通知的系统都可能受到潜在的滥用攻击,比如一些人恶意或是无意的注册一些不期望收到请求的系统地址或是一些注册方无法被认证的地址。在极端情况下,一个实现通知的网络基础设施可能会被滥用成为DoS攻击的发起方。 + +为了保护发送不受恶意滥用伤害,合法的传输目标需要表明它同意接收这条传输给它的通知。 + +上述的传输同意模式是通过下面的验证握手机制实现的。握手可以在注册时执行或是被当作一个被传输前的请求在传输前执行。 + +在这里,理解握手机制并不是为了建立一个认证上下文是尤为重要的。握手机制只是用来保护发送方不会将通知发送到并不想接收的接受者那里去。尽管在本规范中强制使用了认证模型,但这种模型无法保护那些没有实现访问控制但又不想接收不需要流量的网站,因此在这里`Authorization`是没有用的。 + +传输目标应该支持滥用保护特性。如果一个目标端不支持此特性,发送方可能会选择不发送到这个目标端,或是以一个特别低速率去发送请求。 + +### 4.1. 验证请求 + +验证请求使用了HTTP的[OPTIONS][options]方法。请求会被重定向到注册时指定的URI资源上去。 + +有了验证请求,发送方向目标端索要发送通知的权限,验证请求可以声明一个希望的请求速率(如每分钟收到多少请求)。 + +传输目标将会响应一个权限声明以及允许的请求速率。 + +下面就是在验证请求中使用的头部字段。 + +#### 4.1.2. WebHook-Request-Origin + +希望发送通知的发送者必须要在验证请求和请求权限中包含`WebHook-Request-Origin`字段。这个字段必须要包含一个能标识发送系统的DNS表达式(如eventemitter.example.com)。这个字段的值是用来标识所有发送方的实例,而不是一个单独主机。 + +一旦握手和权限被承认,发送者必须在每个请求中都包含`WebHook-Request-Origin`这个字段以及它对应的值。 + + +示例: + +```text +WebHook-Request-Origin: eventemitter.example.com +``` + +#### 4.1.3. WebHook-请求回调 + +`WebHook-Request-Callback`是一个可选的用来补充`WebHook-Request-Origin`的字段。它允许传输目标通过HTTPs回调的方式异步地同意权限请求。 + +如果接收程序没有清楚地表明支持握手机制,管理员仍然可以在日志中找到回调的URL,再手动调用它来授权访问。 + + +传输目标通过发布一个给定URL的HTTPS GET 或 POST请求来授权访问。HTTP GET请求通过浏览器来手动执行。 + +传输目标可能会在回调中包含`WebHook-Allowed-Rate`字段。 + +这个URL没有正式的限制条件,但它应该包含一个能标识出传输目标的标识符,同时它应该包含一个密钥来使URL更加难猜,从而使第三方就无法轻松地冒充传输目标。 + + +示例: + +```text +WebHook-Request-Callback: https://example.com/confirm?id=12345&key=...base64... +``` + +#### 4.1.4. WebHook-请求速率 + +发送者可能通过`WebHook-Request-Rate`字段来向接受者请求一个合适的发送请求速率。这个值以字符串形式来表示一个大于0的整数,它代表着每分钟发送多少个请求。 + +比如,下面的例子在索要一个每分钟发送120次请求的权限: + + +```text +WebHook-Request-Rate: 120 +``` + +### 4.2. 验证响应 + +当且仅在传输目标允许事件传输的情况下,它必须要通过`WebHook-Allowed-Origin` 和`WebHook-Allowed-Rate`字段来响应请求。 + +如果传输目标选择回调的方式来授权,则它不会使用响应字段。 + +如果传输目标不允许事件传输或是不期望收到事件但仍想处理HTTP OPTIONS 方法,当前的响应则不应该被当作批准授权,握手机制此时不应该依靠状态码来判断。如果传输目标不希望处理HTTP OPTIONS方法,它应该以405状态码来响应,就像它不支持HTTP OPTIONS一样。 + +OPTIONS响应应该包含[Allow][allow]字段来表明[POST][post]方法已经被允许了。其它方法类型可能也被允许了,但它们并不在本规范的讨论范围内。 + +#### 4.2.1. WebHook-允许源头 + +当传输目标同意通知事件的传输时,必须要返回`WebHook-Allowed-Origin`字段。该字段的值必须是请求中`WebHook-Request-Origin`字段中发送方的名称,或者是一个单独的星号(\*)表明传输目标同意来自任意源头的通知。 + +```text +WebHook-Allowed-Origin: eventemitter.example.com +``` + +或 + +```text +WebHook-Allowed-Origin: * +``` + +#### 4.2.2. WebHook-允许速率 + +当请求中包含`WebHook-Request-Rate`字段时,响应中必须包含`WebHook-Allowed-Rate`字段。其它情况下`WebHook-Allowed-Rate`字段应当被返回。 + +本字段的值用来表示同意发送通知的速率。它可以是一个单独的星号(\*)或是字符串形式来表示一个大于0的整数。星号代表对速率没有限制。整数代表着每分钟接收多少个请求。对于请求速率大于允许接收速率的情形,发送方应当考虑限流。通过拒绝请求来限流可以参考HTTP的[429 过多请求][429]状态码。 + + +示例: 下面的HTTP头部允许每分钟100次请求的发送速率: + +```text +WebHook-Allowed-Rate: 100 +``` + +## 5. References/引用 + +- [RFC2119][rfc2119] Key words for use in RFCs to Indicate Requirement Levels +- [RFC2818][rfc2818] HTTP over TLS +- [RFC6750][rfc6750] The OAuth 2.0 Authorization Framework: Bearer Token Usage +- [RFC6585][rfc6585] Additional HTTP Status Codes +- [RFC7230][rfc7230] Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and + Routing +- [RFC7231][rfc7231] Hypertext Transfer Protocol (HTTP/1.1): Semantics and + Content +- [RFC7235][rfc7235] Hypertext Transfer Protocol (HTTP/1.1): Authentication +- [RFC7540][rfc7540] Hypertext Transfer Protocol Version 2 (HTTP/2) + +[ce]: ./spec_CN.md +[webhooks]: https://progrium.github.io/blog/2007/05/03/web-hooks-to-revolutionize-the-web/index.html +[content-type]: https://tools.ietf.org/html/rfc7231#section-3.1.1.5 +[retry-after]: https://tools.ietf.org/html/rfc7231#section-7.1.3 +[authorization]: https://tools.ietf.org/html/rfc7235#section-4.2 +[allow]: https://tools.ietf.org/html/rfc7231#section-7.4.1 +[post]: https://tools.ietf.org/html/rfc7231#section-4.3.3 +[options]: https://tools.ietf.org/html/rfc7231#section-4.3.7 +[3xx]: https://tools.ietf.org/html/rfc7231#section-6.4 +[200]: https://tools.ietf.org/html/rfc7231#section-6.3.1 +[201]: https://tools.ietf.org/html/rfc7231#section-6.3.2 +[202]: https://tools.ietf.org/html/rfc7231#section-6.3.3 +[204]: https://tools.ietf.org/html/rfc7231#section-6.3.5 +[410]: https://tools.ietf.org/html/rfc7231#section-6.5.9 +[415]: https://tools.ietf.org/html/rfc7231#section-6.5.13 +[429]: https://tools.ietf.org/html/rfc6585#section-4 +[bearer]: https://tools.ietf.org/html/rfc6750#section-2.1 +[rfc2119]: https://tools.ietf.org/html/rfc2119 +[rfc3986]: https://tools.ietf.org/html/rfc3986 +[rfc2818]: https://tools.ietf.org/html/rfc2818 +[rfc6585]: https://tools.ietf.org/html/rfc6585 +[rfc6750]: https://tools.ietf.org/html/rfc6750 +[rfc7159]: https://tools.ietf.org/html/rfc7159 +[rfc7230]: https://tools.ietf.org/html/rfc7230 +[rfc7230-section-3]: https://tools.ietf.org/html/rfc7230#section-3 +[rfc7231-section-4]: https://tools.ietf.org/html/rfc7231#section-4 +[rfc7230-section-5-1]: https://tools.ietf.org/html/rfc7230#section-5.1 +[rfc7231]: https://tools.ietf.org/html/rfc7231 +[rfc7235]: https://tools.ietf.org/html/rfc7235 +[rfc7540]: https://tools.ietf.org/html/rfc7540 diff --git a/cloudevents/translated/zh-cn/primer_CN.md b/cloudevents/translated/zh-cn/primer_CN.md new file mode 100644 index 000000000..941eadc89 --- /dev/null +++ b/cloudevents/translated/zh-cn/primer_CN.md @@ -0,0 +1,783 @@ +# CloudEvents 入门文档 - 1.0.2 版本(制作中) + +## 摘要 + +这份非技术规范文档用来为你提供关于CloudEvents规范的总体概览。它补充了CloudEvents规范的相关背景以及在制定本规范时的历史和设计理念。这样,CloudEvents的核心规范就只需要关注Events规范的技术细节,而不用过多地关心背景相关内容。 + +## 文档状态 + +这份文档是一份仍在制作中的工作草案。 + +## 目录 + +- [历史](#history) +- [CloudEvents概念](#cloudevents-concepts) +- [设计目标](#design-goals) +- [架构](#architecture) +- [属性版本控制](#versioning-of-cloudevents) +- [CloudEvent属性](#cloudevent-attributes) +- [CloudEvent属性扩展](#cloudevent-attribute-extensions) +- [生产 CloudEvents](#creating-cloudevents) +- [合格的协议与编码](#qualifying-protocols-and-encodings) +- [专有的协议和编码](#proprietary-protocols-and-encodings) +- [现有技术](#prior-art) +- [角色](#roles) +- [价值主张](#value-proposition) +- [现有的数据格式](#existing-event-formats) + +## History/历史 + +[CNCF Serverless 工作组](https://github.com/cncf/wg-serverless) 是由 CNCF的[技术监管委员会](https://github.com/cncf/toc) 成立,用于研究Serverless相关技术并为CNCF推荐相关领域的未来发展计划的工作组。工作组其中一项建议就是研究创建一种通用事件格式,用于提升不同云厂商间函数的可移植性和事件流处理的互操作性。就此,CloudEvents应运而生。 + +尽管CloudEvents起初是作为Serverless工作组的项目进行的,但随着CloudEvents规范完成它v0.1版本的里程碑,技术监管委员会批准了CloudEvents作为一个新的独立的CNCF沙箱级项目。 + +## Cloudevents Concepts/概念 + +一个[事件](spec_CN.md#event)包含了[事件发生](spec_CN.md#occur)的上下文和相关数据。 +事件的相关数据可以用来唯一标识一件事件的发生。 + +事件代表了已发生的事实,因此它并不包含任何目的地相关信息,但消息能够传达事件内容,从而将事件数据 +从源头传输到指定的目的地。 + +### Eventing + +事件通常在服务器端代码中使用来连接不同的系统,其中一个系统中的状态变化会导致代码在另一个系统中执行。 +比如,一个事件源,可能会在收到某个外部信号(如HTTP或RPC)或观察到状态变化(如IoT传感器数据变化或不活跃) +时,生产一个事件。 + +为了更好地解释一个系统如何使用CloudEvents,下图展示了一个从事件源生产的事件是如何触发一个行为的。 + +![alt text](../../source-event-action.png "A box representing the source with +arrow pointing to a box representing the action. The arrow is annotated with +'e' for event and 'protocol'.") + +事件源生产了一条封装了基于某种协议的事件数据的消息。 +当载有事件的消息到达目的地时,会触发一个使用了事件数据的行为函数。 + +一个事件源是那些允许暂存和测试实例的源类型的特定实例。 +某个特定源类型的开源软件可能由多个公司或提供商部署。 + +事件可以通过各种行业标准协议(如HTTP、AMQP、MQTT、SMTP)、开源协议(例如 Kafka、NATS)或 +平台/供应商专有协议(AWS Kinesis、Azure Event Grid)传输。 + +一个操作函数能够处理那些定义了行为或影响的事件,这些行为和效果由来自特定源的特定事件触发而来。 +虽然超出了规范的范围,但生成事件的目的通常是让其他系统能够轻松地对它们无法控制的源中的更改做出反应。 +源和操作通常由不同的开发人员构建。 +通常,源是托管服务,而操作是serverless函数(如 AWS Lambda 或 Google Cloud Functions)中 +的自定义代码。 + +## Design Goals/设计目标 + +CloudEvents 通常用于分布式系统,以允许服务在开发过程中松耦合,独立部署,方便之后连接以创建新的应用程序。 + +CloudEvents 规范的目标是定义允许服务生产或消费事件的事件系统的互操作性, +其中生产者和消费者可以独立开发和部署。 生产者可以在没有消费者监听时就生成事件, +消费者也可以表达对尚未生成的事件或事件类的兴趣。值得注意的是,这项工作产生的规范侧重于事件格式的互操作性 +以及它在通过各种协议(例如 HTTP)发送时的显示方式。我们不关注事件生产者或事件消费者的处理模型。 + +CloudEvents的核心规范中定义了一组称之为属性的元数据, +它们描述了在系统之间传输的事件以及这些元数据片段应如何显示在该消息中。 +这些元数据是,将请求路由到适当组件并帮助该组件正确处理事件所需的最小信息集。 +因此,某些事件本身的数据可能会作为 CloudEvent 属性集的一部分而被复制, +但这样做仅是为了能够正确传递和处理消息。那些不用于该目的的数据应放置在事件(数据)本身中。 + +此外,本规范中假设协议层所需的用来将消息传递到目标系统的元数据应完全由协议处理, +因此不包含在 CloudEvents 属性中。 有关更多详细信息,请参阅[非目标](#non-goals)部分。 + +除了这些属性的定义之外,规范还描述了关于如何序列化 +不同格式(例如 JSON)和协议(例如 HTTP、AMQP、Kafka)的事件。 + +一些协议本身支持将多个事件批处理到单个 API 的调用中。 +为了提升系统间的互操作性,是否以及如何实现批处理将由协议自己决定。 +相关详细信息可以在协议绑定或协议规范中找到。 +成批的CloudEvents并没有语义,也没有排序。 +[中间人](spec_CN.md#intermediary)可以添加或删除批处理以及将事件分配给不同的批处理。 + +事件的目的或语义含义超出了 CloudEvents 规范的范围。 +只要发送的消息符合规范,那么它就是一个有效的 CloudEvent。 +很多人不容易意识到一件事,错误和异常是可以作为CloudEvents来传输的。 +接下来应由事件生产者定义将使用的 CloudEvents 属性值,就像它可能生成的任何其他事件一样。 + +由于并非所有事件生产者都将其事件以CloudEvents的形式发布, +因此我们定义了一组 [适配器](../../adapters.md) +来展示如何将事件从一些流行的事件生产者映射到 CloudEvents。 +这些适配器是非规范的, +但它们是规范作者对 CloudEvents 属性如何在其它生产者本地生成事件并映射到CloudEvents时的最佳猜测。 + +### Non Goals/非目标 + +以下内容不在本规范的范围之内: + +- 函数的构建和调用过程 +- 特定语言的运行时 APIs +- 选择单一身份认证或访问控制的系统 +- 包含协议级路由信息 +- 事件持久化过程 +- 授权、数据完整性和保密机制 + +就连那些刚接触 CloudEvents 概念的人都会建议 +CloudEvents 规范不应包括协议级路由信息(例如,将事件发送到的目标的URL)。 +经过深思熟虑,工作组得出的结论是,CloudEvents规范中不需要路由信息: +因为任何现有的协议(例如 HTTP、MQTT、XMPP 或 Pub/Sub 总线)都已经定义了路由语义。 +例如,CloudEvents [HTTP 绑定](../../bindings/http-protocol-binding.md) 规定了头部和请求正文内容。 +CloudEvents 不需要在规范中包含目标 URL 即可与 HTTP 兼容;HTTP 规范已经在 +[请求行](https://tools.ietf.org/html/rfc2616#section-5.1) 中包含了所需的目标URL。 + +路由信息不仅是多余的,而且是有害的。 +CloudEvents 应该增加互操作性并解耦事件的生产者和消费者。 +禁止来自事件格式的路由信息允许将 CloudEvents 重新传送到新的行为,或通过包含多个通道的复杂中继传送。 +例如,如果 Webhook 地址不可用,则用于 Webhook 的 CloudEvent 应可传送到死信队列。 +死信队列应该能够将事件传送给原始事件发射者从未想象过的新的行为上。 + +在系统内和跨系统生产和消费的CloudEvent能够触发产生价值的行为。 +因此,对于调试或复制的目的而言,存档和或重放事件可能很有价值。 +但是,持久化事件会删除传输期间可用的上下文信息,例如生产者的身份和权利、保真验证机制或机密性保护。 +此外,持久化会增加满足用户需求的复杂性和挑战。 +例如,出于加密或签名目的重复使用私钥会增加攻击者可用的信息,从而降低安全性。 +因此我们推测,可以定义有助于满足持久性要求的属性,但这些属性可能随着行业最佳实践和进步而不断发展。 + +CloudEvents 规范目前不强制或提倡任何有关授权、数据完整性和保密的专有机制和原则, +因为当前规范的目的不是定义有关CloudEvents的安全原则。 +每个实现者都有一个增强其安全模型的不同原则。 +我们把它留给规范的实现者去提供额外的细节来通过扩展字段的方式强化他们的安全模型, +这样可以更好地被实现者为规范而自己实现的组件所解释。 +但是,如果社区观察到一种扩展字段的模式,作为处理数据完整性主题的标准方法。 +在这种情况下,此类扩展字段可能被声明为对 CloudEvent 规范的官方扩展。 + +## Architecture/架构 + +CloudEvents 规范集定义了四种有助于形成分层架构模型的不同类型的协议元素。 + +1. [基本规范](spec_CN.md) 定义了一个抽象信息模型, + 该模型由属性(键值对)和构成 CloudEvent 的相关规则组成。 +2. [扩展属性](./spec_CN.md#extension-context-attributes) + 添加了特定于用例且可能重叠的扩展属性集和相关规则,如支持不同的追踪标准的规则。 +3. 事件格式编码,如 [JSON](../../formats/json-format.md), 定义了基本规范的信息模型与所选扩展的编码方式, + 以将其映射到应用程序协议的头部和负载元素。 +4. 协议绑定, 如. [HTTP协议绑定](../../bindings/http-protocol-binding.md), + 在HTTP to HTTP的情况下, + 定义了 CloudEvent 如何绑定到应用程序协议的传输层 。 + 协议绑定不限制传输层的使用方式,这意味着 HTTP绑定可用于任何 HTTP方法以及请求和响应消息。 + +为了确保更广泛的互操作性,CloudEvents规范集为使用专有应用协议的事件传输提供了特定约束。 +[HTTP Webhook](../../http-webhook.md)规范并非特定于 CloudEvents, +而是可用于将任何类型的单向事件和通知发布到符合标准的 HTTP 端点。 +但是,由于其他地方缺乏此类规范,因此 CloudEvents 需要对其进行定义。 + +### 互操作性约束条件 + +如 [设计目标](#design-goals) 部分所述,互操作性是本规范的一个关键目标。 +因此,本协议中有地方被建议有所约束条件。 +例如,在[大小限制](spec_CN.md#size-limits) 部分提示事件大小应该不超过 64KB。 +重要的是要注意诸如这些约束,在没有通过“必须”强制执行的情况下, +是对增加多个实现和部署之间互操作性的可能性的一种建议。 +具体使用规范可以随意忽略这些建议, +但这些环境有责任确保所有参与 CloudEvents 传输的组件能够远离这些建议的边界。 + +### 协议错误处理 + +CloudEvents 规范在很大程度上并未规定与 CloudEvents 的创建或处理相关联的处理模型。 +因此,如果在处理 CloudEvent 过程中出现错误, +请使用正常的协议级错误处理机制进行处理。 + +## Versioning of CloudEvents/属性版本控制 + +对于某些 CloudEvents 属性,由其值引用的实体或数据模型可能会随时间变化。 +CloudEvents 规范不强制要求要使用的特定模式,甚至不要求必须考虑用到版本控制。 +这个决定取决于每个事件生产者。 + +然而,鼓励事件生产者考虑他们如何在不破坏消费者的情况下发展他们的scheme。 +两个具体的上下文属性`type` 和 `dataschema`在这方面尤为重要,但是预期用法有所不同。 +两者间在版本控制方面的差异在下面介绍。 + +鼓励事件生产者从一开始就考虑版本问题,尤其是在首先声明一个特定的 CloudEvent +是“稳定的”之前。 +所选版本控制方案的文档,包括其背后的原理,都会是消费者所喜欢的。 + +### `type` 属性在版本控制方面的作用 + +`type` 属性应该是消费者识别他们收到的事件类型的主要方式。 +这可以通过订阅特定的 CloudEvent 类型来实现,或者通过本地过滤所有收到的 CloudEvent实现。 +但确定了 CloudEvent 类型的消费者通常会期望该类型的数据 +仅以向后兼容的方式更改,除非另有明确说明。 +“向后兼容”的确切含义将因数据内容类型而异。 + +当 CloudEvent 的数据以向后兼容的方式更改时,`type` 属性的值通常应保持不变。 + +当 CloudEvent 的数据以向后不兼容的方式更改时,`type` 属性的值通常应更改。 +我们鼓励事件生产者在一段时间内(可能永远)同时生产旧事件和新事件,以避免干扰消费者。 + +在考虑 `type` 属性的值时,事件生产者可以选择他们希望的任何版本控制方案, +例如版本号 (v1, v2) 或日期 (2018-01-01) 作为值的一部分。 +他们还可能使用 `type` 属性来表示特定版本尚未稳定,可能会经历重大更改。 +或者,他们可以选择根本不在类型值中包含版本。 + +### `dataschema` 属性在版本控制方面的作用 + +我们预计 `dataschema` 属性是信息性的,主要在开发过程中使用,并通过工具使用时, +该工具能够通过其理解的数据内容类型提供任意 CloudEvents 的诊断信息。 + +当 CloudEvent 的数据以向后兼容的方式更改时, +`dataschema` 属性的值通常应更改以反映这一点。 +另一种方法是让 URI 保持不变,但从该 URI 提供的内容要更改以反映更新的架构。 +后一种方法对于事件生产者来说可能更容易实现, +但对于希望通过 URI 缓存schema内容的消费者来说不太方便。 + +当 CloudEvent 的数据以向后不兼容的方式更改时,`dataschema` 属性的值通常应更改, +就像上述的 `type` 属性的情况一样。 + +## CloudEvent Attributes/属性 + +本节介绍了与CloudEvent 属性相关的其它背景和设计要点。 + +### id + +`id` 属性是一个在同一事件源下所有事件中用来标识事件唯一的值 +(其中每个事件源由其 CloudEvents `source`属性唯一标识)。 +虽然`id`使用的确切值是生产者定义的, +但必须要确保来自单个事件源的 CloudEvents 消费者不会有两个事件共享相同的 id 值。 +我们在这里隐含地声明没有两个事件将共享相同的 id 值,但不提供关于如何保证这一点的解释, +因为这超出了本规范的范围。 +唯一的例外是如果支持事件的重播,在这些情况下,可以使用 id 来检测这一点。 + +由于一次事件的发生可能导致生成多个cloud event, +在所有这些事件都来自同一事件源的情况下, +生成的每个 CloudEvent 将具有唯一的 `id`。 +以创建数据库条目为例,这一事件的发生可能会生成一个类型为 `create` 的 CloudEvent +和一个类型为 `write` 的 CloudEvent。 +这两个 CloudEvents 各自都有一个唯一的 ID。 +如果需要在这两个 CloudEvent 之间建立某种关联以表明它们都与同一事件相关, +那么可以使用 CloudEvent 中的一些附加数据来实现该目的。 + +从这方面来看,虽然事件生产者对`id`的使用可能是某个随机字符串, +或者在其它上下文中具有某种语义的字符串, +但对于此 CloudEvent 属性而言,这些含义并不成立, +因此本规范不建议将 `id` 用于除了唯一性检查之外的其它目的。 + +## CloudEvent Attribute Extensions/属性扩展 + +为了实现规范的设计目标, +规范作者将尝试限制他们在 CloudEvents 中定义的元数据属性的数量。 +为此,该项目定义的属性将分为以下三类: + +- 必要属性 +- 可选属性 +- 扩展属性 + +正如类别名称所暗示的那样, +“必要”属性是工作组认为在任何情况下,对所有事件都至关重要的属性, +而“可选”属性将在大多数情况下使用。 这些情况下的两个属性都在本规范中定义了出来。 + +工作组考虑到某些属性不够常见而不能归入上述两个类别, +但此类属性的良好定义仍会使系统间的互操作性级别受益, +因此将这些属性放入了“扩展”类别并记录在[扩展文档](../../documented-extensions.md)中, +本规范定义了这些扩展属性在 CloudEvent 中的显示方式。 + +在确定提议的属性属于哪个类别时, +工作组使用现有的用例和用户故事来解释它们的基本原理和需求。 +相关信息将添加到本文档的[现有技术](#prior-art)部分。 + +CloudEvent 规范的扩展属性是需要包含的附加元数据,它们能确保正确的路由和正确处理CloudEvent。 +用于其它目的的附加元数据, +即那些与事件本身相但在 CloudEvent 的传输或处理中不需要的元数据, +应改为放置在事件 (`data`)的扩展点内。 + +扩展属性应保持最少,以确保 CloudEvent 可以正确序列化和传输。 +事件生产者应该考虑在向 CloudEvent 添加扩展时可能遇到的技术限制。 +例如,[HTTP Binary Mode](../../bindings/http-protocol-binding.md#31-binary-content-mode) +使用 HTTP 头来传输元数据; +大多数 HTTP 服务器会拒绝包含过多 HTTP 头部数据的请求,要求限制其低至 8kb。 +因此,扩展属性的大小和数量应保持最小。 + +如果扩展变得流行,那么规范作者可能会考虑将其作为核心属性移入规范。 +这意味着在正式将新属性添加到规范之前,扩展机制/过程可用作审查新属性的一种方式。 + +### JSON 扩展 + +如 [CloudEvents JSON 事件格式](../../formats/json-format.md)中 +[属性](../../formats/json-format.md#2-attributes)部分所述, +CloudEvent 扩展属性与已定义属性(必要属性、可选属性)在序列化时处于同一等级 - +也就是说,它们都是 JSON 对象的顶层属性。 +CloudEvent的作者花了很长时间考虑所有选项,并认为这是最好的选择。 +理由如下: + +由于CloudEvents规范遵循 [semver](https://semver.org/) , +这意味着只要新属性是可选属性,它们可以在核心规范的未来版本定义,而无需更改当前主要版本。 +在这样的情况下,请考虑现有消费者将如何使用新的(未知的)顶级属性。 +虽然消费者可以随意忽略它,因为它是可选的, +但在大多数情况下,这些属性仍然希望向接收这些事件的应用程序公开。 +这可能导致这些应用程序在基础设施不支持的情况下,支持这些属性。 +这意味着未知的顶级属性(无论是谁定义的——规范的未来版本或事件生产者)可能不会被忽略。 +因此,虽然其它一些规范定义了放置扩展的特定属性(例如顶级`extensions`属性), +但作者认为在传入事件中具有两个不同位置的未知属性可能会导致互操作性问题和开发人员的混淆。 + +扩展属性通常用于测试那些被规范正式采用之前的潜在属性。 +如果有一个`extensions`类型的属性,这个新属性已经被序列化, +那么如果该属性被核心规范采用,它将从`extensions`属性提升(从序列化的角度)为顶级属性。 +如果我们假设这个新属性是可选的,那么当它被核心规范采用时, +它只是一个小版本增量,所有现有的消费者仍然会继续工作。 +但是,消费者将不知道此属性将出现在何处 - 在扩展属性中还是作为顶级属性。 +这意味着他们可能需要同时查看两个地方。 +如果属性出现在两个地方但具有不同的值怎么办? +生产者是否需要将它放在两个地方,因为他们可能同时有新、老消费者? +虽然可以为如何解决出现的每个潜在问题而制定明确的规则, +但作者认为一个避免这些问题的更好的办法是在序列化中只有一个位置来放置未知的甚至是新的属性。 +作者还注意到 HTTP 规范现在遵循类似的模式,不再建议扩展 HTTP 头部以 X- 为前缀。 + +## Creating CloudEvents + +CloudEvents 规范有意避免将CloudEvents 的创建方式设计的过于死板。 +例如,它不假定原始事件源必须是该事件生产对应 CloudEvent 的同一实体。 +这允许多种实现方式。 +但是,对于规范的实现者来说,理解规范作者心中的期望还是有帮助的,因为这将有助于确保互操作性和一致性。 + +如上所述,生成初始事件的实体是否与创建相应 CloudEvent 的实体相同是由实现决定的。 +但是,当构建/填充 CloudEvents 属性的实体代表事件源进行操作时,这些属性的值是用来描述事件或事件源, +而不是计算 CloudEvent 属性值的实体的。 +换句话说,当事件源和 CloudEvents 生产者之间的分离对事件使用者没有实质性意义时, +规范定义的属性通常不会包含任何值来指示这种职责分离。 + +这并不是说 CloudEvents 生产者不能向 CloudEvent 添加一些额外的属性, +但这些属性超出了规范的互操作性定义属性的范围。 +这类似于 HTTP 代理通常如何最大限度地减少对传入消息的明确定义的 HTTP 头部的更改, +但它可能会添加一些额外的头部,其中包括一些特定代理的元数据。 + +还值得注意的是,原始事件源和 CloudEvents 生产者之间的这种分离可大可小。 +意思是,即使 CloudEvent 生产者不是原始事件源生态系统的一部分, +如果它代表事件源行事,并且它在事件流中的存在对事件消费者没有意义,那么上述指导仍然适用。 + +当实体同时充当 CloudEvents 的接收者和发送者以转发或转换传入事件时, +出站 CloudEvent 与入站 CloudEvent 匹配的程度将根据该实体的处理语义而有所不同。 +在它充当代理的情况下,它只是将 CloudEvents 转发给另一个事件消费者, +那么出站 CloudEvent 通常看起来与入站 CloudEvent 就规范定义的属性相同 +- 请参阅上一段有关添加其他属性的内容。 + +但是,如果此实体正在执行 CloudEvent 的某种类型的语义处理, +通常会导致`data`属性值发生更改, +则可能需要将其视为与原始事件源不同的“事件源”。 +因此,与事件生产者相关的 CloudEvents 属性(例如`source` and `id`) +将从传入的 CloudEvent 中更改。 + +可能存在需要创建包含另一个 CloudEvent 的 CloudEvent 的特殊情况。 +虽然规范没有明确定义嵌套,但它是可能的。 +虽然内部事件将始终以[独立的事件格式](spec_CN.md#event-format) 编码, +但外部事件可能是二进制或结构化模式的。 +外部事件的 `datacontenttype` 属性不得设置为 application/cloudevents+json +或任何其它用于表示使用结构化模式的媒体类型。 +事件嵌套的正确示例是: + +``` +Content-Type: application/json +ce-specversion: 1.0 +ce-type: myevent +ce-id: 1234-1234-1234 +ce-source: example.com + +{ + "specversion": "1.0", + "type": "coolevent", + "id": "xxxx-xxxx-xxxx", + "source": "bigco.com", + "data": { ... } +} +``` + +## Qualifying Protocols and Encodings/合理化协议与编码 + +正如规范中所表达的,CloudEvents 工作的明确目标是 +“以通用方式描述事件数据”且 +“定义允许服务产生或消费事件的事件系统的互操作性,其中生产者和消费者可以被独立开发和部署”。 + +这种互操作性的基础是开放的数据格式和协议, +CloudEvents 旨在提供这种开放的数据格式,并将其数据格式映射到常用协议和常用编码上。 + +虽然每个软件或服务产品和项目都可以自己选择自己喜欢的通信形式, +但毫无疑问,这种产品或项目私有的专有协议无法进一步实现跨生产者和消费者的广泛互操作性的目标。 + +特别是在消息传递和事件处理领域,该行业在过去十年中开发出了强大且受到广泛支持的协议 +例如 HTTP 1.1 和 HTTP/2 以及 WebSockets 或 Web 上的事件,或者 MQTT 和 AMQP +用于面向连接的消息传递和遥测传输的协议。 + +一些广泛使用的协议已经成为事实上的标准,这些协议来自三个或更多公司的顶级财团打造的强大生态系统, +还有一些来自单个公司发布的强大项目生态系统,在任何一种情况下都与前面提到的标准栈的演变相一致。 + +CloudEvents的努力不应成为认可或推广项目或产品专有协议的工具, +因为这与CloudEvents 的原始目标背道而驰。 + +要使协议或编码符合核心 CloudEvents 事件格式或协议绑定的条件,它必须属于以下任一类别: + +- 该协议具有广泛认可的多供应商协议标准化机构(例如 W3C、IETF、OASIS、ISO)的正式标准地位 +- 该协议在其生态系统类别中具有“事实上的标准”地位, + 这意味着它被广泛使用,甚至被认为是给定应用程序的标准。 + 实际上,我们希望在供应商中立的开源组织(例如 Apache、Eclipse、CNCF、.NET 基金会)的保护伞下 + 看到至少一个开源实现, + 并且至少有十几个独立供应商在他们的产品中使用它的产品或服务。 + +除了正式状态之外,协议或编码是否符合核心 CloudEvents 事件格式或协议绑定的一个关键标准是, +该组织是否认为协议或编码出现后,该规范对与产品或项目无关的任何一方具有持续的实际利益。 +对此的基本要求是协议或编码的定义方式允许独立于产品或项目代码的替代实现。 + +欢迎将 CloudEvents 的所有其他协议和编码格式 +包含在指向相应项目自己的公共仓库,或站点中的 CloudEvents binding信息的列表中。 + +## Proprietary Protocols and Encodings/专有的协议与编码 + +为了鼓励更多人采用 CloudEvents,本仓库将自动收集专有协议和编码。 +本仓库的维护人员不负责创建、维护或通知专有规范的维护人员有关专有规范和CloudEvents规范间的偏差。 + +专有规范将托管在他们自己的仓库或文档站点中,并记录在[专有规范](../../proprietary-specs.md) +文件中。 专有规范应遵循与核心协议和编码相关的其他规范相同的格式。 + +专有规范将比核心规范受到更少的审查,并且随着 CloudEvents 规范的发展, +相应协议和编码的维护者有责任使规范与 CloudEvents 规范保持同步。 +如果专有规范过时太多,CloudEvents 可能会将指向该规范的链接标记为已弃用或将其删除。 + +如果为同一个协议创建了多个不兼容的规范,存储库维护者将不知道哪个规范是正确的,并列出所有规范的链接。 + +## Prior Art/现有技术 + +本节介绍了工作组在 CloudEvent 规范开发过程中使用的一些输入材料。 + +### Roles/角色 + +下面列举了可能涉及事件的产生、管理或消费的各种参与者和场景。 + +1. 应用程序生成供他人使用的事件, + 如为消费者提供有关终端用户活动、状态变化或环境观察的见解, + 或允许通过事件驱动的扩展来补充应用程序的功能。 + + 生产的事件通常与上下文或生产者选择的分类相关。 + 例如,房间中的温度传感器可能被安装位置、房间、楼层和建筑物等上下文限定。 + 运动结果可以按联赛和球队分类。 + + 生产者应用程序可以在任何地方运行,例如在服务器或设备上。 + + 生产的事件可能由生产者或中间人直接提供和发出; + 作为后者的示例,请考虑设备通过负载大小受限的网络(如 LoRaWAN 或 ModBus)传输的事件数据, + 并且符合此规范的事件将由网络网关代表生产者提供。 + + 例如,气象站每 5 分钟通过 LoRaWAN 传输一次 12 字节的专有事件payload用于指示天气状况。 + 然后使用 LoRaWAN 网关以 CloudEvents 格式将事件发布到 Internet 目标。 + LoRaWAN 网关是事件生产者,代表气象站发布事件,并将设置一定的元数据以反映事件的来源(气象站)。 + +2. 应用程序可能以以下目的: + 如显示、存档、分析、工作流处理、监控状态或提供业务解决方案及其基本构建模块的透明化 + 来消费事件。 + + 消费者应用程序可以在任何地方运行,例如在服务器或设备上。 + + 消费应用程序通常对以下内容感兴趣: + + - 区分事件,使得完全相同的事件不会被处理两次。 + - 识别和选择源上下文或生产者指定的分类。 + - 确定事件相对于原始上下文或相对于时钟的时间顺序。 + - 了解事件中携带的上下文相关的详细信息。 + - 关联来自多个事件生产者的事件实例并将它们发送到相同的消费者上下文。 + + 在某些情况下,消费应用程序可能对以下内容感兴趣: + + - 从原始上下文中获取有关事件主题的更多详细信息,例如获取有关需要特权访问授权的已更改对象的详细信息。 + 例如,出于隐私原因,HR 解决方案可能仅在事件中发布非常有限的信息, + 任何需要更多数据的事件消费者都必须在其自己的授权上下文背景下从 HR 系统获取与事件相关的详细信息 + - 在原始上下文中与事件的主题进行交互,例如在被告知该数据块刚刚创建后读取存储该数据块。 + + 消费者的兴趣激发了信息生产者应该包括事件的需求。 + +3. 中间件将事件从生产者路由到消费者,或转发到其他中间件。 + 产生事件的应用程序可能会将根据消费者需求产生的某些任务委托给中间件: + + - 管理同时对大量类别和上下文背景中的某个事件感兴趣的消费者。 + - 代表消费者在类或事件的原始上下文上处理过滤条件。 + - 转码,比如从 JSON 解码后在 MsgPack 中编码。 + - 更改事件结构的转换,例如从专有格式映射到 CloudEvents,同时保留事件的身份和语义完整性。 + - 即时“推送式”传输给感兴趣的消费者。 + - 存储最终传输的事件,用于由消费者发起的“拉”请求,或延迟后由中间件发起“推”请求。 + - 观察事件内容或事件流以进行监控或诊断。 + + 为了满足这些需求,中间件将对以下方面感兴趣: + + - 一种元数据鉴别器,可用于事件的分类或上下文化,以便消费者可以表达对一个或多个类或上下文的兴趣。 + 例如,消费者可能对文件存储帐户内的特定目录相关的所有事件感兴趣。 + - 一种元数据鉴别器,允许区分该类或上下文的特定事件的主题。例如,消费者可能希望过滤掉与以“.jpg”结尾的 + 新文件相关的所有事件(文件名是“新文件”事件的主题),以此表示它对感兴趣的文件存储账户下某个目录的 + 上下文环境。 + - 一个事件及其数据编码的指示器。 + - 一个事件及其数据的结构布局(模式)的指示器。 + + 事件是否可通过中间件消费取决于生产者的选择。 + + 在实践中,当中间件改变事件的语义时可以扮演[生产者](spec_CN.md#producer)的角色, + 当它根据事件采取行动时可以扮演[消费者](spec_CN.md#consumer)的角色, + 或者当它路由事件而不进行语义改变时可以扮演[中间人](spec_CN.md#intermediary)的角色。 + +4. 框架和其他抽象使与事件平台基础设施间的交互更简单, + 并且通常为多个事件平台基础设施提供公共 API 区域。 + + 框架通常用于将事件转换为对象图,并将事件分派给某些特定的处理逻辑或用户规则, + 这些用户逻辑或用户规则允许消费应用程序对原始上下文和特定主题中的特定类型的事件做出反应。 + + 框架最感兴趣的是跨抽象平台的语义元数据通用性,以便可以统一处理类似的活动。 + + 对于体育应用程序,使用该框架的开发人员可能对联盟中一支球队今天的比赛(主题) + 的所有事件感兴趣,但希望以不同于“换人”事件的方式处理“得分”事件。 + 为此,框架将需要一个合适的元数据鉴别器,使其不必了解事件细节。 + 需要明确的是,合适的元数据鉴别器应该由生产者填充,而不是框架的责任。 + +### Value Proposition/价值主张 + +本节介绍了一些能够展示 CloudEvents 价值主张的用例。 + +#### 跨服务和平台规范化事件 + +主要事件发布者(例如 AWS、Microsoft、Google 等)都在各自的平台上以不同的格式发布事件。 +甚至在少数情况下,同一提供商的服务以不同格式(例如 AWS)发布事件。 +这迫使事件消费者实现自定义逻辑以跨平台读取或处理事件数据,有时甚至需要跨单个平台的多个服务处理。 + +CloudEvents 可以为那些跨平台和服务处理事件的使用者提供单一体验。 + +#### 促进跨服务和平台的集成 + +跨环境传输的事件数据越来越普遍。 +然而,如果没有描述事件的通用方式,跨环境的事件传递就会受到阻碍。 +CloudEvents之前没有单一的方法可以确定事件的来源和可能的去向。 +这对研究成功传输事件事件工具和消费者知道如何处理事件数据形成了巨大阻碍。 + +CloudEvents 提供有用的元数据,中间件和消费者可以依赖这些元数据来促进事件路由、日志记录、传输和接收。 + +#### 提高功能即服务的可移植性 + +功能即服务(也称为serverless计算)是 IT 中增长最快的趋势之一,它主要是由事件驱动的。 +然而,FaaS 的一个主要问题是供应商锁定。 +这种锁定部分是由函数 API 和供应商之间签名的差异引起的, +锁定同样也是由函数内接收的事件数据格式的差异引起的。 + +CloudEvents提供描述事件数据的通用方式提高了功能即服务的可移植性。 + +#### 改进事件驱动/serverless架构的开发和测试 + +缺乏通用事件格式使事件驱动和serverless架构的开发和测试变得复杂。 +没有简单的方法可以准确地为开发和测试目的模拟事件,并帮助在开发环境中模拟事件驱动的工作流。 + +CloudEvents 可以提供更好的开发工具来构建、测试和处理事件驱动和无服务器架构的端到端生命周期。 + +#### 事件数据发展 + +大多数平台和服务对其事件的数据模型进行不同的版本控制(如果他们这样做的话)。 +随着这些数据模型的发展,这会为发布和使用事件的数据模型带来不一致的体验。 + +CloudEvents 可以提供一种通用的方式来版本化和演化事件数据的发展。 +这将帮助事件发布者根据最佳实践安全地对其数据模型进行版本控制, +并且这有助于事件消费者随着事件数据的发展安全地使用它。 + +#### 规范化 Webhook + +Webhooks 是一种不使用通用格式的来发布事件的模式。 +Webhook 的使用者没有一致的方式来开发、测试、识别、验证和整体处理通过 Webhook 传输的事件数据。 + +CloudEvents 可以提供 Webhook 发布和消费事件的一致性。 + +#### 安全策略 + +出于安全和策略考虑,可能需要过滤、转换或阻止系统之间的事件传输。 +比如可能需要防止事件的进入或退出,如包含敏感信息的事件数据或想要禁止发送方和接收方之间的信息流。 + +通用事件格式将允许更容易地推理正在传输的数据,并提供更好的数据自查。 + +#### 事件追踪 + +从源发送的事件可能会出现在一系列附加事件序列之中, +这些附加事件序列从各种中间件设备(例如事件代理和网关)发出。 +CloudEvents 在事件中包含元数据以将这些事件关联为事件序列的一部分,以便进行事件跟踪和故障排除。 + +#### IoT + +物联网设备会发送和接收与其功能相关的事件。 +例如,连接的恒温器将发送有关当前温度的遥测数据, +并可以接收改变温度的事件。 +这些设备通常具有受限的操作环境(cpu、内存),需要明确定义的事件消息格式。 +在很多情况下,这些消息是二进制编码的,而不是文本的。 +无论是直接来自设备还是通过网关转换,CloudEvents 都可以更好地描述消息的来源和消息中包含的数据格式。 + +#### 事件关联 + +一个serverless应用或工作流可能与来自不同事件源或事件生产者的多个事件相关联。 +例如,盗窃检测应用程序/工作流可能涉及运动事件和门/窗打开事件。 +一个serverless平台可能接收每种类型事件的许多实例,例如 它可以接收来自不同房屋的运动事件和开窗事件。 + +serverless平台需要将一种类型的事件实例与其他类型的事件实例正确关联, +并将接收到的事件实例映射到正确的应用/工作流实例。 +CloudEvents 将为任何事件使用者(例如serverless平台)提供一种标准方式, +以在事件数据中定位事件关联信息/令牌并将接收到的事件实例映射到正确的应用/工作流实例。 + +### Existing Event Formats/现有的数据格式 + +与上一节一样,对当前现状的调查(和理解)对CloudEvents 小组来说非常重要。 +为此,下面列出了在实践中被广泛使用的当前事件格式的样本。 + +#### Microsoft - Event Grid + +```json +{ + "topic": "/subscriptions/{subscription-id}", + "subject": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "eventType": "Microsoft.Resources.ResourceWriteSuccess", + "eventTime": "2017-08-16T03:54:38.2696833Z", + "id": "25b3b0d0-d79b-44d5-9963-440d4e6a9bba", + "data": { + "authorization": "{azure_resource_manager_authorizations}", + "claims": "{azure_resource_manager_claims}", + "correlationId": "54ef1e39-6a82-44b3-abc1-bdeb6ce4d3c6", + "httpRequest": "", + "resourceProvider": "Microsoft.EventGrid", + "resourceUri": "/subscriptions/{subscription-id}/resourceGroups/{resource-group}/providers/Microsoft.EventGrid/eventSubscriptions/LogicAppdd584bdf-8347-49c9-b9a9-d1f980783501", + "operationName": "Microsoft.EventGrid/eventSubscriptions/write", + "status": "Succeeded", + "subscriptionId": "{subscription-id}", + "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47" + } +} +``` + +[Documentation](https://docs.microsoft.com/en-us/azure/event-grid/event-schema) + +#### Google - Cloud Functions (potential future) + +```json +{ + "data": { + "@type": "types.googleapis.com/google.pubsub.v1.PubsubMessage", + "attributes": { + "foo": "bar" + }, + "messageId": "12345", + "publishTime": "2017-06-05T12:00:00.000Z", + "data": "somebase64encodedmessage" + }, + "context": { + "eventId": "12345", + "timestamp": "2017-06-05T12:00:00.000Z", + "eventTypeId": "google.pubsub.topic.publish", + "resource": { + "name": "projects/myProject/topics/myTopic", + "service": "pubsub.googleapis.com" + } + } +} +``` + +#### AWS - CloudWatch Events + +AWS 上的很大一部分事件处理系统都在使用这种格式。 + +```json +{ + "version": "0", + "id": "6a7e8feb-b491-4cf7-a9f1-bf3703467718", + "detail-type": "EC2 Instance State-change Notification", + "source": "aws.ec2", + "account": "111122223333", + "time": "2017-12-22T18:43:48Z", + "region": "us-west-1", + "resources": [ + "arn:aws:ec2:us-west-1:123456789012:instance/i-1234567890abcdef0" + ], + "detail": { + "instance-id": "i-1234567890abcdef0", + "state": "terminated" + } +} +``` + +#### IBM - OpenWhisk - Web Action Event + +```json +{ + "__ow_method": "post", + "__ow_headers": { + "accept": "*/*", + "connection": "close", + "content-length": "4", + "content-type": "text/plain", + "host": "172.17.0.1", + "user-agent": "curl/7.43.0" + }, + "__ow_path": "", + "__ow_body": "Jane" +} +``` + +#### OpenStack - Audit Middleware - Event + +```json +{ + "typeURI": "http://schemas.dmtf.org/cloud/audit/1.0/event", + "id": "d8304637-3f63-5092-9ab3-18c9781871a2", + "eventTime": "2018-01-30T10:46:16.740253+00:00", + "action": "delete", + "eventType": "activity", + "outcome": "success", + "reason": { + "reasonType": "HTTP", + "reasonCode": "204" + }, + "initiator": { + "typeURI": "service/security/account/user", + "name": "user1", + "domain": "domain1", + "id": "52d28347f0b4cf9cc1717c00adf41c74cc764fe440b47aacb8404670a7cd5d22", + "host": { + "address": "127.0.0.1", + "agent": "python-novaclient" + }, + "project_id": "ae63ddf2076d4342a56eb049e37a7621" + }, + "target": { + "typeURI": "compute/server", + "id": "b1b475fc-ef0a-4899-87f3-674ac0d56855" + }, + "observer": { + "typeURI": "service/compute", + "name": "nova", + "id": "1b5dbef1-c2e8-5614-888d-bb56bcf65749" + }, + "requestPath": "/v2/ae63ddf2076d4342a56eb049e37a7621/servers/b1b475fc-ef0a-4899-87f3-674ac0d56855" +} +``` + +[Documentation](https://github.com/openstack/pycadf/blob/master/doc/source/event_concept.rst) + +#### Adobe - I/O Events + +```json +{ + "event_id": "639fd17a-d0bb-40ca-83a4-e78612bce5dc", + "event": { + "@id": "82235bac-2b81-4e70-90b5-2bd1f04b5c7b", + "@type": "xdmCreated", + "xdmEventEnvelope:objectType": "xdmAsset", + "activitystreams:to": { + "xdmImsUser:id": "D13A1E7053E46A220A4C86E1@AdobeID", + "@type": "xdmImsUser" + }, + "activitystreams:generator": { + "xdmContentRepository:root": "https://cc-api-storage.adobe.io/", + "@type": "xdmContentRepository" + }, + "activitystreams:actor": { + "xdmImsUser:id": "D13A1E7053E46A220A4C86E1@AdobeID", + "@type": "xdmImsUser" + }, + "activitystreams:object": { + "@type": "xdmAsset", + "xdmAsset:asset_id": "urn:aaid:sc:us:4123ba4c-93a8-4c5d-b979-ffbbe4318185", + "xdmAsset:asset_name": "example.jpg", + "xdmAsset:etag": "6fc55d0389d856ae7deccebba54f110e", + "xdmAsset:path": "/MyFolder/example.jpg", + "xdmAsset:format": "image/jpeg" + }, + "activitystreams:published": "2016-07-16T19:20:30+01:00" + } +} +``` + +[Documentation](https://www.adobe.io/apis/cloudplatform/events/documentation.html) diff --git a/cloudevents/translated/zh-cn/proprietary-specs_CN.md b/cloudevents/translated/zh-cn/proprietary-specs_CN.md new file mode 100644 index 000000000..b416e9507 --- /dev/null +++ b/cloudevents/translated/zh-cn/proprietary-specs_CN.md @@ -0,0 +1,15 @@ +# CloudEvent 专有协议与编码规范 + +免责声明:CloudEvents并不支持这些协议或规范,也不能保证它们能与CloudEvents的当前版本保持一致。使用这些协议的项目维护者应该保证这些协议与CloudEvents的最新版本的兼容性。 + +- [Apache RocketMQ Transport Binding](https://github.com/apache/rocketmq-externals/blob/master/rocketmq-cloudevents-binding/rocketmq-transport-binding.md) +- [Google Cloud Pub/Sub Protocol Binding](https://github.com/google/knative-gcp/blob/master/docs/spec/pubsub-protocol-binding.md) + +**想要添加一个专属的传输层协议绑定?** + +- 根据现有的绑定规范的格式来创建自己的规范 (如 [http](../../bindings/http-protocol-binding.md) or [amqp](../../bindings/amqp-protocol-binding.md)) - 这会对相应的SDKs开发有帮助。 + - **注意:** + - 这个新建的规范必须能被公开访问,同时它必须被提出它的组织所管理。 + - 这个新建的规范必须明确地指出它支持的CloudEvents版本. +- 为这个新建的规范创立一个PR。 +- 回复在这个PR下的相关评论,可能会被要求加入到工作组的常规会话中。 diff --git a/cloudevents/translated/zh-cn/spec_CN.md b/cloudevents/translated/zh-cn/spec_CN.md new file mode 100644 index 000000000..7e0dae984 --- /dev/null +++ b/cloudevents/translated/zh-cn/spec_CN.md @@ -0,0 +1,488 @@ +# CloudEvents 核心规范- 1.0.2(制作中) + +## 摘要 + +CloudEvents 是一个用于定义事件格式的供应商中立规范。 + +## 文档状态 + +这份文档是一份仍在制作中的工作草案。 + +## 目录 + +- [概览](#overview) +- [符号和术语](#notations-and-terminology) +- [上下文属性](#context-attributes) +- [事件数据](#event-data) +- [大小限制](#size-limits) +- [隐私与安全](#privacy-and-security) +- [示例](#exmaple) + +## Overview/概览 + +事件(Events)在现代系统中无处不在。但不同的事件生产者往往用不同的规范来描述自己的事件。 + +对事件的统一描述的匮乏意味着开发者必须不断重新学习如何消费不同定义的事件。 +它同样限制了那些用来帮助事件数据完成 跨环境传输的库(如SDKs), +工具(如事件路由器)和基础设施(如事件追踪系统)的发展。 +总体来看,这种匮乏严重阻碍了事件数据的可移植性和生产力。 + +CloudEvents是一个以通用格式来描述事件数据的标准。它提供了事件在服务、平台和系统中的互操作性。 + +事件格式指定如何使用某些编码格式序列化一个 CloudEvent。 +支持那些编码且兼容 CloudEvents 的实现必须遵守相应事件格式中指定的编码规则。 +所有实现都必须支持 [JSON 格式](../../formats/json-format.md)。 + +有关规范背后的历史、开发和设计原理等更多信息, +请参阅 CloudEvents [入门文档](primer_CN.md)。 + +## Notations and Terminology/符号和术语 + +### Notational Conventions/符号约定 + +本文档中的关键词 +"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", +"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 需要按照 +[RFC 2119](https://tools.ietf.org/html/rfc2119) 中的描述来理解。 + +为清楚起见, +当一个功能被标记为“OPTIONAL”时,这意味着消息的 +[生产者](#producer)和[消费者](#consumer) 都可以自行选择是否支持该功能。 +换句话说,生产者可以在需要时在消息中包含该功能,消费者也可以在需要时选择支持该功能。 +不支持该功能的消费者将默默地忽略该部分消息。 +生产者需要做好消费者并没有启用该功能的准备。 +[中间人](#intermediary) 应当转发OPTIONAL属性。 + +### 术语 + +本规范定义了下列术语 + +#### Occur/发生 + +“发生”是指在软件系统运行期间对事实状态的捕获。 +这可能是由于系统发出了信号或系统观察到信号、状态更改、计时器超时 +或任何其他值得注意的活动而发生的。 +例如,设备可能会因为电池电量低或虚拟机即将执行计划的重启而进入警报状态。 + +#### Event/事件 + +“事件”是表示一条"发生"及其上下文的数据记录。 +事件从事件生产者(源)路由到对它感兴趣的事件消费者。 +事件中包含的信息帮助完成路由操作,但事件不会标识特定的路由目的地。 +事件将包含两种类型的信息:表示"发生"的 [事件数据](#event-data) +和提供有关事件的环境信息的[上下文](#context) 元数据。 +一次"发生"可能导致多个事件的产生。 + +#### Producer/生产者 + +“生产者”是一种特定的实例、进程或设备,它能够创建用来描述CloudEvent的数据结构。 + +#### Source/源 + +"源"是事件发生的上下文环境。在分布式系统中,它可能由多个[生产者](#producer)组成。 +如果一个源无法查看到CloudEvents,那么一定有有外部的生产者在代替源来生产CloudEvent。 + +#### Consumer/消费者 + +一个“消费者”会接收事件并根据事件采取一定的行为。 +它使用上下文环境和事件数据来执行一些逻辑,这可能会导致新事件的发生。 + +#### Intermediary/中间人 + +一个“中间人”会接收包含事件的消息, +并将其转发给下一个接收者,但该接收者可能是另一个中间人或事件[消费者](#consumer)。 +中间人的典型任务就是根据[上下文](#context)环境中的信息将事件路由到接收者。 + +#### Context/上下文 + +上下文环境元数据被封装在[上下文-属性](#context-attributes)中。 +工具和应用程序代码可以使用此信息来识别事件与系统方面或事件与其他事件的关系。 + +#### Data/数据 + +关于事件的特定域信息(即有效负载)。这可能包括有关事件的信息、有关已更改数据的详细信息等。 +有关更多信息,请参阅[事件数据](#event-data)部分。 + +#### Event Format/事件格式 + +一个事件格式会指定如何将 CloudEvent 序列化为字节序列。 +独立事件格式(例如 [JSON 格式](../../formats/json-format.md))指定独立于任何协议或存储介质的序列化。 +协议绑定可以定义依赖于协议的格式。 + +#### 消息 + +事件通过消息从源传输到目标。 + +“结构化模式消息”是一种使用独立事件格式对事件进行完全编码并存储在消息体中的消息。 + +“二进制模式消息”会将事件数据存储在消息体中,并将事件属性作为消息元数据的一部分存储下来。 + +#### 协议 + +消息可以通过各种行业标准协议 +(例如 HTTP、AMQP、MQTT、SMTP)、开源协议(例如 Kafka、NATS)或平台/供应商 +专有协议(AWS Kinesis、Azure 事件网格)传输。 + +#### 协议绑定 + +协议绑定描述了如何通过给定的协议发送和接收事件。 + +协议绑定可以选择使用[Event Format](#event-format) +将事件直接映射到传输包的正文,或者可以为包提供额外的格式和结构。 +例如,可以使用结构化模式消息的包装器,或者可以将多个消息一起批处理到传输包正文中。 + +## Context Attributes/上下文属性 + +每个符合本规范的 CloudEvent 必须包括指定为 REQUIRED 的上下文属性, +可以包括一个或多个OPTIONAL上下文属性, +并且可以包括一个或多个扩展属性。 + +这些属性虽然描述了事件,但被设计为可以独立于事件数据进行序列化。 +这允许在不反序列化事件数据的情况下,在目的检查这些上下文属性。 + +### Attribute Naming Convention/属性命名约定 + +CloudEvents 规范定义了到各种协议和编码的映射,随附的 CloudEvents SDK 面向各种运行时和编程语言。 +其中一些将元数据元素区分大小写,而另一些则不区分, +并且单个 CloudEvent 可能通过涉及到协议、编码和运行时混合的多个跃点进行路由。 +因此,本规范限制了所有属性的可用字符集,以防止区分大小写问题或与通用语言中标识符的合法字符集冲突问题。 + +CloudEvents 属性名称必须由来自 ASCII 字符集的小写字母(“a”到“z”)或数字(“0”到“9”)组成。 +属性名称应该是描述性的和简洁的,并且长度不应超过 20 个字符。 + +### Type System/类型系统 + +以下抽象数据类型可用于属性。 +这些类型中的每一种都可以由不同的事件格式和协议元数据字段以不同的方式表示。 +本规范为所有实现必须支持的每种类型定义了规范的字符串编码。 + +- `Boolean` - “true”或“false”的布尔值。 + - 字符串编码:区分大小写的`true` 或 `false`值。 +- `Integer` -范围在 -2,147,483,648 到 +2,147,483,647 (包含)之间的整数。 + 这是有符号 32 位二进制补码编码的范围。 + 事件格式不必使用此编码,但它们必须使用在此范围内的`Integer` 值。 + - 字符串编码: 符合 + [RFC 7159, 第 6 节](https://tools.ietf.org/html/rfc7159#section-6) + JSON 数字的整数部分 +- `String` - 允许的 Unicode 字符序列。 不允许使用以下字符: + - 范围 U+0000-U+001F 和 U+007F-U+009F(包含首尾)中的“控制字符”, + 因为大多数没有商定的含义,还有一些,例如 U+000A(换行符), 在如 HTTP 头部之类的上下文中不可用。 + -[被 Unicode 标识为非字符的](http://www.unicode.org/faq/private_use.html#noncharacters) + 代码点。 + - 被 Unicode 标识为代理项的代码点, 范围 U+D800-U+DBFF 和 U+DC00-U+DFFF(包含首尾) + , 除非被合理的用作代理对. 因此(在 JSON 符号中) + “\uDEAD”是无效的,因为它是一个未配对的代理,而“\uD800\uDEAD”是合法的。 +- `Binary` - 字节序列. + - 字符串编码: Base64 编码,符合 + [RFC4648](https://tools.ietf.org/html/rfc4648). +- `URI` - 绝对统一资源标识符。 + - 字符串编码: + [RFC 3986 第 4.3 节](https://tools.ietf.org/html/rfc3986#section-4.3) + 中定义的 `Absolute URI` 。 +- `URI-reference` - 统一资源标识符引用。 + - 字符串编码: + [RFC 3986 第 4.1 节](https://tools.ietf.org/html/rfc3986#section-4.1) + 中定义的`URI-reference` 。 +- `Timestamp` - 使用公历的日期和时间表达式。 + - 字符串编码: [RFC 3339](https://tools.ietf.org/html/rfc3339) 。 + +所有上下文属性值必须是上面列出的类型之一。 +属性值可以表示为原生类型或规范字符串。 + +当强类型编程语言表示 CloudEvent 或任何扩展时, +必须能够在规范字符串编码与对应抽象类型的运行时/编程语言类型之间进行转换。 + +例如,在给定的实现中,`time` 属性可能由编程语言的本地时间类型表示, +但它必须是可设置提供 RFC3339 字符串的, +并且当映射到 HTTP 消息头时,它必须可转换为 RFC3339 字符串。 + +CloudEvents 协议绑定或事件格式实现同样必须能够 +在规范字符串编码与协议元数据字段中的对应数据类型之间进行转换。 + +`Timestamp` 类型的属性值确实可能以字符串形式路由通过多个跃点, +并且仅在生产者和最终消费者处实现为本地运行时/语言类型。 +`Timestamp` 类型也可以作为本地协议类型路由, +并且可以在生产者和消费者端映射到/从各自的语言/运行时类型,但永远不会转为字符串格式。 + +序列化机制的选择将决定上下文属性和事件数据将如何序列化。 +例如,在 JSON 序列化的情况下,上下文属性和事件数据可能都出现在同一个 JSON 对象中。 + +### 必要属性 + +下列属性必须在所有的 CloudEvents 中展示: + +#### id + +- 类型: `String` +- 描述: 标识一个事件。 生产者必须确保每个不同事件的 `source` + `id` 是唯一的。 + 如果重复的事件被重新发送(例如由于网络错误),它可能具有相同的 `id`。 + Consumers MAY assume that + 消费者可以假设具有相同`source` 和 `id`的事件是重复的。 +- 约束条件: + - 必要的 + - 必须是非空字符串 + - 在生产者的范围内必须是唯一的 +- 示例: + - 一个由生产者维护的事件计数器 + - 一个 UUID + +#### source + +- 类型: `URI-reference` +- 描述: 标识事件发生的上下文背景。 这通常包括诸如事件源类型、发布事件的组织 + 或产生事件的过程等信息。URI 中编码的数据背后的确切语法和语义由事件生产者定义。 + + 生产者必须确保每个不同事件的 `source` + `id` 是唯一的。 + + 应用程序可以为每个不同的生产者分配一个唯一的`source`, + 这使得生成唯一 ID 变得容易,因为没有其他生产者将拥有相同的来源。 + 应用程序可以使用 UUIDs、URNs、DNS权威机构或特定于应用程序的方案来创建唯一的`source` 标识符。 + + 一个来源可以包括多个生产者。 + 在这种情况下,生产者必须协作以确保每个不同事件的 `source` + `id`都是唯一的。 + +- 约束条件: + - 必要的 + - 必须是非空 URI-reference + - 推荐使用 绝对 URI +- 示例 + - 具有 DNS 权限的 Internet 范围唯一 URI: + - https://github.com/cloudevents + - mailto:cncf-wg-serverless@lists.cncf.io + - 具有 UUID 的通用唯一 URN: + - urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66 + - 应用程序专有的标识符 + - /cloudevents/spec/pull/123 + - /sensors/tn-1234567/alerts + - 1-555-123-4567 + +#### specversion + +- 类型: `String` +- 描述: 事件使用的 CloudEvents 规范的版本。 + 这让解释上下文环境更容易。 + 当引用这个版本的规范时,兼容的事件生产者必须使用 `1.0` 的值。 + +目前,此属性仅包含“主要”和“次要”版本号。这允许对规范进行“补丁”更改,而无需更改序列化中此属性的值。 +注意:对于“候选发布”版本,后缀可能用于测试目的。 +- 约束条件: + - 必要的 + - 必须是非空字符串 + +#### type + +- 类型: `String` +- 描述: 该属性包含一个值,描述与原始事件相关的事件类型。 + 该属性通常用于路由、可观察性、策略实施等。其格式是生产者定义的,可能包括诸如 `type`版本之类的信息 + -从 + [入门文档-属性版本控制](primer_CN.md#versioning-of-cloudevents) 中获得更多信息。 + +- 约束条件: + - 必要的 + - 必须是非空字符串 + - 应该以反向 DNS 名称作为前缀。该前缀域表明了定义此事件类型语义的组织。 +- 示例 + - com.github.pull.create + - com.example.object.delete.v2 + +### 可选属性 + +下列属性在 CloudEvents 中是可选的. 在 +[符号约定](#notational-conventions) 中查看更多 OPTIONAL 定义的信息。 + + +#### datacontenttype + +- 类型: `String` [RFC 2046](https://tools.ietf.org/html/rfc2046) +- 描述: `data`值的内容类型。 此属性使`data`能够承载任何类型的内容, + 因此格式和编码可能与所选事件格式的不同。 + 例如,使用 [JSON envelope](../../formats/json-format.md#3-envelope) + 格式呈现的事件可能在数据中携带 XML 的payload,这个属性可以用来通知消费者 + 设置"application/xml"。 + 关于`data`内容如何提供不同的`datacontenttype`的值的规则在事件格式规范中定义。 + 例如,JSON 事件格式定义了 [3.1 节](../../formats/json-format.md#31-handling-of-data)中的关系。 + + 对于某些二进制模式协议绑定, + 此字段直接能映射到相应协议的内容类型的元数据属性上。 + 二进制模式和内容类型元数据映射的规范规则可以在各自的协议中找到。 + + 在某些事件格式中,可以省略 `datacontenttype` 属性。 + 例如,如果 JSON 格式的事件没有 `datacontenttype` 属性, + 则表示该`data`是符合“application/json”媒体类型的 JSON 值。 + 换句话说:一个没有 `datacontenttype` 的 JSON 格式的事件完全等同于 + 一个带有 `datacontenttype="application/json"`的事件。 + + 当将没有 `datacontenttype` 属性的事件消息转换为不同的格式或协议绑定时, + 目标 `datacontenttype` 应该显式设置为事件源的隐含或默认的 `datacontenttype`。 + +- 约束条件: + - 可选的 + - 若有则必须遵守 + [RFC 2046](https://tools.ietf.org/html/rfc2046) 制定的格式 +- 媒体类型示例 + [IANA Media Types](http://www.iana.org/assignments/media-types/media-types.xhtml) + +#### dataschema + +- 类型: `URI` +- 描述: 标识 `data` 遵守的规范。 对模式的不兼容的更改应该由不同的 URI 体现。 在 + [入门文档-属性版本控制](primer_CN.md#versioning-of-cloudevents) + 中查看更多信息。 +- 约束条件: + - 可选的 + - 若有必须是非空的 URI + +#### subject + +- 类型: `String` +- 描述: 这个属性描述了事件生产者 (由`source`标识) 上下文环境中的主题信息。 + 在发布-订阅场景中,订阅者通常会订阅`source`发出的事件, + 但如果`source` 的上下文环境具有内部子结构, + 则单独的`source`标识符可能不足以作为任何指定事件的限定符。 + + Identifying the subject of the event in context metadata (opposed to only in + the `data` payload) is particularly helpful in generic subscription filtering + scenarios where middleware is unable to interpret the `data` content. In the + above example, the subscriber might only be interested in blobs with names + ending with '.jpg' or '.jpeg' and the `subject` attribute allows for + constructing a simple and efficient string-suffix filter for that subset of + events. + +- 约束条件: + - 可选的 + - 若有必须是非空字符串 +- 示例: + - 订阅者可能对在blob在blob存储容器中创建的时候感兴趣并订阅。 + 在这个场景下,事件`source`标示出订阅的范围(存储容器),`type` 标识出 + blob 创建" 这个事件,`id` 唯一标识出事件示例,以区分已创建同名blob的事件, + 而新创建的blob的名字可以放在`subject`属性中: + - `source`: `https://example.com/storage/tenant/container` + - `subject`: `mynewfile.jpg` + +#### time + +- 类型: `Timestamp` +- 描述: 事件发生的时间戳。 + 如果无法确定发生的时间,则 CloudEvents 生产者可以将此属性设置为其他时间(例如当前时间)。 + 但是在这方面,同一`source`的所有生产者必须保持一致。 + 换句话说,要么它们都使用发生的实际时间,要么它们都使用相同的算法来确定所使用的值。 +- 约束条件: + - 可选的 + - 若有则必须遵守 + [RFC 3339](https://tools.ietf.org/html/rfc3339) + +### Extension Context Attributes/扩展上下文属性 + +CloudEvent 可以包含任意数量的具有不同名称的附加上下文属性,被称为"扩展属性"。 +扩展属性必须遵循相同的[命名约定](#attribute-naming-convention)并使用与标准属性相同的 +[类型系统](#type-system)。 +扩展属性在本规范中没有定义好的含义, +它们允许外部系统将元数据附加到事件,就像 HTTP 自定义头部一样。 + +扩展属性总是如标准属性一样,根据绑定规则进行序列化。 +然而,该规范不阻止扩展将事件属性值复制到消息的其他部分, +以便与也其它处理消息的非 CloudEvents 系统进行交互。 +如果复制的值与云事件序列化值不同,执行此操作的扩展规范应该指定接收者如何解释消息。 + +#### 定义扩展 + +在 +[CloudEvent-属性扩展](primer_CN.md#cloudevent-attribute-extensions) +查阅有关扩展使用和定义等相关信息。 + +扩展的定义应该完全定义属性的方方面面——例如 它的名称、类型、语义含义和可能的值。 +新的扩展定义应该使用一个足够描述性的名称来减少与其他扩展的名称冲突的机会。 +特别是,扩展作者应该检查[扩展文件](../../documented-extensions.md)中 +已知的扩展集——不仅是可能的名称冲突,还有相同目的冲突的扩展。 + +许多协议为发送者提供了包含额外元数据的能力,例如作为 HTTP 头部。 +虽然没有强制要求 CloudEvents 接受者处理和传递它们, +但建议接受者通过某种机制进行处理,以明确它们是非 CloudEvents 的元数据。 + +下面是一个示例,说明了 CloudEvents 对附加属性的需求。 +在许多物联网和企业用例中,事件可用于跨多种类型事件执行操作的serverless应用程序中。 +为了支持这样的用例,事件生产者需要向“上下文属性”添加额外的身份属性, +事件消费者可以使用这些属性将这个事件与其他事件相关联。 +如果此类身份属性恰好是事件“数据”的一部分, +则事件生产者还会将身份属性添加到“上下文属性”中, +以便事件消费者可以轻松访问此信息,而无需解码和检查事件数据。 +此类身份属性还可用于帮助中间网关确定如何路由事件。 + +## Event Data/事件数据 + +正如[数据](#data)所定义的那样,CloudEvents 可以包括有关事件的特定域的信息。 +这些信息将被封装在`data`中。 + +- 描述: 事件负载。 本规范对该信息的类型不作任何限制。 + 它被编码为一种媒体格式,这种格式由`datacontenttype` 属性(如 application/json)指定, + 并在存在这些相应属性时遵循`dataschema`格式。 + +- 约束条件: + - 可选的 + +# Size Limits/大小限制 + +在很多情况下,CloudEvents 将通过一个或多个通用中间人进行转发, +每个中间人都可能对转发事件的大小施加限制。 +CloudEvents 也可能直接被路由到消费者,如嵌入式设备, +这些设备是受存储或内存限制的,对单个大型事件表现不佳。 + +事件的“大小”是它的线路大小,包括在线路上为事件传输的每一位: +协议帧元数据、事件元数据和事件数据,基于所选的事件格式和所选的协议绑定。 + +如果应用程序配置需要跨不同协议路由事件或重新编码事件, +应用程序能使用的效率最低的协议和编码,都需要符合这些大小限制: + +- 中间人转发的事件大小必须为 64 KB 或更小。 +- 消费者应该能接受大小至少为 64 KB 的事件。 + +为了方便,上述规则将允许生产者安全地发布最大 64KB 的事件。 +这里的安全意味着生产者期望事件被所有中间人接受并合理地转发。 +它是指在任何特定消费者的控制之下,无论消费者是否由于本地考虑而选择接受或拒绝该大小的事件。 + +通常,CloudEvents 发布者应该通过避免将大型数据项嵌入到事件而使用事件有效链接到此类数据项, +来保持事件紧凑。 +从访问控制的角度来看,这种方法对更广泛的事件分布式化有帮助, +因为通过解析链接访问与事件相关的细节能实现差异化访问控制和选择性披露, +而不是将敏感详细数据直接嵌入到事件中。 + +# Privacy and Security/隐私与安全 + +互操作性是本规范背后的主要驱动力, +实现此目标需要一些信息明确可用,这可能导致信息的泄漏。 + +考虑以下事项以防止信息意外泄漏,尤其是在利用第三方平台和通信网络时: + +- 上下文属性 + + 敏感信息不应在上下文属性中携带。 + + CloudEvent 生产者、消费者和中间人可以自查并记录下上下文属性。 + +- 数据 + + 特定的[事件数据](#event-data) 应该被加密以限制对受信任方的可见性。 + 用于这种加密的机制是生产者和消费者之间的协议,不在本规范的讨论范围内。 + +- 协议绑定 + 应该采用协议级别的安全性机制来确保 CloudEvents 完成可信和安全的交换。 + +# Exmaple/示例 + + +The following example shows a CloudEvent serialized as JSON: + +```JSON +{ + "specversion" : "1.0", + "type" : "com.github.pull_request.opened", + "source" : "https://github.com/cloudevents/spec/pull", + "subject" : "123", + "id" : "A234-1234-1234", + "time" : "2018-04-05T17:31:00Z", + "comexampleextension1" : "value", + "comexampleothervalue" : 5, + "datacontenttype" : "text/xml", + "data" : "" +} +``` diff --git a/community/CONTRIBUTING.md b/community/CONTRIBUTING.md index c9d914cbd..6cf7272ca 100644 --- a/community/CONTRIBUTING.md +++ b/community/CONTRIBUTING.md @@ -1,13 +1,19 @@ # Contributing to CloudEvents + + This page contains information about reporting issues, how to suggest changes as well as the guidelines we follow for how our documents are formatted. ## Table of Contents -- [Reporting an Issue](#reporting-an-issue) -- [Suggesting a Change](#suggesting-a-change) -- [Spec Formatting Conventions](#spec-formatting-conventions) +- [Contributing to CloudEvents](#contributing-to-cloudevents) + - [Table of Contents](#table-of-contents) + - [Reporting an Issue](#reporting-an-issue) + - [Suggesting a Change](#suggesting-a-change) + - [Assigning and Owning work](#assigning-and-owning-work) + - [Sign your work](#sign-your-work) + - [Spec Formatting Conventions](#spec-formatting-conventions) ## Reporting an Issue @@ -25,6 +31,9 @@ set of changes you'd like to see. See the [Spec Formatting Conventions](#spec-formatting-conventions) section for the guidelines we follow for how documents are formatted. +Please use [conventional commits](https://conventionalcommits.org) when writing +commit messages. + Each PR must be signed per the following section. ### Assigning and Owning work diff --git a/community/GOVERNANCE.md b/community/GOVERNANCE.md index ed2bec4d3..e8e1d6545 100644 --- a/community/GOVERNANCE.md +++ b/community/GOVERNANCE.md @@ -1,5 +1,7 @@ # Governance + + This document describes the governance process under which the CloudEvents project will manage this repository. @@ -139,9 +141,15 @@ The specifications produced will adhere to the following: apply and the "major" version number will change. The net effect of this is that the "minor" version number will always be zero and the `specversion` string will always be of the form `X.0`. +- Additionally, the working group has decided that "patch" changes that are + trivial in nature (e.g. typos) can be merged directly into the latest + release without a version number change and without creating a new formal + "patch" branch/release. Non-trivial "patch" changes will necessitate the + creation of a new "patch" branch (e.g. `1.0.2-wip`) and release cycle that + will eventually result in an official "patch" release (e.g. `1.0.2`) Note that these rules do not apply to the -[documented extensions](../documented-extensions.md). +[documented extensions](../cloudevents/documented-extensions.md). To create a new release: @@ -167,7 +175,7 @@ To create a new release: any potential noteworthy activities of the group: - Send it to the mailing list - Announce the release on our - [twitter account](https://twitter.com/cloudeventsio) + [twitter account](http://twitter.com/cloudeventsio) - Add it to the "announcement" section of our [website](https://cloudevents.io/) diff --git a/community/SDK-GOVERNANCE.md b/community/SDK-GOVERNANCE.md index 22a6c6138..01f5102ac 100644 --- a/community/SDK-GOVERNANCE.md +++ b/community/SDK-GOVERNANCE.md @@ -1,5 +1,7 @@ ## SDK Community + + The community is organized as follows: - Every SDK has its own @@ -8,6 +10,29 @@ The community is organized as follows: [cloudevents/sdk-go project](https://github.com/cloudevents/sdk-go) - The union of all the `sdk-*-maintainers` assembles the _sdk maintainers_ group +## New SDKs + +To propose a new SDK for the community, a PR should be opened in the `spec` +repository with the documentation changes necessary to point to the new repo. +For example, changes to the `README.md` and `SDK.md` files. The first comment +in the PR should include: +- desired repo name (e.g. `SDK-...`) +- list of initial maintainers (github IDs) + +Ideally, the new SDK should integrate with a technology stack that the existing +SDKs do not already have support for. + +The community will proceed with a vote using the +[Asynchronous voting process](#asynchronous-voting-process). The voting +criteria are: + +- 1 week to vote +- At least 2/3 of the votes cast agree to the proposal +- All _sdk maintainers_ are entitled to vote + +If approved, the PR will be merged and a new repo and corresponding +github teams will be created. + ## New maintainers Maintainers are a crucial part of this community. They keep our projects alive @@ -64,7 +89,7 @@ We define an SDK project _healthy_ if: 2. It supports the latest versions of the integrated libraries/frameworks 3. It receives security patches regularly 4. It supports the last N-1 major versions of CloudEvents spec, as defined in - [Contribution Acceptance](../SDK.md#contribution-acceptance) + [Contribution Acceptance](../cloudevents/SDK.md#contribution-acceptance) 5. Issues and PRs are triaged (labeled, commented, reviewed, etc) regularly We define a project `cloudevents/sdk-x` _not actively maintained_ if: diff --git a/community/SDK-PR-guidelines.md b/community/SDK-PR-guidelines.md index 38f5d63e9..c3812d198 100644 --- a/community/SDK-PR-guidelines.md +++ b/community/SDK-PR-guidelines.md @@ -1,3 +1,5 @@ + + # Pull Request Guidelines Here you will find step by step guidance for creating, submitting and updating diff --git a/community/SDK-maintainer-guidelines.md b/community/SDK-maintainer-guidelines.md index ac0a79852..c4cd03f33 100644 --- a/community/SDK-maintainer-guidelines.md +++ b/community/SDK-maintainer-guidelines.md @@ -1,5 +1,7 @@ # SDK Maintainer's Guide + + This guide is meant to provide SDK maintainers with some recommended common practices. New and existing SDK maintainers are encouraged to copy this file to their repositories and adopt these guidelines so that contributors may diff --git a/community/contributors.md b/community/contributors.md index 32383d820..bb07bb520 100644 --- a/community/contributors.md +++ b/community/contributors.md @@ -12,39 +12,31 @@ to see who has been involved already. Contributions do not constitute an official endorsement. - **Alibaba** - - [Alibaba Cloud Function Compute](https://www.alibabacloud.com/product/function-compute) - Ryan Zhang - [@nerdyyatrice](https://github.com/nerdyyatrice) - Haoran Yang, Hongqi Wang - Heng Du - [@duhenglucky](https://github.com/duhenglucky) - **Amazon** - - [AWS Lambda events](https://docs.aws.amazon.com/lambda/latest/dg/invoking-lambda-function.html) - Arun Gupta, Ajay Nair, Rob Leidle, Orr Weinstein - **commercetools** - Christoph Neijenhuis - [@cneijenhuis](https://github.com/cneijenhuis) - **Confluent** - Neil Avery - [@bluemonk3y](https://github.com/bluemonk3y) - **Google** - - [Google Cloud Functions](https://cloud.google.com/functions/) and - [Cloud Functions for Firebase](https://firebase.google.com/docs/functions/) - Sarah Allen - [@ultrasaurus](https://github.com/ultrasaurus) - Rachel Myers - [@rachelmyers](https://github.com/rachelmyers) - Thomas Bouldin - [@inlined](https://github.com/inlined) - Mike McDonald, Morgan Hallmon, Robert-Jan Huijsman - Scott Nichols - [@n3wscott](https://github.com/n3wscott) + - Jon Skeet - [@jskeet](https://github.com/jskeet) - **Huawei** - - [Huawei Function Stage](http://www.huaweicloud.com/en-us/product/functionstage.html) - - [Huawei Function Graph](https://www.huaweicloud.com/en-us/product/functiongraph.html) - Cathy Hong Zhang - [@cathyhongzhang](https://github.com/cathyhongzhang) - Louis Fourie - [@lfourie](https://github.com/lfourie) - **IBM** - - [IBM Cloud Functions](https://console.bluemix.net/openwhisk/) - Doug Davis - [@duglin](https://github.com/duglin) - Daniel Krook - [@krook](https://github.com/krook) - Matt Rutkowski - [@mrutkows](https://github.com/mrutkows) - Michael M Behrendt - [@mbehrendt](https://github.com/mbehrendt) - **Iguazio** - - [nuclio (serverless)](https://github.com/nuclio/nuclio) - - [iguazio data platform](https://www.iguazio.com/) - Yaron Haviv - [@yaronha](https://github.com/yaronha) - Orit Nissan-Messing - [@oritnm](https://github.com/oritnm) - **Intel** @@ -52,13 +44,11 @@ Contributions do not constitute an official endorsement. - **Lightbend** - James Roper - [@jroper](https://github.com/jroper) - **Microsoft** - - [Microsoft Event Grid](https://azure.microsoft.com/en-us/services/event-grid/) - Clemens Vasters - [@clemensv](https://github.com/clemensv) - Bahram Banisadr - [@banisadr](https://github.com/banisadr) - Dan Rosanova - [@djrosanova](https://github.com/djrosanova) - Cesar Ruiz-Meraz, Raja Ravipati - **Oracle** - - [Fn Project](https://fnproject.io/) - Chad Arimura - [@carimura](https://github.com/banisadr) - Stanley Halka - [@shalka](https://github.com/banisadr) - Travis Reeder - [@treeder](https://github.com/banisadr) @@ -72,12 +62,10 @@ Contributions do not constitute an official endorsement. - Tihomir Surdilovic - [@tsurdilo](https://github.com/tsurdilo) - Lance Ball - [@lance](https://github.com/lance) - **SAP** - - [kubeless](https://kubeless.io) - Nathan Oyler - [@notque](https://github.com/notque) - Stevo Slavić - [@sslavic](https://github.com/sslavic) - Klaus Deissner - [@deissnerk](https://github.com/deissnerk) - **Serverless Inc** - - [Serverless Framework and Event Gateway](https://serverless.com/) - Austen Collins - [@ac360](https://github.com/ac360) - Rupak Ganguly - [@rupakg](https://github.com/rupakg) - Brian Neisler - [@brianneisler](https://github.com/brianneisler) @@ -85,5 +73,6 @@ Contributions do not constitute an official endorsement. - **SolarWinds** - Lee Calcote - [@leecalcote](https://github.com/leecalcote) - **VMWare** - - [Dispatch Functions Framework](http://dispatchframework.io) - Mark Peek - [@markpeek](https://github.com/markpeek) +- **Individuals** + - Rémi Cattiau - [@loopingz](https://github.com/loopingz) diff --git a/community/demos.md b/community/demos.md index e4c2011fe..b075b9b75 100644 --- a/community/demos.md +++ b/community/demos.md @@ -1,3 +1,5 @@ + + If you have a demo of CloudEvents in action, please add a link here. If there isn't an associated blog or github repo, feel free to add descriptive text as a markdown file in `community/demos/`. diff --git a/community/open-source.md b/community/open-source.md index c83489613..8cb164208 100644 --- a/community/open-source.md +++ b/community/open-source.md @@ -1,16 +1,43 @@ If you have created (or know of) an open source library or product that uses -CloudEvents v1.0+, please include in the list below. - -## Routing and Platforms +CloudEvents, please include in the list below. +- [CloudEvents.NET](https://github.com/aliencube/CloudEvents.NET): is a .NET + implementation of the CloudEvents [spec](../cloudevents/spec.md) and + [HTTP protocol binding](../cloudevents/bindings/http-protocol-binding.md). It has been released to + [nuget.org](https://www.nuget.org/packages?q=Aliencube.CloudEventsNet). It + also contains some app + [samples](https://github.com/aliencube/CloudEvents.NET/tree/master/sample) + of 1) console app to Web API, and 2) Web API to Azure Event Grid, which + demonstrates how CloudEvent messages are generated and sent to Web API and + Azure Event Grid over HTTP. +- [microBean CloudEvents](https://microbean.github.io/microbean-cloudevents/): + CloudEvents represented as plain Java objects. Satellite projects add + [Jackson and CDI event integration](https://microbean.github.io/microbean-cloudevents-jackson-cdi). +- [jCloudEvents](https://github.com/project-streamzi/jcloudevents): Java POJO + implementation of the CloudEvents specification and some CDI bindings. +- [Strombrau Gateway](https://github.com/project-streamzi/event-gateway): Vert.x + based gateway routing CloudEvent metadata to internal Apache Kafka topic +- [Event Gateway](https://github.com/serverless/event-gateway): It's dataflow + for event-driven, serverless architectures. The Event Gateway combines both + API Gateway and Pub/Sub functionality into a single event-driven experience. +- [CloudEvents Extend API](https://github.com/goextend/cloudevents-extend-api) + is a JavaScript programming model for Extend which allows handling Cloud + Events. +- [CloudEvents Verify](https://github.com/btbd/CEVerify): is a tool to help + verify CloudEvents according to the proper specifications. It is currently + being hosted publicly [here](http://soaphub.org/ceverify). +- [Gloo](https://github.com/solo-io/gloo): is a function gateway built on top of + [Envoy Proxy](https://envoyproxy.io/) by [Solo.io](https://www.solo.io/) that + supports CloudEvents. +- [cloudevents-python](https://github.com/williamhogman/cloudevents-python): A + CloudEvents library for python. - [Argo-Events](https://github.com/argoproj/argo-events): An event-based dependency manager for Kubernetes which uses sensors to act on CloudEvents. +- [cloudevent.js](https://github.com/smartiniOnGitHub/cloudevent.js): A + CloudEvents library for Node.js. +- [CloudEvents JSON Schema](https://marketplace.visualstudio.com/items?itemName=tsurdilovic.cloudevents-schema-vscode): + Visual Studio Code extension for CloudEvents format. - [Knative Eventing](https://knative.dev) implements CloudEvents based sources and event delivery abstractions build on top of Kubernetes. - [VMware Event Broker Appliance](https://vmweventbroker.io) enables event driven workflows from vCenter Server Events. - -## Tooling and Extensions - -- [CloudEvents JSON Schema](https://marketplace.visualstudio.com/items?itemName=tsurdilovic.cloudevents-schema-vscode): - Visual Studio Code extension for CloudEvents format. diff --git a/misc/Makefile b/misc/Makefile new file mode 100644 index 000000000..0098e6850 --- /dev/null +++ b/misc/Makefile @@ -0,0 +1,10 @@ +all: verify + +verify: + @echo Running href checker: + @# Use "-x" if you want to skip external links + @misc/tools/verify-links.sh -t -v . + @echo Running the spec phrase checker: + @misc/tools/verify-specs.sh -v . + @echo Running the doc phrase checker: + @misc/tools/verify-docs.sh -v . diff --git a/misc/RELEASE_NOTES.md b/misc/RELEASE_NOTES.md new file mode 100644 index 000000000..5740cc5f1 --- /dev/null +++ b/misc/RELEASE_NOTES.md @@ -0,0 +1,91 @@ +# CloudEvents Release Notes + +## v1.0.2 - 2022/02/03 + +- Add C# namespace option to proto - #937 +- Tweak SDK requirements wording - #915 +- Re-organized repo directory structure - #904/#905 +- Translate CE specs into Chinese - #899/#898 +- Explicitly state application/json defaulting when serializing - #881 +- Add PowerShell SDK to the list of SDKs - #875 +- WebHook "Origin" header concept clashes with RFC6454 - #870 +- Clarify data encoding in JSON format with a JSON datacontenttype - #861 +- Webhook-Allowed-Origin instead of Webhook-Request-Origin - #836 +- Clean-up of Sampled Rate Extension - #832 +- Remove the conflicting sentence in Kafka Binding - #823/#813 +- Fix the sentences conflict in Kafka Binding - #814 +- Clarify HTTP header value encoding and decoding requirements - #793 +- Expand versioning suggestions in Primer - #799 +- Add support for protobuf batch format - #801 +- Clarify HTTP header value encoding and decoding requirements - #816 +- Primer guidance for dealing with errors - #763 +- Information Classification Extension - #785 +- Clarify the role of partitioning extension in Kafka - #727 + +## v1.0.1 - 2020/12/12 +- Add protobuf format as a sub-protocol - #721 +- Allow JSON values to be null, meaning unset - #713 +- [Primer] Adding a Non-Goal w.r.t Security - #712 +- WebSockets protocol binding - #697 +- Clarify difference between message mode and HTTP content mode - #672 +- add missing sdks to readme - #666 +- New sdk maintainers rules - #665 +- move sdk governance and cleanup - #663 +- Bring 'datadef' definition into line with specification - #658 +- Add CoC and move some governance docs into 'community' - #656 +- Add blog post around understanding Cloud Events interactions - #651 +- SDK governance draft - #649 +- docs: add common processes for SDK maintainers and contributors - #648 +- Adding Demo for Cloud Events Orchestration - #646 +- Clarified MUST requirement for JSON format - #644 +- Re-Introducing Protocol Buffer Representation - #626 +- Closes #615 - #616 +- Reworked Distributed Tracing Extension - #607 +- Minor updates to Cloud Events Primer - #600 +- Kafka clarifications - #599 +- Proprietary binding spec inclusion guide - #595 +- Adding link to Pub/Sub binding - #588 +- Add some clarity around SDK milestones - #584 +- How to determine binary CE vs random non-CE message - #577 +- Adding Visual Studio Code extension to community open-source doc - #573 +- Specify encoding of kafka header keys and values and message key - #572 +- Fix distributed tracing example - #569 +- Paragraph about nested events to the primer - #567 +- add rules for changing Admins- #564 +- Updating JSON Schema - #563 +- Say it's ok to ignore non-MUST recommendations - at your own risk - #562 +- Update Distributed Tracing extension spec links - #550 +- Add Ruby SDK to SDK lists - #548 + +## v1.0.0 - 2019/10/24 +- Use "producer" and "consumer" instead of "sender" and "receiver" +- Clarification that intermediaries should forward optional attributes +- Remove constraint that attribute names must start with a letter +- Remove suggestion that attributes names should be descriptive and terse +- Clarify that a single occurrence may result in more than one event +- Add an Event Data section (replacing `data`), making event data a top level + concept rather than an attribute +- Introduce an Event Format section +- Define structured-mode and binary-mode messages +- Define protocol binding +- Add extension attributes into "context attributes" description +- Move mention of attribute serialization mechanism from "context attributes" + description into "type system" +- Change "transport" to "protocol" universally +- Introduce the Boolean, URI and URI-reference types for attributes +- Remove the Any and Map types for attributes +- Clarify which Unicode characters are permitted in String attributes +- Require all context attribute values to be one of the listed types, + and state that they may be presented as native types or strings. +- Require `source` to be non-empty; recommend an absolute URI +- Update version number from 0.3 to 1.0 +- Clarify that `type` is related to "the originating occurrence" +- Remove `datacontentencoding` section +- Clarify handling of missing `datacontenttype` attribute +- Rename `schemaurl` to `dataschema`, and change type from URI-reference to URI +- Constrain `dataschema` to be non-empty (when present) +- Add details of how `time` can be generated when it can't be determined, + specifically around consistency within a source +- Add details of extension context attribute handling +- Add recommendation that CloudEvent receivers pass on non-CloudEvent metadata +- Sample CloudEvent no longer has a JSON object as a sample extension value diff --git a/artwork/README.md b/misc/artwork/README.md similarity index 100% rename from artwork/README.md rename to misc/artwork/README.md diff --git a/roadmap.md b/misc/roadmap.md similarity index 89% rename from roadmap.md rename to misc/roadmap.md index 3fd8e0ffa..588a38ef1 100644 --- a/roadmap.md +++ b/misc/roadmap.md @@ -1,5 +1,7 @@ ## Roadmap + + The CloudEvents Roadmap. _Note: The ordered lists for each milestone provide a way to reference each @@ -29,9 +31,9 @@ _0.1_ - Completed - 2018/04/20 1. Have at least 2 implementations of the specification that can demonstrate interoperability. 1. Include a specification for mapping the CloudEvents specification to - [HTTP](http-protocol-binding.md). + [HTTP](../cloudevents/bindings/http-protocol-binding.md). 1. Include a specification for mapping the CloudEvents specification to - [JSON](json-format.md). + [JSON](../cloudevents/formats/json-format.md). 1. Changes to the spec to facilitate adoption. 1. Publicize at conferences ([CloudNativeCon Europe](https://events.linuxfoundation.org/events/kubecon-cloudnativecon-north-america-2018/)). @@ -80,7 +82,17 @@ _1.0_ - Completed - 2019/10/24 Format and protocol-binding specs may introduce breaking change if necessary to align with the core spec. -_Post 1.0_ +_1.0.1_ - Completed - 2020/12/10 + +1. See [V1.0.1 Release](https://github.com/cloudevents/spec/releases/tag/v1.0.1) + for details. + +_1.0.2_ - Completed - 2022/02/03 + +1. See [V1.0.2 Release](https://github.com/cloudevents/spec/releases/tag/v1.0.2) + for details. + +_Future_ - All remaining issues and PRs will be examined. - How, and when, future releases (major, minor or patch) will be released will diff --git a/share/2018-02-22-CloudEvents-Routing.pptx b/misc/share/2018-02-22-CloudEvents-Routing.pptx similarity index 100% rename from share/2018-02-22-CloudEvents-Routing.pptx rename to misc/share/2018-02-22-CloudEvents-Routing.pptx diff --git a/share/2018-02-22-CloudEvents.pdf b/misc/share/2018-02-22-CloudEvents.pdf similarity index 100% rename from share/2018-02-22-CloudEvents.pdf rename to misc/share/2018-02-22-CloudEvents.pdf diff --git a/share/2018-03-22-TopicsAndSubjects.pptx b/misc/share/2018-03-22-TopicsAndSubjects.pptx similarity index 100% rename from share/2018-03-22-TopicsAndSubjects.pptx rename to misc/share/2018-03-22-TopicsAndSubjects.pptx diff --git a/share/2018-11-14-KubeCon-Intro-DeepDive.pdf b/misc/share/2018-11-14-KubeCon-Intro-DeepDive.pdf similarity index 100% rename from share/2018-11-14-KubeCon-Intro-DeepDive.pdf rename to misc/share/2018-11-14-KubeCon-Intro-DeepDive.pdf diff --git a/share/README.md b/misc/share/README.md similarity index 100% rename from share/README.md rename to misc/share/README.md diff --git a/tools/verify-docs.sh b/misc/tools/verify-docs.sh similarity index 100% rename from tools/verify-docs.sh rename to misc/tools/verify-docs.sh diff --git a/tools/verify-links.sh b/misc/tools/verify-links.sh similarity index 93% rename from tools/verify-links.sh rename to misc/tools/verify-links.sh index e55d98f70..3408cb824 100755 --- a/tools/verify-links.sh +++ b/misc/tools/verify-links.sh @@ -161,11 +161,30 @@ for file in ${mdFiles}; do sed 's/)/)\ /g' | \ sed "s/^/ /g" | \ - grep "[^\\]\[.*\](.*)" > ${tmp}1 || continue + grep "[^\\]\[.*\](.*)" > ${tmp}1 || true # This sed will extract the href portion of the [..](..) - meaning # the stuff in the parens. - sed "s/.*\[*\]\([^()]*\)/\1/" < ${tmp}1 > ${tmp}2 || continue + sed "s/.*\[*\]\([^()]*\)/\1/" < ${tmp}1 > ${tmp}2 || true + + # Look for bookmark URLs + cat $file | sed -n "s/^ *\[.*\]: .*/&/p" > ${tmp}bks || true + + # Look for bookmarks + cat $file | \ + tr '\n' ' ' | \ + sed -e 's/\[[^][]*\]\[[^][]*\]/&\ +/g' | \ + sed -n -e 's/^.*\[.*\[\(.*\)\]$/\1/p' > "${tmp}links" || true + + cat ${tmp}links | while read bk ; do + grep -q "^ *\\[${bk}\\]: " ${tmp}bks || + echo "$file: Can't find bookmark '[$bk]'" | \ + tee -a ${tmp}3 + done + + # Skip file if there are no matches + [ ! -s ${tmp}2 ] && continue cat ${tmp}2 | while read line ; do # Strip off the leading and trailing parens diff --git a/tools/verify-specs.sh b/misc/tools/verify-specs.sh similarity index 92% rename from tools/verify-specs.sh rename to misc/tools/verify-specs.sh index 6a91f5e34..8272eeab5 100755 --- a/tools/verify-specs.sh +++ b/misc/tools/verify-specs.sh @@ -103,9 +103,20 @@ function checkFile { fi done + for phrase in "${bannedPhrases[@]}"; do + words=( ${phrase[@]} ) + if (( ${#words[@]} > $maxWords )); then + maxWords=${#words[@]} + fi + done + lines=( "" ) words=( "" ) + if grep -i "