-
Notifications
You must be signed in to change notification settings - Fork 5.1k
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
EventGridv2 TypeSpec Api Preview #23204
Changes from 19 commits
68f887b
6554c10
eb98a20
c879030
6b989da
4a5f9cf
5511313
1a56614
c724eed
f91ee18
eb01ed4
69ccc41
0d2cb3a
c2d4c68
36d0e06
15dccec
13f6949
069bafb
5d21632
17fd291
663b348
fd1fd9d
02ea7de
17d65e2
3806bc1
799d10c
10e0e8c
09f9244
6c2b560
20958fd
16602df
911c47f
418e39a
e570388
0b24c89
a90210c
d1c21b5
4b1d4a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import "@azure-tools/typespec-client-generator-core"; | ||
import "./main.tsp"; | ||
|
||
using Azure.ClientGenerator.Core; | ||
|
||
@@internal(Azure.Messaging.EventGrid.CloudEventEvent); | ||
@@internal(Azure.Messaging.EventGrid.ReceiveDetails); | ||
@@internal(Azure.Messaging.EventGrid.PublishBatchOfCloudEvents); | ||
@@internal(Azure.Messaging.EventGrid.PublishCloudEvent); | ||
@@internal(Azure.Messaging.EventGrid.ReceiveBatchOfCloudEvents); |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,236 @@ | ||||||
import "@typespec/http"; | ||||||
import "@typespec/rest"; | ||||||
import "@typespec/versioning"; | ||||||
import "@azure-tools/typespec-autorest"; | ||||||
import "@azure-tools/typespec-azure-core"; | ||||||
|
||||||
enum ServiceApiVersions { | ||||||
v2023_06_01_preview: "2023-06-01-preview" | ||||||
} | ||||||
|
||||||
@useAuth( | ||||||
ApiKeyAuth<ApiKeyLocation.header, "SharedAccessKey"> | OAuth2Auth<[{ | ||||||
type: OAuth2FlowType.implicit, | ||||||
authorizationUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize", | ||||||
scopes: ["https://eventgrid.azure.net/.default"], | ||||||
}]> | ||||||
) | ||||||
|
||||||
@service({ | ||||||
title: "Azure.Messaging.EventGridMessagingClient", | ||||||
version: "2023-06-01-preview" | ||||||
}) | ||||||
|
||||||
// | ||||||
// Supported operations. | ||||||
// | ||||||
// POST https://{namespaceName}.{region}.eventgrid.azure.net/topics/{topicName}:publish?api-version={apiVersion}} | ||||||
// POST https://{namespaceName}.{region}.eventgrid.azure.net/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:receive?api-Version={apiVersion}&timeout=60&maxEvents={maxEvents} | ||||||
// POST https://{namespaceName}.{region}.eventgrid.azure.net/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:acknowledge?api-Version={apiVersion} | ||||||
// POST https://{namespaceName}.{region}.eventgrid.azure.net/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:release?api-version={apiVersion} | ||||||
// | ||||||
|
||||||
@server( | ||||||
"{endpoint}", | ||||||
"The host name of the topic", | ||||||
{ | ||||||
@doc("The host name of the namespace, e.g. namespaceName1.westus-1.eventgrid.azure.net") | ||||||
endpoint: url, | ||||||
} | ||||||
) | ||||||
|
||||||
@doc("Azure Messaging EventGrid Client") | ||||||
@versioned(ServiceApiVersions) | ||||||
namespace Azure.Messaging.EventGrid { | ||||||
using TypeSpec.Http; | ||||||
using TypeSpec.Rest; | ||||||
using TypeSpec.Versioning; | ||||||
using Azure.Core; | ||||||
using Azure.Core.Foundations; | ||||||
|
||||||
@doc("Properties of an event published to an Azure Messaging EventGrid Namespace topic using the CloudEvent 1.0 Schema.") | ||||||
model CloudEventEvent { | ||||||
@doc("An identifier for the event. The combination of id and source must be unique for each distinct event.") | ||||||
id: string; | ||||||
|
||||||
@doc("Identifies the context in which an event happened. The combination of id and source must be unique for each distinct event.") | ||||||
source: string; | ||||||
|
||||||
@doc("Event data specific to the event type.") | ||||||
data?: object; | ||||||
|
||||||
@doc("Event data specific to the event type, encoded as a base64 string.") | ||||||
data_base64?: bytes; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here, and directly below, we prefer camelCase for property names and enum values. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because this is following the outside spec of CloudEvent, it requires these parameters to be lowercase |
||||||
|
||||||
@doc("Type of event related to the originating occurrence.") | ||||||
type: string; | ||||||
|
||||||
@doc("The time (in UTC) the event was generated, in RFC3339 format.") | ||||||
time?: zonedDateTime; | ||||||
|
||||||
@doc("The version of the CloudEvents specification which the event uses.") | ||||||
specversion: string; | ||||||
|
||||||
@doc("Identifies the schema that data adheres to.") | ||||||
dataschema?: string; | ||||||
|
||||||
@doc("Content type of data value.") | ||||||
datacontenttype?: string; | ||||||
|
||||||
@doc("This describes the subject of the event in the context of the event producer (identified by source).") | ||||||
subject?: string; | ||||||
} | ||||||
|
||||||
@doc("LockToken information.") | ||||||
model LockToken { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can't have the model and property name be the same thing. Can this be called something like LockTokenProperties? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, possibly too late for the initial preview, but I really wonder whether it is worth having this model vs simply defining the lockToken as a string on each of the containing models. In my mind, the lock token is self sufficient and any supplementary information that might be added in the future may be context-dependent and can be added to the container model. Especially considering we don't even use this model for both input and output (only output). |
||||||
@doc("The token used to lock the event.") | ||||||
lockToken: string; | ||||||
} | ||||||
|
||||||
@doc("Properties of the Event Broker operation.") | ||||||
model BrokerProperties { | ||||||
@doc("The token used to lock the event.") | ||||||
lockToken: LockToken; | ||||||
} | ||||||
|
||||||
@doc("Receive operation details per Cloud Event.") | ||||||
model ReceiveDetails { | ||||||
@doc("The Event Broker details.") | ||||||
brokerProperties: BrokerProperties; | ||||||
|
||||||
@doc("Cloud Event details.") | ||||||
event: CloudEventEvent; | ||||||
} | ||||||
|
||||||
@doc("Details of the Receive operation response.") | ||||||
model ReceiveResponse { | ||||||
@doc("Array of receive responses, one per cloud event.") | ||||||
value: ReceiveDetails[]; | ||||||
} | ||||||
|
||||||
@doc("Failed LockToken information.") | ||||||
model FailedLockToken { | ||||||
@doc("LockToken value") | ||||||
lockToken: LockToken; | ||||||
|
||||||
@doc("Error code") | ||||||
errorCode: int32; | ||||||
|
||||||
@doc("Description of the error") | ||||||
errorDescription: string; | ||||||
} | ||||||
|
||||||
@doc("Details of the LockTokens information. This is used for both Acknowledge and Release operation response.") | ||||||
model LockTokensResponse { | ||||||
JoshLove-msft marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
@doc("Array of LockToken values for failed cloud events.") | ||||||
failedLockTokens: FailedLockToken[]; | ||||||
|
||||||
@doc("Array of LockToken values for succeeded cloud events.") | ||||||
succeededLockTokens: string[]; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FailedLockToken contains additional information - the errorCode and errorDescription. So the docs need updating to clarify that it is an array of FailedLockToken values. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updating the docs is certainly welcome, but I think some users will still find the naming confusing. A "LockToken" is a string. A "succeededLockToken" is a LockToken (string) that succeeded. A "failedLockToken" is not a LockToken that failed -- it is a completely different type. Rather than "failedLockToken", I think a better name would be "LockTokenFailure" -- since it describes the failure for a lock token. Is it too late to make a name change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not really a LockTokenFailure - it's a failure in one of the settlement operations (acknowledge or release), and the lock tokens that can be used to correlate the failures with the events that were received via the receive operations are included in the payload. Maybe something like "failureInformation"? |
||||||
} | ||||||
|
||||||
@doc("Lock token input formatting.") | ||||||
model LockTokenInput { | ||||||
@doc("LockTokens") | ||||||
lockTokens: string[]; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this string array rather than LockToken array? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess the LockToken type is meant for output that might evolve over time. |
||||||
} | ||||||
|
||||||
// POST https://{namespaceName}.{region}.eventgrid.azure.net/topics/{topicName}:publish?api-version={apiVersion}} | ||||||
|
||||||
@doc("Publish Single Cloud Event to namespace topic.") | ||||||
@route("/topics/{topicName}:publish", {shared: true}) | ||||||
@post op PublishCloudEvent is Azure.Core.RpcOperation<{ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not a collection action of a |
||||||
@doc("content type") | ||||||
@header("content-type") | ||||||
contentType: "application/cloudevents+json; charset=utf-8"; | ||||||
|
||||||
@doc("Topic Name.") | ||||||
@path | ||||||
topicName: string; | ||||||
|
||||||
@doc("Single Cloud Event being published.") | ||||||
@body | ||||||
event: CloudEventEvent; | ||||||
}, OkResponse>; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From testing the server, we indeed receive a 200. We would have expected a 204, not a 200, given this returns no body. |
||||||
|
||||||
|
||||||
@doc("Publish Batch of Cloud Events to namespace topic.") | ||||||
@route("/topics/{topicName}:publish", {shared: true}) | ||||||
@post op PublishBatchOfCloudEvents is Azure.Core.RpcOperation<{ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
@doc("content type") | ||||||
@header("content-type") | ||||||
contentType: "application/cloudevents-batch+json; charset=utf-8"; | ||||||
|
||||||
@doc("Topic Name.") | ||||||
@path | ||||||
topicName: string; | ||||||
|
||||||
@doc("Array of Cloud Events being published.") | ||||||
@body | ||||||
events: CloudEventEvent[]; | ||||||
}, OkResponse>; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as before: |
||||||
|
||||||
@doc("Receive Batch of Cloud Events from the Event Subscription.") | ||||||
@route("/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:receive") | ||||||
@post op ReceiveBatchOfCloudEvents is Azure.Core.RpcOperation<{ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not a collection action over an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
@doc("Topic Name.") | ||||||
@path | ||||||
topicName: string; | ||||||
|
||||||
@doc("Event Subscription Name.") | ||||||
@path | ||||||
eventSubscriptionName: string; | ||||||
|
||||||
@doc("Max Events count to be received.") | ||||||
@query | ||||||
maxEvents?: int32 = 1; | ||||||
|
||||||
@doc("Timeout value for receive operation in Seconds. Default is 60 seconds.") | ||||||
@query | ||||||
timeout?: int32 =60; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we wanted to name this as maxWaitTime - is there a way to do that given this is query param sent to the service? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there some format we can apply so this generates as a TimeSpan,Duration,etc? In swagger, we would use format: date-time. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think projected name can be used here for renaming There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool, is there an equivalent for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Type it as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||
}, ReceiveResponse & CreatedResponse >; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What we see calling the service, is that nothing to receive returns an empty list with a 200, and if there are events this is a 201 |
||||||
|
||||||
// POST https://{namespaceName}.{region}.eventgrid.azure.net/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:acknowledge&apiVersion={apiVersion} | ||||||
|
||||||
@doc("Acknowledge Cloud Events.") | ||||||
@route("/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:acknowledge") | ||||||
@post op AcknowledgeBatchOfCloudEvents is Azure.Core.RpcOperation<{ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
@doc("content type") | ||||||
@header("content-type") | ||||||
contentType: "application/json; charset=utf-8"; | ||||||
|
||||||
@doc("Topic Name.") | ||||||
@path | ||||||
topicName: string; | ||||||
|
||||||
@doc("Event Subscription Name.") | ||||||
@path | ||||||
eventSubscriptionName: string; | ||||||
|
||||||
@doc("Array of LockTokens for the corresponding received Cloud Events to be acknowledged.") | ||||||
@body | ||||||
lockTokens: LockTokenInput; | ||||||
}, LockTokensResponse >; | ||||||
|
||||||
// POST https://{namespaceName}.{region}.eventgrid.azure.net/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:release?api-version={apiVersion} | ||||||
|
||||||
@doc("Release Cloud Events.") | ||||||
@route("/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:release") | ||||||
@post op ReleaseBatchOfCloudEvents is Azure.Core.RpcOperation<{ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
@doc("content type") | ||||||
@header("content-type") | ||||||
contentType: "application/json; charset=utf-8"; | ||||||
|
||||||
@doc("Topic Name.") | ||||||
@path | ||||||
topicName: string; | ||||||
|
||||||
@doc("Event Subscription Name.") | ||||||
@path | ||||||
eventSubscriptionName: string; | ||||||
|
||||||
@doc("Array of LockTokens for the corresponding received Cloud Events to be acknowledged.") | ||||||
@body | ||||||
tokens : LockToken[]; | ||||||
}, LockTokensResponse >; | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be changed to
unknown
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/Azure/azure-rest-api-specs/pull/23539/files