Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add IBM MQ binding #52

Merged
merged 1 commit into from
Feb 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This repository contains the specifications for each AsyncAPI protocol binding.
* [AMQP binding](./amqp)
* [AMQP 1.0 binding](./amqp1)
* [HTTP binding](./http)
* [IBM MQ binding](./ibmmq)
* [JMS binding](./jms)
* [Kafka binding](./kafka)
* [MQTT binding](./mqtt)
Expand Down
312 changes: 312 additions & 0 deletions ibmmq/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,312 @@
# IBM MQ Bindings

This document defines how to describe IBM MQ specific information with AsyncAPI.

<a name="version"></a>

## Version

Current version is `0.1.0`.

## Terminology

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this bindings specification are to be interpreted as described in IETF [RFC2119](https://www.ietf.org/rfc/rfc2119.txt).

## AsyncAPI considerations

This specification binding requests that the AsyncAPI specification reserve the IBM MQ protocol to allow connections to queue manager endpoints to be defined within the server object.

AsyncAPI Object Fixed Field Name | Reserved Value for IBM MQ Protocol | Description
---|:---|:---
<a name="serverObjectProtocolFieldValueIbmmq"></a>`server.protocol` | ibmmq | IBM MQ protocol.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fmvilas shouldn't we consider this new protocol and binding as something reserved, like names we already have in the spec https://github.com/asyncapi/asyncapi/blob/master/versions/2.0.0/asyncapi.md#server-object and therefor this part should also be extended in the spec? I don't think it is must-have, but nice to have anyway?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely. In AsyncAPI 1, protocols were reserved because the list was fixed. This changed in v2 and we made a free-form list, i.e., anyone can put there whatever they want. As long as tooling understands it, that's fine. It would be great to have a middle way between v1 and v2 and add some names to a reserved list of names 👍 Should we create a new issue maybe?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fmvilas sure, no problem. Is there a convention to the ordering of the protocol list?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it used to be sorted alphabetically but mercure got there at the end by mistake. If you can fix it at the same time that would be awesome.

<a name="serverObjectProtocolFieldValueIbmmqSecure"></a>`server.protocol` | ibmmq-secure | IBM MQ protocol over TLS.

## URI scheme considerations

For the purposes of establishing an IBM MQ binding for use within AsyncAPI, this document defines the URI scheme `ibmmq://` consisting of components and generic URI syntax as specified in [RFC3986](https://tools.ietf.org/html/rfc3986)

### Defining an IBM MQ queue manager endpoint in the server object `url` field

When defining an IBM MQ `url` for a queue manager endpoint, the `ibmmq://` URI scheme MUST be used. IBM MQ URIs are defined using the following components.

URI Component | IBM MQ reference | Applicability | Description |
---|:---|:--|:--
<a name="uriObjectScheme"></a>`scheme` | `ibmmq://` | REQUIRED | The URI scheme used to represent an IBM MQ endpoint.
<a name="uriObjectAuthority>"></a>`authority` | `<hostname or ipAddress>:port` | REQUIRED | The network IP address or hostname and port of the queue manager endpoint. |
<a name="uriObjectQueueManager>"></a>`path` | `queueManager` | OPTIONAL | The queue manager name. If no queue manager name is specified this segment is left undefined, for example `ibmmq://hostname:{port}//CHANNEL.NAME`
<a name="uriObjectChannelName>"></a>`path` | `mqChannelName` | REQUIRED | The `SVRCONN` channel to use for communication with an IBM MQ queue manager. When connecting to a queue manager, IBM MQ partitions this communication into logical channels.

URI `query` or `fragment` components MUST NOT be used within the `ibmmq://` scheme. Path components that contain characters reserved by RFC2936 such as `/` MUST be percent encoded as defined in [Section 2.2 of RFC2936](https://tools.ietf.org/html/rfc3986#section-2.2). `port` MUST be specified as part of the authority component in the `ibmmq://` scheme.


### Defining IBM MQ queue manager endpoints with the AsyncAPI Server Object

This section defines the convention for how IBM MQ queue manager endpoints are encoded within the AsyncAPI Server Object fields. A `groupId` field has been made available on the IBM MQ AsyncAPI server binding object to allow server objects to be defined as a related collection. This is necessary to group, or cluster, IBM MQ queue manager endpoints within the AsyncAPI specification and where a Client Channel Definition Table ([CCDT](https://www.ibm.com/support/knowledgecenter/SSFKSJ_latest/com.ibm.mq.con.doc/q132905_.html)) reference is not appropriate.


##### Example of two possible MQ servers defined using ibmmq url syntax
```yaml
servers:
production1:
url: ibmmq://qmgr1host:1414/qm1/DEV.APP.SVRCONN
protocol: ibmmq
production2:
url: ibmmq://qmgr2host:1414/qm2/DEV.APP.SVRCONN
protocol: ibmmq
```

##### Example of single MQ server defined using ibmmq url syntax and with no queue manager name specified
```yaml
servers:
production:
url: ibmmq://qmgr1host:1414//DEV.APP.SVRCONN
protocol: ibmmq
```

## Defining an IBM MQ queue manager endpoint CCDT in the `url` field
When defining a connection to IBM MQ, a CCDT connection file can be specified. The server url will specify the location of the file with additional information contained within the server binding to specify its usage.

##### Example using an IBM MQ CCDT file url

```yaml
servers:
production1:
url: 'http://my-ccdt-json-file'
protocol: ibmmq
production2:
url: 'file://myccdt.json'
protocol: ibmmq
```

<a name="server"></a>

## Server Binding Object

This object contains server connection information about the IBM MQ server, referred to as an IBM MQ queue manager. This object contains additional connectivity information not possible to represent within the core AsyncAPI specification.

##### Fixed Fields


Field Name | Type | Description | Applicability \[default\] | Constraints
---|:---:|---|:---|:---
<a name="serverObjectGroupId>"></a>`groupId` | string | Defines a logical group of IBM MQ server objects. This is necessary to specify multi-endpoint configurations used in high availability deployments. If omitted, the server object is not part of a group. | OPTIONAL | MUST NOT be specified for URI Scheme `http://` or `file://`
<a name="serverObjectCCDTQueueManager"></a>`ccdtQueueManagerName` | string | The name of the IBM MQ queue manager to bind to in the CCDT file. | OPTIONAL [`*`] | MUST NOT be specified for URI Scheme `ibmmq://`
<a name="serverObjectCipherSpec"></a>`cipherSpec` | string | The recommended cipher specification used to establish a TLS connection between the client and the IBM MQ queue manager. More information on SSL/TLS cipher specifications supported by IBM MQ can be found on this [page](https://www.ibm.com/support/knowledgecenter/SSFKSJ_latest/com.ibm.mq.dev.doc/q113220_.html) in the IBM MQ Knowledge Center. | OPTIONAL [`ANY`] | MUST NOT be specified for protocol `ibmmq` or URI Scheme `file://` or `http://`
<a name="serverObjectMultiEndpointServer:"></a>`multiEndpointServer` | boolean | If `multiEndpointServer` is `true` then multiple connections can be workload balanced and applications should not make assumptions as to where messages are processed. Where message ordering, or affinity to specific message resources is necessary, a single endpoint (`multiEndpointServer` = `false`) may be required. | OPTIONAL [`false`] | MUST NOT be specified for URI Scheme `file://` or `http://`
<a name="serverObjectEndpointHeartBeatInterval"></a>`heartBeatInterval` | integer | The recommended value (in seconds) for the heartbeat sent to the queue manager during periods of inactivity. A value of zero means that no heart beats are sent. A value of `1` means that the client will use the value defined by the queue manager. More information on heart beat interval can be found on this [page](https://www.ibm.com/support/knowledgecenter/SSFKSJ_latest/com.ibm.mq.ref.dev.doc/q108450_.html) in the IBM MQ Knowledge Center. | OPTIONAL [`300`] | MUST be `0-999999`
<a name="serverBindingObjectBindingVersion"></a>`bindingVersion` | string | The version of this binding. | OPTIONAL [`latest`] | -

This object MUST contain only the properties defined above.

##### Example for multiple endpoints defined in the AsyncAPI configuration

```yaml
servers:
production1:
url: ibmmq://qmgr1host:1414/qm1/DEV.APP.SVRCONN
protocol: ibmmq-secure
description: Production Instance 1
bindings:
ibmmq:
groupId: PRODCLSTR1
cipherSpec: ANY_TLS12_OR_HIGHER
bindingVersion: 0.1.0
production2:
url: ibmmq://qmgr2host:1414/qm2/DEV.APP.SVRCONN
protocol: ibmmq-secure
description: Production Instance 2
bindings:
ibmmq:
groupId: PRODCLSTR1
bindingVersion: 0.1.0
```

##### Example using combined strategy

```yaml
servers:
production:
url: 'http://my-ccdt-json-file'
protocol: ibmmq-secure
description: Production MQ Instance
bindings:
ibmmq:
ccdtQueueManagerName: qm1
test:
url: ibmmq://qmgrtest:1414/qm2/DEV.APP.SVRCONN
protocol: ibmmq-secure
description: Test MQ Instance
bindings:
ibmmq:
cipherSpec: ANY_TLS12_OR_HIGHER
bindingVersion: 0.1.0
```

<a name="channel"></a>

## Channel Binding Object

This object contains information about the channel representation in IBM MQ. Each channel corresponds to a Queue or Topic within IBM MQ.

##### Fixed Fields

Field Name | Type | Description | Applicability [default] | Constraints
---|:---:|---|:---|:---
<a name="channelBindingObjectDestinationType"></a>`destinationType` | string | Defines the type of AsyncAPI channel. | OPTIONAL [`topic`] | MUST be either `topic` or `queue`. For type `topic`, the AsyncAPI channel name MUST be assumed for the IBM MQ topic string unless overridden.
<a name="channelBindingObjectQueue"></a>`queue` | Map[string, any] | Defines the properties of a queue. | REQUIRED if `destinationType` = `queue` | `queue` and `topic` fields MUST NOT coexist within a channel binding
<a name="channelBindingObjectQueueObjectName"></a>`queue.`<br>`objectName`</br> | string | Defines the name of the IBM MQ queue associated with the channel. | REQUIRED | A value MUST be specified. MUST NOT exceed 48 characters in length. MUST be a valid IBM MQ queue name
<a name="channelBindingObjectisPartitioned"></a>`queue.`<br>`isPartitioned`</br> | boolean | Defines if the queue is a cluster queue and therefore partitioned. If `true`, a binding option MAY be specified when accessing the queue. More information on binding options can be found on this [page](https://www.ibm.com/support/knowledgecenter/SSFKSJ_latest/com.ibm.mq.ref.dev.doc/q101870_.html#q101870___BIND_ON_OPEN) in the IBM MQ Knowledge Center. | OPTIONAL [`false`] | If `false`, binding options SHOULD NOT be specified when accessing the queue.
<a name="channelBindingObjectQueueExclusive"></a>`queue.`<br>`exclusive`</br> | boolean | Specifies if it is recommended to open the queue exclusively. | OPTIONAL [`false`] | -
<a name="channelBindingObjectTopic"></a>`topic` | Map[string, any] | Defines the properties of a topic. | OPTIONAL if `destinationType` = `topic` | `queue` and `topic` fields MUST NOT coexist within a channel binding.
<a name="channelBindingObjectTopicString"></a>`topic.`<br>`string`</br> | string | The value of the IBM MQ topic string to be used. | OPTIONAL *<br>Note: if specified, SHALL override AsyncAPI channel name.</br>* | MUST NOT exceed 10240 characters in length. MAY coexist with `topic.objectName`
<a name="channelBindingObjectTopicObjectName"></a>`topic.`<br>`objectName`</br> | string | The name of the IBM MQ topic object. | OPTIONAL *<br>Note: if specified, SHALL override AsyncAPI channel name.</br>*| MUST NOT exceed 48 characters in length. MAY coexist with `topic.string`
<a name="channelBindingObjectTopicDurablePermitted"></a>`topic.`<br> `durablePermitted`</br> | boolean | Defines if the subscription may be durable. | OPTIONAL [`true`] | -
<a name="channelBindingObjectTopicLastMsgRetained"></a>`topic.`<br>`lastMsgRetained`</br> | boolean | Defines if the last message published will be made available to new subscriptions. | OPTIONAL [`false`] | -
<a name="channelBindingObjectMaxMsgLength"></a>`maxMsgLength` | integer | The maximum length of the physical message (in bytes) accepted by the Topic or Queue. Messages produced that are greater in size than this value may fail to be delivered. More information on the maximum message length can be found on this [page](https://www.ibm.com/support/knowledgecenter/SSFKSJ_latest/com.ibm.mq.ref.adm.doc/q085520_.html#q085520___maxmsgl) in the IBM MQ Knowledge Center. | OPTIONAL [negotiated on IBM MQ channel]| MUST be `0-104,857,600` bytes (100 MB).
<a name="channelBindingObjectBindingVersion"></a>`bindingVersion` | string | The version of this binding. | OPTIONAL [`latest`] | -


This object MUST contain only the properties defined above.

##### Example for an IBM MQ Topic where topic string is defined by AsyncAPI channel

```yaml
channels:
user/signedup:
```

##### Example for AsyncAPI channel mapping to an IBM MQ topic with a specified MQ Topic object

```yaml
channels:
user/signedup:
bindings:
ibmmq:
destinationType: topic
topic:
objectName: myTopicName
bindingVersion: 0.1.0
```

##### Example for AsyncAPI channel mapping to an IBM MQ Queue

```yaml
channels:
user/signedup:
bindings:
ibmmq:
destinationType: queue
queue:
objectName: myQueueName
exclusive: true
bindingVersion: 0.1.0
```

<a name="operation"></a>


## Message Binding Object

This object contains information about the message representation in IBM MQ.

##### Fixed Fields

Field Name | Type | Description | Applicability [default] | Constraints
---|:---:|---|:---|:---
<a name="messageBindingObjectType"></a>`type` | string | The type of the message. | OPTIONAL [`string`] | MUST be either `string`, `jms` or `binary`
<a name="messageBindingObjectHeaders"></a>`headers` | string | Defines the IBM MQ message headers to include with this message. More than one header can be specified as a comma separated list. Supporting information on IBM MQ message formats can be found on this [page](https://www.ibm.com/support/knowledgecenter/SSFKSJ_latest/com.ibm.mq.ref.dev.doc/q097520_.html) in the IBM MQ Knowledge Center. | OPTIONAL if `type` = `binary` | `headers` MUST NOT be specified if `type` = `string` or `jms`
<a name="messageBindingObjectDescription"></a>`description` | string<sup>1</sub> | Provides additional information for application developers: describes the message type or format. | OPTIONAL | -
<a name="messageBindingObjectExpiry"></a>`expiry` | integer | The recommended setting the client should use for the TTL (Time-To-Live) of the message. This is a period of time expressed in milliseconds and set by the application that puts the message. `expiry` values are API dependant e.g., MQI and JMS use different units of time and default values for *`unlimited`*. General information on IBM MQ message expiry can be found on this [page](https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_latest/com.ibm.mq.ref.dev.doc/q097490_.html) in the IBM MQ Knowledge Center. | OPTIONAL [*`unlimited`*] | `expiry` value MUST be either `zero` (*`unlimited`*) or greater than zero.
<a name="messageBindingObjectBindingVersion"></a>`bindingVersion` | string | The version of this binding. | OPTIONAL [`latest`] | -

This object MUST contain only the properties defined above.

### Rich Text Formatting

<sup>1</sup> The `description` field of the IBM MQ message binding object MAY include CommonMark markdown formatting. A minimum markdown syntax as described by [CommonMark 0.27](https://spec.commonmark.org/0.27/) is assumed.

##### Example for plain text message

```yaml
channels:
user/signup:
publish:
message:
bindings:
ibmmq:
type: text
bindingVersion: 0.1.0
```

##### Example for IBM MQ message using JMS

```yaml
channels:
user/signup:
publish:
message:
bindings:
ibmmq:
type: jms
description: JMS stream message
bindingVersion: 0.1.0
```

# AsyncAPI example with IBM MQ binding

##### Example for AsyncAPI user signup

```yaml
asyncapi: 2.0.0
info:
title: Account Service
version: 1.0.0
description: This service is in charge of processing user signups
servers:
production1:
url: ibmmq://qmgr1host:1414/qm1/DEV.APP.SVRCONN
protocol: ibmmq-secure
description: Production Instance 1
bindings:
ibmmq:
groupId: PRODCLSTR1
cipherSpec: ANY_TLS12_OR_HIGHER
bindingVersion: 0.1.0
production2:
url: ibmmq://qmgr2host:1414/qm2/DEV.APP.SVRCONN
protocol: ibmmq-secure
description: Production Instance 2
bindings:
ibmmq:
groupId: PRODCLSTR1
cipherSpec: ANY_TLS12_OR_HIGHER
bindingVersion: 0.1.0
channels:
user/signedup:
bindings:
ibmmq:
topic:
durablePermitted: true
bindingVersion: 0.1.0
subscribe:
message:
$ref: '#/components/messages/UserSignedUp'
bindings:
ibmmq:
type: jms
description: JMS bytes message
bindingVersion: 0.1.0
components:
messages:
UserSignedUp:
payload:
type: object
properties:
displayName:
type: string
description: Name of the user
email:
type: string
format: email
description: Email of the user
```