From 268d79d4c5637b117baf7187ecf67626bfd31aac Mon Sep 17 00:00:00 2001
From: Rishi <52498617+kaushik-rishi@users.noreply.github.com>
Date: Tue, 25 Jul 2023 15:50:45 +0530
Subject: [PATCH 1/5] ci: update release workflow (#939)
---
.github/workflows/release.yml | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 8252eadd..34ce3e2d 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -13,11 +13,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Setup Node.js
- uses: actions/setup-node@v1
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18
- name: Add plugin for conventional commits
- run: npm install conventional-changelog-conventionalcommits
+ run: npm install --save-dev conventional-changelog-conventionalcommits@5.0.0
- name: Release to GitHub
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
From 121ea2b09af6ef57b3cd0c01baeb28f0f869e87c Mon Sep 17 00:00:00 2001
From: Lukasz Gornicki
Date: Fri, 11 Aug 2023 12:43:16 +0200
Subject: [PATCH 2/5] ci: upgrade GH workflows and fix markdown linting (#958)
---
.github/workflows/lint.yml | 9 +-
.github/workflows/new-spec-release.yml | 14 +--
.github/workflows/update-spec.yaml | 6 +-
.markdownlint.yaml | 9 ++
CONTRIBUTING.md | 8 ++
mlc_config.json | 19 ---
spec/asyncapi.md | 164 +++++++++----------------
7 files changed, 89 insertions(+), 140 deletions(-)
create mode 100644 .markdownlint.yaml
delete mode 100644 mlc_config.json
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 0fab4bd2..2b23e7fb 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -1,15 +1,16 @@
-name: Lint
+name: Lint specification markdown file
on:
pull_request:
types: [opened, reopened, synchronize, ready_for_review]
+ paths:
+ - 'spec/asyncapi.md'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Run linter
- run: npx mdv spec/*.md
-
+ run: docker run -v $PWD:/workdir ghcr.io/igorshubovych/markdownlint-cli:v0.35.0 "spec/asyncapi.md"
\ No newline at end of file
diff --git a/.github/workflows/new-spec-release.yml b/.github/workflows/new-spec-release.yml
index eadf1fda..11c59cd0 100644
--- a/.github/workflows/new-spec-release.yml
+++ b/.github/workflows/new-spec-release.yml
@@ -13,12 +13,12 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
steps:
- name: Checkout Current repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
path: spec
ref: ${{ github.event.release.target_commitish }}
- name: Checkout Another repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
repository: asyncapi/website
path: website
@@ -32,7 +32,7 @@ jobs:
run: |
git checkout -b spec-release-${{github.event.release.tag_name}}
- name: Check for previous spec file and remove it
- uses: actions/github-script@v3
+ uses: actions/github-script@v6
with:
github-token: ${{ env.GITHUB_TOKEN }}
script: |
@@ -53,14 +53,14 @@ jobs:
run: |
cp ../spec/spec/asyncapi.md ./pages/docs/reference/specification/${{github.event.release.tag_name}}.md
- name: Remove Table of Contents from Spec
- uses: actions/github-script@v4
+ uses: actions/github-script@v6
with:
github-token: ${{ env.GITHUB_TOKEN }}
script: |
const script = require('./spec/.github/scripts/remove-toc');
script(`${{github.event.release.tag_name}}`);
- name: Change the redirect file to point to latest spec
- uses: actions/github-script@v3
+ uses: actions/github-script@v6
if: ${{github.event.release.prerelease == false}}
with:
github-token: ${{ env.GITHUB_TOKEN }}
@@ -90,7 +90,7 @@ jobs:
fs.writeFileSync("./website/public/_redirects", newRedirect);
- name: Remove previous pre-release redirects in case of a new release
- uses: actions/github-script@v3
+ uses: actions/github-script@v6
with:
github-token: ${{ env.GITHUB_TOKEN }}
script: |
@@ -125,7 +125,7 @@ jobs:
fs.writeFileSync("./website/public/_redirects", newRedirect);
- name: Change the redirect file to point to specs
- uses: actions/github-script@v3
+ uses: actions/github-script@v6
with:
github-token: ${{ env.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/update-spec.yaml b/.github/workflows/update-spec.yaml
index d5ad7aa1..49b2481b 100644
--- a/.github/workflows/update-spec.yaml
+++ b/.github/workflows/update-spec.yaml
@@ -15,11 +15,11 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
steps:
- name: Checkout Current repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
path: spec
- name: Checkout Another repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
repository: asyncapi/website
path: website
@@ -43,7 +43,7 @@ jobs:
run: |
cp ../spec/spec/asyncapi.md ./pages/docs/reference/specification/${{ steps.latest_version.outputs.latest_tag }}.md
- name: Remove Table of Contents from Spec
- uses: actions/github-script@v4
+ uses: actions/github-script@v6
with:
github-token: ${{ env.GITHUB_TOKEN }}
script: |
diff --git a/.markdownlint.yaml b/.markdownlint.yaml
new file mode 100644
index 00000000..7b77ce97
--- /dev/null
+++ b/.markdownlint.yaml
@@ -0,0 +1,9 @@
+# MD013/line-length - Line length
+# We should keep it disabled as this line length limit do not maeke sense really
+MD013: false
+# MD033/no-inline-html - Inline HTML
+# We use HTML links in deadings all over the place. Probably this is why links in GitHub do not work, but that requires investingation if we can remove them really
+MD033: false
+# MD024/no-duplicate-heading/no-duplicate-header - Multiple headings with the same content
+# For now hard to say how that should be fixed as we have such duplicates like Fixed Fields all over the place
+MD024: false
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c82242d8..d096c5f4 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -243,6 +243,14 @@ A pull request can be merged if all the following conditions are met:
* There is, at least, a mininum of 3 approvals from the [repository code owners](./CODEOWNERS).
* Sufficient time has passed to let all code owners review the pull request. As of now, it should be a minimum of 1 week. If all code owners have already approved a pull request, it's ok not to wait for this period of time.
+## Linting specification document
+
+Always make sure that the specification markdown file has no markdown-related errors.
+
+Instead of waiting for GitHub Actions workflow to check markdown file, you can do it locally by calling the following docker command:
+```bash
+docker run -v $PWD:/workdir ghcr.io/igorshubovych/markdownlint-cli:v0.35.0 "spec/asyncapi.md"
+```
## References
This document was adapted from the [GraphQL Specification Contribution Guide](https://github.com/graphql/graphql-spec/blob/main/CONTRIBUTING.md).
\ No newline at end of file
diff --git a/mlc_config.json b/mlc_config.json
deleted file mode 100644
index 01833db7..00000000
--- a/mlc_config.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "ignorePatterns": [
- {
- "pattern": "^https://github.com/asyncapi/spec/tree/BRANCH_NAME"
- },
- {
- "pattern": "^https://github.com/asyncapi/spec-json-schemas/tree/BRANCH_NAME"
- },
- {
- "pattern": "^https://github.com/asyncapi/parser-js/tree/BRANCH_NAME"
- },
- {
- "pattern": "^https://github.com/asyncapi/website/pull/PULLREQUEST"
- },
- {
- "pattern": "^https://github.com/asyncapi/spec/blob/.*.md$"
- }
- ]
-}
diff --git a/spec/asyncapi.md b/spec/asyncapi.md
index 1fb6c8bd..26bbd7f3 100644
--- a/spec/asyncapi.md
+++ b/spec/asyncapi.md
@@ -1,10 +1,10 @@
# AsyncAPI Specification
-#### Disclaimer
+## Disclaimer
Part of this content has been taken from the great work done by the folks at the [OpenAPI Initiative](https://openapis.org). Mainly because **it's a great work** and we want to keep as much compatibility as possible with the [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification).
-#### Version 2.6.0
+## Version 2.6.0
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).
@@ -86,29 +86,37 @@ It means that the [application](#definitionsApplication) allows [consumers](#def
## Definitions
-#### Server
+### Server
+
A server MAY be a message broker that is capable of sending and/or receiving between a [producer](#definitionsProducer) and [consumer](#definitionsConsumer). A server MAY be a service with WebSocket API that enables message-driven communication between browser-to-server or server-to-server.
-#### Application
-An application is any kind of computer program or a group of them. It MUST be a [producer](#definitionsProducer), a [consumer](#definitionsConsumer) or both. An application MAY be a microservice, IoT device (sensor), mainframe process, etc. An application MAY be written in any number of different programming languages as long as they support the selected [protocol](#definitionsProtocol). An application MUST also use a protocol supported by the [server](#definitionsServer) in order to connect and exchange [messages](#definitionsMessage).
+### Application
+
+An application is any kind of computer program or a group of them. It MUST be a [producer](#definitionsProducer), a [consumer](#definitionsConsumer) or both. An application MAY be a microservice, IoT device (sensor), mainframe process, etc. An application MAY be written in any number of different programming languages as long as they support the selected [protocol](#definitionsProtocol). An application MUST also use a protocol supported by the [server](#definitionsServer) in order to connect and exchange [messages](#definitionsMessage).
+
+### Producer
-#### Producer
A producer is a type of application, connected to a [server](#definitionsServer), that is creating [messages](#definitionsMessage) and addressing them to [channels](#definitionsChannel). A producer MAY be publishing to multiple channels depending on the [server](#definitionsServer), protocol, and use-case pattern.
-#### Consumer
+### Consumer
+
A consumer is a type of application, connected to a [server](#definitionsServer) via a supported [protocol](#definitionsProtocol), that is consuming [messages](#definitionsMessage) from [channels](#definitionsChannel). A consumer MAY be consuming from multiple channels depending on the [server](#definitionsServer), protocol, and the use-case pattern.
-#### Message
-A message is the mechanism by which information is exchanged via a channel between [servers](#definitionsServer) and applications. A message MUST contain a payload and MAY also contain headers. The headers MAY be subdivided into [protocol](#definitionsProtocol)-defined headers and header properties defined by the application which can act as supporting metadata. The payload contains the data, defined by the application, which MUST be serialized into a format (JSON, XML, Avro, binary, etc.). Since a message is a generic mechanism, it can support multiple interaction patterns such as event, command, request, or response.
+### Message
+
+A message is the mechanism by which information is exchanged via a channel between [servers](#definitionsServer) and applications. A message MUST contain a payload and MAY also contain headers. The headers MAY be subdivided into [protocol](#definitionsProtocol)-defined headers and header properties defined by the application which can act as supporting metadata. The payload contains the data, defined by the application, which MUST be serialized into a format (JSON, XML, Avro, binary, etc.). Since a message is a generic mechanism, it can support multiple interaction patterns such as event, command, request, or response.
+
+### Channel
-#### Channel
A channel is an addressable component, made available by the [server](#definitionsServer), for the organization of [messages](#definitionsMessage). [Producer](#definitionsProducer) applications send messages to channels and [consumer](#definitionsConsumer) applications consume messages from channels. [Servers](#definitionsServer) MAY support many channel instances, allowing messages with different content to be addressed to different channels. Depending on the [server](#definitionsServer) implementation, the channel MAY be included in the message via protocol-defined headers.
-#### Protocol
+### Protocol
+
A protocol is the mechanism (wireline protocol or API) by which [messages](#definitionsMessage) are exchanged between the application and the [channel](#definitionsChannel). Example protocols include, but are not limited to, AMQP, HTTP, JMS, Kafka, Anypoint MQ, MQTT, Solace, STOMP, Mercure, WebSocket, Google Pub/Sub, Pulsar.
-#### Bindings
-A "binding" (or "protocol binding") is a mechanism to define protocol-specific information. Therefore, a protocol binding MUST define protocol-specific information only.
+### Bindings
+
+A "binding" (or "protocol binding") is a mechanism to define protocol-specific information. Therefore, a protocol binding MUST define protocol-specific information only.
## Specification
@@ -170,7 +178,6 @@ Field Name | Type | Description
tags | [Tags Object](#tagsObject) | A list of tags used by the specification with additional metadata. Each tag name in the list MUST be unique.
externalDocs | [External Documentation Object](#externalDocumentationObject) | Additional external documentation.
-
This object MAY be extended with [Specification Extensions](#specificationExtensions).
#### AsyncAPI Version String
@@ -189,7 +196,7 @@ This field represents a unique universal identifier of the [application](#defini
It is RECOMMENDED to use a [URN](https://tools.ietf.org/html/rfc8141) to globally and uniquely identify the application during long periods of time, even after it becomes unavailable or ceases to exist.
-###### Examples
+##### Examples
```json
{
@@ -229,7 +236,7 @@ Field Name | Type | Description
This object MAY be extended with [Specification Extensions](#specificationExtensions).
-##### Info Object Example:
+##### Info Object Example
```json
{
@@ -277,7 +284,7 @@ Field Name | Type | Description
This object MAY be extended with [Specification Extensions](#specificationExtensions).
-##### Contact Object Example:
+##### Contact Object Example
```json
{
@@ -306,7 +313,7 @@ Field Name | Type | Description
This object MAY be extended with [Specification Extensions](#specificationExtensions).
-##### License Object Example:
+##### License Object Example
```json
{
@@ -351,7 +358,6 @@ production:
protocolVersion: '1.0.0'
```
-
#### Server Object
An object representing a message broker, a server or any other kind of computer program capable of sending and/or receiving data. This object is used to capture details such as URIs, protocols and security configuration. Variable substitution can be used so that some details, for example usernames and passwords, can be injected by code generation tools.
@@ -515,7 +521,6 @@ servers:
default: v2
```
-
#### Server Variable Object
An object representing a Server Variable for server URL template substitution.
@@ -531,10 +536,6 @@ Field Name | Type | Description
This object MAY be extended with [Specification Extensions](#specificationExtensions).
-
-
-
-
#### Default Content Type
A string representing the default content type to use when encoding/decoding a message's payload. The value MUST be a specific media type (e.g. `application/json`). This value MUST be used by schema parsers when the [contentType](#messageObjectContentType) property is omitted.
@@ -553,11 +554,6 @@ In case a message can't be encoded/decoded using this value, schema parsers MUST
defaultContentType: application/json
```
-
-
-
-
-
#### Channels Object
Holds the relative paths to the individual channel and their operations. Channel paths are relative to servers.
@@ -591,9 +587,6 @@ user/signedup:
$ref: "#/components/messages/userSignedUp"
```
-
-
-
#### Channel Item Object
Describes the operations available on a single channel.
@@ -602,7 +595,7 @@ Describes the operations available on a single channel.
Field Name | Type | Description
---|:---:|---
-$ref | `string` | Allows for a referenced definition of this channel item. The referenced structure MUST be in the form of a [Channel Item Object](#channelItemObject). In case a Channel Item Object field appears both in the defined object and the referenced object, the behavior is *undefined*. Resolution is done as defined by the [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03).
**Deprecated:** Usage of the `$ref` property has been deprecated.
+$ref | `string` | Allows for a referenced definition of this channel item. The referenced structure MUST be in the form of a [Channel Item Object](#channelItemObject). In case a Channel Item Object field appears both in the defined object and the referenced object, the behavior is _undefined_. Resolution is done as defined by the [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03).
**Deprecated:** Usage of the `$ref` property has been deprecated.
description | `string` | An optional description of this channel item. [CommonMark syntax](https://spec.commonmark.org/) can be used for rich text representation.
servers | [`string`] | The servers on which this channel is available, specified as an optional unordered list of names (string keys) of [Server Objects](#serverObject) defined in the [Servers Object](#serversObject) (a map). If `servers` is absent or empty then this channel must be available on all servers defined in the [Servers Object](#serversObject).
subscribe | [Operation Object](#operationObject) | A definition of the SUBSCRIBE operation, which defines the messages produced by the application and sent to the channel.
@@ -688,7 +681,6 @@ subscribe:
- $ref: '#/components/messages/login'
```
-
Using explicit by-name references to the servers on which the channel is available:
```json
@@ -724,10 +716,6 @@ bindings:
is: queue
```
-
-
-
-
#### Operation Object
Describes a publish or a subscribe operation. This provides a place to document how and why messages are sent and received.
@@ -836,9 +824,6 @@ traits:
- $ref: "#/components/operationTraits/kafka"
```
-
-
-
#### Operation Trait Object
Describes a trait that MAY be applied to an [Operation Object](#operationObject). This object MAY contain any property from the [Operation Object](#operationObject), except `message` and `traits`.
@@ -877,9 +862,6 @@ bindings:
ack: false
```
-
-
-
#### Parameters Object
Describes a map of parameters included in a channel name.
@@ -926,10 +908,6 @@ user/{userId}/signup:
$ref: "#/components/messages/userSignedUp"
```
-
-
-
-
#### Parameter Object
Describes a parameter included in a channel name.
@@ -980,9 +958,6 @@ user/{userId}/signup:
$ref: "#/components/messages/userSignedUp"
```
-
-
-
#### Server Bindings Object
Map describing protocol-specific definitions for a server.
@@ -1013,8 +988,6 @@ Field Name | Type | Description
This object MAY be extended with [Specification Extensions](#specificationExtensions).
-
-
#### Channel Bindings Object
Map describing protocol-specific definitions for a channel.
@@ -1045,8 +1018,6 @@ Field Name | Type | Description
This object MAY be extended with [Specification Extensions](#specificationExtensions).
-
-
#### Operation Bindings Object
Map describing protocol-specific definitions for an operation.
@@ -1077,9 +1048,6 @@ Field Name | Type | Description
This object MAY be extended with [Specification Extensions](#specificationExtensions).
-
-
-
#### Message Bindings Object
Map describing protocol-specific definitions for a message.
@@ -1110,12 +1078,6 @@ Field Name | Type | Description
This object MAY be extended with [Specification Extensions](#specificationExtensions).
-
-
-
-
-
-
#### Message Object
Describes a message received on a given channel and operation.
@@ -1149,17 +1111,16 @@ The following table contains a set of values that every implementation MUST supp
Name | Allowed values | Notes
---|:---:|---
[AsyncAPI 2.6.0 Schema Object](#schemaObject) | `application/vnd.aai.asyncapi;version=2.6.0`, `application/vnd.aai.asyncapi+json;version=2.6.0`, `application/vnd.aai.asyncapi+yaml;version=2.6.0` | This is the default when a `schemaFormat` is not provided.
-[JSON Schema Draft 07](https://json-schema.org/specification-links.html#draft-7) | `application/schema+json;version=draft-07`, `application/schema+yaml;version=draft-07` |
+[JSON Schema Draft 07](https://json-schema.org/specification-links.html#draft-7) | `application/schema+json;version=draft-07`, `application/schema+yaml;version=draft-07` |
The following table contains a set of values that every implementation is RECOMMENDED to support.
Name | Allowed values | Notes
---|:---:|---
[Avro 1.9.0 schema](https://avro.apache.org/docs/1.9.0/spec.html#schemas) | `application/vnd.apache.avro;version=1.9.0`, `application/vnd.apache.avro+json;version=1.9.0`, `application/vnd.apache.avro+yaml;version=1.9.0` |
-[OpenAPI 3.0.0 Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject) | `application/vnd.oai.openapi;version=3.0.0`, `application/vnd.oai.openapi+json;version=3.0.0`, `application/vnd.oai.openapi+yaml;version=3.0.0` |
+[OpenAPI 3.0.0 Schema Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject) | `application/vnd.oai.openapi;version=3.0.0`, `application/vnd.oai.openapi+json;version=3.0.0`, `application/vnd.oai.openapi+yaml;version=3.0.0` |
[RAML 1.0 data type](https://github.com/raml-org/raml-spec/blob/master/versions/raml-10/raml-10.md/) | `application/raml+yaml;version=1.0` |
-
##### Message Object Example
```json
@@ -1308,12 +1269,6 @@ payload:
$ref: 'path/to/user-create.avsc/#UserCreate'
```
-
-
-
-
-
-
#### Message Trait Object
Describes a trait that MAY be applied to a [Message Object](#messageObject). This object MAY contain any property from the [Message Object](#messageObject), except `payload` and `traits`.
@@ -1356,13 +1311,13 @@ contentType: application/json
#### Message Example Object
-Message Example Object represents an example of a [Message Object](#messageObject) and MUST contain either **headers** and/or **payload** fields.
+Message Example Object represents an example of a [Message Object](#messageObject) and MUST contain either **headers** and/or **payload** fields.
##### Fixed Fields
Field Name | Type | Description
---|:---:|---
-headers | `Map[string, any]` | The value of this field MUST validate against the [Message Object's headers](#messageObjectHeaders) field.
+headers | `Map[string, any]` | The value of this field MUST validate against the [Message Object's headers](#messageObjectHeaders) field.
payload | `any` | The value of this field MUST validate against the [Message Object's payload](#messageObjectPayload) field.
name | `string` | A machine-friendly name.
summary | `string` | A short summary of what the example is about.
@@ -1412,6 +1367,7 @@ A Tags object is a list of Tag Objects.
Allows adding meta data to a single tag.
##### Fixed Fields
+
Field Name | Type | Description
---|:---:|---
name | `string` | **REQUIRED.** The name of the tag.
@@ -1424,8 +1380,8 @@ This object MAY be extended with [Specification Extensions](#specificationExtens
```json
{
- "name": "user",
- "description": "User-related messages"
+ "name": "user",
+ "description": "User-related messages"
}
```
@@ -1434,12 +1390,6 @@ name: user
description: User-related messages
```
-
-
-
-
-
-
#### External Documentation Object
Allows referencing an external resource for extended documentation.
@@ -1476,6 +1426,7 @@ The Reference Object is defined by [JSON Reference](https://tools.ietf.org/html/
For this specification, reference resolution is done as defined by the JSON Reference specification and not by the JSON Schema specification.
##### Fixed Fields
+
Field Name | Type | Description
---|:---:|---
$ref | `string` | **REQUIRED.** The reference string.
@@ -1502,10 +1453,10 @@ All objects defined within the components object will have no effect on the API
##### Fixed Fields
Field Name | Type | Description
----|:---|---
+---|:---|---
schemas | Map[`string`, [Schema Object](#schemaObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Schema Objects](#schemaObject).
servers | Map[`string`, [Server Object](#serverObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Server Objects](#serverObject).
- serverVariables | Map[`string`, [Server Variable Object](#serverVariableObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Server Variable Objects](#serverVariableObject).
+ serverVariables | Map[`string`, [Server Variable Object](#serverVariableObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Server Variable Objects](#serverVariableObject).
channels | Map[`string`, [Channel Item Object](#channelItemObject)] | An object to hold reusable [Channel Item Objects](#channelItemObject).
messages | Map[`string`, [Message Object](#messageObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Message Objects](#messageObject).
securitySchemes| Map[`string`, [Security Scheme Object](#securitySchemeObject) \| [Reference Object](#referenceObject)] | An object to hold reusable [Security Scheme Objects](#securitySchemeObject).
@@ -1524,7 +1475,7 @@ All the fixed fields declared above are objects that MUST use keys that match th
Field Name Examples:
-```
+```plaintext
User
User_1
User_Name
@@ -1805,6 +1756,7 @@ Alternatively, any time a Schema Object can be used, a [Reference Object](#refer
In addition to the JSON Schema fields, the following AsyncAPI vocabulary fields MAY be used for further schema documentation:
##### Fixed Fields
+
Field Name | Type | Description
---|:---:|---
discriminator | `string` | Adds support for polymorphism. The discriminator is the schema property name that is used to differentiate between other schema that inherit this schema. The property name used MUST be defined at this schema and it MUST be in the `required` property list. When used, the value MUST be the name of this schema or any schema that inherits it. See [Composition and Inheritance](#schemaComposition) for more details.
@@ -1816,7 +1768,7 @@ This object MAY be extended with [Specification Extensions](#specificationExtens
###### Composition and Inheritance (Polymorphism)
The AsyncAPI Specification allows combining and extending model definitions using the `allOf` property of JSON Schema, in effect offering model composition.
-`allOf` takes in an array of object definitions that are validated *independently* but together compose a single object.
+`allOf` takes in an array of object definitions that are validated _independently_ but together compose a single object.
While composition offers model extensibility, it does not imply a hierarchy between the models.
To support polymorphism, AsyncAPI Specification adds the support of the `discriminator` field.
@@ -1827,7 +1779,7 @@ There are two ways to define the value of a discriminator for an inheriting inst
- Use the schema's name.
- Override the schema's name by overriding the property with a new value. If exists, this takes precedence over the schema's name.
-As such, inline schema definitions, which do not have a given id, *cannot* be used in polymorphism.
+As such, inline schema definitions, which do not have a given id, _cannot_ be used in polymorphism.
##### Schema Object Examples
@@ -2212,25 +2164,22 @@ schemas:
- color
```
-
-
-
-
#### Security Scheme Object
Defines a security scheme that can be used by the operations. Supported schemes are:
-* User/Password.
-* API key (either as user or as password).
-* X.509 certificate.
-* End-to-end encryption (either symmetric or asymmetric).
-* HTTP authentication.
-* HTTP API key.
-* OAuth2's common flows (Implicit, Resource Owner Protected Credentials, Client Credentials and Authorization Code) as defined in [RFC6749](https://tools.ietf.org/html/rfc6749).
-* [OpenID Connect Discovery](https://tools.ietf.org/html/draft-ietf-oauth-discovery-06).
-* SASL (Simple Authentication and Security Layer) as defined in [RFC4422](https://tools.ietf.org/html/rfc4422).
+- User/Password.
+- API key (either as user or as password).
+- X.509 certificate.
+- End-to-end encryption (either symmetric or asymmetric).
+- HTTP authentication.
+- HTTP API key.
+- OAuth2's common flows (Implicit, Resource Owner Protected Credentials, Client Credentials and Authorization Code) as defined in [RFC6749](https://tools.ietf.org/html/rfc6749).
+- [OpenID Connect Discovery](https://tools.ietf.org/html/draft-ietf-oauth-discovery-06).
+- SASL (Simple Authentication and Security Layer) as defined in [RFC4422](https://tools.ietf.org/html/rfc4422).
##### Fixed Fields
+
Field Name | Type | Applies To | Description
---|:---:|---|---
type | `string` | Any | **REQUIRED**. The type of the security scheme. Valid values are `"userPassword"`, `"apiKey"`, `"X509"`, `"symmetricEncryption"`, `"asymmetricEncryption"`, `"httpApiKey"`, `"http"`, `"oauth2"`, `"openIdConnect"`, `"plain"`, `"scramSha256"`, `"scramSha512"`, and `"gssapi"`.
@@ -2386,6 +2335,7 @@ type: scramSha512
Allows configuration of the supported OAuth Flows.
##### Fixed Fields
+
Field Name | Type | Description
---|:---:|---
implicit| [OAuth Flow Object](#oauthFlowObject) | Configuration for the OAuth Implicit flow.
@@ -2400,6 +2350,7 @@ This object MAY be extended with [Specification Extensions](#specificationExtens
Configuration details for a supported OAuth Flow
##### Fixed Fields
+
Field Name | Type | Applies To | Description
---|:---:|---|---
authorizationUrl | `string` | `oauth2` (`"implicit"`, `"authorizationCode"`) | **REQUIRED**. The authorization URL to be used for this flow. This MUST be in the form of an absolute URL.
@@ -2508,11 +2459,11 @@ petstore_auth:
### Correlation ID Object
-An object that specifies an identifier at design time that can used for message tracing and correlation.
+An object that specifies an identifier at design time that can used for message tracing and correlation.
For specifying and computing the location of a Correlation ID, a [runtime expression](#runtimeExpression) is used.
-##### Fixed Fields
+#### Fixed Fields
Field Name | Type | Description
---|:---|---
@@ -2521,7 +2472,7 @@ location | `string` | **REQUIRED.** A [runtime expression](#runtimeExpression) t
This object MAY be extended with [Specification Extensions](#specificationExtensions).
-##### Examples
+#### Examples
```json
{
@@ -2542,7 +2493,7 @@ This mechanism is used by [Correlation ID Object](#correlationIdObject).
The runtime expression is defined by the following [ABNF](https://tools.ietf.org/html/rfc5234) syntax:
-```
+```plaintext
expression = ( "$message" "." source )
source = ( header-reference | payload-reference )
header-reference = "header" ["#" fragment]
@@ -2552,7 +2503,7 @@ The runtime expression is defined by the following [ABNF](https://tools.ietf.org
The table below provides examples of runtime expressions and examples of their use in a value:
-##### Examples
+#### Examples
Source Location | Example expression | Notes
---|:---|:---|
@@ -2584,7 +2535,6 @@ Tools that do not recognize a specific `format` MAY default back to the `type` a
The formats defined by the AsyncAPI Specification are:
-
Common Name | `type` | [`format`](#dataTypeFormat) | Comments
----------- | ------ | -------- | --------
integer | `integer` | `int32` | signed 32 bits
From ca429e60126ff5635d9deca05061a9cd1122ef39 Mon Sep 17 00:00:00 2001
From: Darren Dsouza <130863032+DarrenDsouza7273@users.noreply.github.com>
Date: Tue, 29 Aug 2023 20:47:55 +0530
Subject: [PATCH 3/5] docs: add bronze sponsors (#964)
---
README.md | 13 +++++++++++++
assets/ably.png | Bin 0 -> 19105 bytes
assets/rviewer.png | Bin 0 -> 34837 bytes
3 files changed, 13 insertions(+)
create mode 100644 assets/ably.png
create mode 100644 assets/rviewer.png
diff --git a/README.md b/README.md
index c198d686..3fd00027 100644
--- a/README.md
+++ b/README.md
@@ -134,6 +134,19 @@ Check out the [examples](https://github.com/asyncapi/asyncapi/blob/master/exampl
+### Bronze
+
+
+
+
+
+
+
+
+
+
+
+
## Contributors
diff --git a/assets/ably.png b/assets/ably.png
new file mode 100644
index 0000000000000000000000000000000000000000..b451373d2414a8afcd553a370ed3224084c8241c
GIT binary patch
literal 19105
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
literal 0
HcmV?d00001
diff --git a/assets/rviewer.png b/assets/rviewer.png
new file mode 100644
index 0000000000000000000000000000000000000000..28c4979cd73b875e6e0c418fffabf0bd66ce0689
GIT binary patch
literal 34837
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