From 4666e36389cd87c80703bc6dac050c6f1563e4c9 Mon Sep 17 00:00:00 2001 From: ripark Date: Thu, 21 Mar 2024 01:21:24 +0000 Subject: [PATCH 01/12] Regenerated based on a02f2ba78bfb988c3bd195886c0492024f0ea7fc, which adds in ACSRouterWorkerUpdatedEventData. Also fixed more naming where we were still using 'Acs' instead of 'ACS', which is our convention. --- .../eventgrid/azsystemevents/CHANGELOG.md | 10 + .../eventgrid/azsystemevents/autorest.md | 23 ++- .../eventgrid/azsystemevents/constants.go | 182 +++++++++++------- .../eventgrid/azsystemevents/models.go | 114 +++++++---- .../eventgrid/azsystemevents/models_serde.go | 142 +++++++++++--- .../eventgrid/azsystemevents/system_events.go | 1 + 6 files changed, 339 insertions(+), 133 deletions(-) diff --git a/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md b/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md index fbb0c1b3d817..e52289768d92 100644 --- a/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md +++ b/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md @@ -1,5 +1,15 @@ # Release History +## 0.2.1 (TBD) + +### Features Added + +- Added ACSRouterWorkerUpdatedEventData. + +### Breaking Changes + +- ACS events and constants have been changed to use an all-caps name (ex: AcsEmailDeliveryReportStatusDetails -> ACSEmailDeliveryReportStatusDetails). + ## 0.2.0 (2024-03-14) ### Features Added diff --git a/sdk/messaging/eventgrid/azsystemevents/autorest.md b/sdk/messaging/eventgrid/azsystemevents/autorest.md index aabc8ca434fa..14579178b538 100644 --- a/sdk/messaging/eventgrid/azsystemevents/autorest.md +++ b/sdk/messaging/eventgrid/azsystemevents/autorest.md @@ -6,7 +6,7 @@ description: Azure Event Grid system events generated-metadata: false clear-output-folder: false go: true -require: https://github.com/Azure/azure-rest-api-specs/blob/64819c695760764afa059d799fc7320d3fee33de/specification/eventgrid/data-plane/readme.md +require: https://github.com/Azure/azure-rest-api-specs/blob/a02f2ba78bfb988c3bd195886c0492024f0ea7fc/specification/eventgrid/data-plane/readme.md license-header: MICROSOFT_MIT_NO_VERSION openapi-type: "data-plane" output-folder: ../azsystemevents @@ -153,7 +153,6 @@ directive: - models.go - models_serde.go where: $ - debug: true transform: | const acronyms = ["Acs", "Avs", "Iot"]; for (let acr of acronyms) { @@ -162,8 +161,26 @@ directive: // 'type AcsChatMessageDeletedEventData struct' // 'Participants []AcsChatThreadParticipantProperties' // 'ParticipantRemoved *AcsChatThreadParticipantProperties' - const re = new RegExp(`([ *\\]])${acr}([A-Za-z0-9]+?(?:EventData|Properties))`, "sg"); + const re = new RegExp(`([ *\\]])${acr}([A-Za-z0-9]+?(?:EventData|Properties|Property|Details|Context|Configuration|Error|Selector))`, "sg"); + $ = $.replace(re, `$1${acr.toUpperCase()}$2`); + + // fix any fields that reference these models + const re2 = new RegExp(`([*])${acr}([A-Za-z0-9]+?)`, "sg"); + $ = $.replace(re2, `$1${acr.toUpperCase()}$2`); + } + + return $; + - from: + - constants.go + where: $ + debug: True + transform: | + const acronyms = ["Acs", "Avs", "Iot"]; + for (let acr of acronyms) { + // ex: + const re = new RegExp(`([ \\]]|Possible)${acr}([A-Za-z0-9]+?[ ,{(])`, "sg"); $ = $.replace(re, `$1${acr.toUpperCase()}$2`); } + return $; ``` diff --git a/sdk/messaging/eventgrid/azsystemevents/constants.go b/sdk/messaging/eventgrid/azsystemevents/constants.go index d0737a10e7e7..99a692702fd8 100644 --- a/sdk/messaging/eventgrid/azsystemevents/constants.go +++ b/sdk/messaging/eventgrid/azsystemevents/constants.go @@ -8,28 +8,28 @@ package azsystemevents -// AcsEmailDeliveryReportStatus - The status of the email. Any value other than Delivered is considered failed. -type AcsEmailDeliveryReportStatus string +// ACSEmailDeliveryReportStatus - The status of the email. Any value other than Delivered is considered failed. +type ACSEmailDeliveryReportStatus string const ( - // AcsEmailDeliveryReportStatusBounced - Hard bounce detected while sending the email - AcsEmailDeliveryReportStatusBounced AcsEmailDeliveryReportStatus = "Bounced" - // AcsEmailDeliveryReportStatusDelivered - The email was delivered - AcsEmailDeliveryReportStatusDelivered AcsEmailDeliveryReportStatus = "Delivered" - // AcsEmailDeliveryReportStatusFailed - The email failed to be delivered - AcsEmailDeliveryReportStatusFailed AcsEmailDeliveryReportStatus = "Failed" - // AcsEmailDeliveryReportStatusFilteredSpam - The message was identified spam and was rejected or blocked (not quarantined). - AcsEmailDeliveryReportStatusFilteredSpam AcsEmailDeliveryReportStatus = "FilteredSpam" - // AcsEmailDeliveryReportStatusQuarantined - The message was quarantined (as spam, bulk mail, or phishing). For more information, + // ACSEmailDeliveryReportStatusBounced - Hard bounce detected while sending the email + AcsEmailDeliveryReportStatusBounced ACSEmailDeliveryReportStatus = "Bounced" + // ACSEmailDeliveryReportStatusDelivered - The email was delivered + AcsEmailDeliveryReportStatusDelivered ACSEmailDeliveryReportStatus = "Delivered" + // ACSEmailDeliveryReportStatusFailed - The email failed to be delivered + AcsEmailDeliveryReportStatusFailed ACSEmailDeliveryReportStatus = "Failed" + // ACSEmailDeliveryReportStatusFilteredSpam - The message was identified spam and was rejected or blocked (not quarantined). + AcsEmailDeliveryReportStatusFilteredSpam ACSEmailDeliveryReportStatus = "FilteredSpam" + // ACSEmailDeliveryReportStatusQuarantined - The message was quarantined (as spam, bulk mail, or phishing). For more information, // see Quarantined email messages in EOP (EXCHANGE ONLINE PROTECTION). - AcsEmailDeliveryReportStatusQuarantined AcsEmailDeliveryReportStatus = "Quarantined" - // AcsEmailDeliveryReportStatusSuppressed - The email was suppressed - AcsEmailDeliveryReportStatusSuppressed AcsEmailDeliveryReportStatus = "Suppressed" + AcsEmailDeliveryReportStatusQuarantined ACSEmailDeliveryReportStatus = "Quarantined" + // ACSEmailDeliveryReportStatusSuppressed - The email was suppressed + AcsEmailDeliveryReportStatusSuppressed ACSEmailDeliveryReportStatus = "Suppressed" ) -// PossibleAcsEmailDeliveryReportStatusValues returns the possible values for the AcsEmailDeliveryReportStatus const type. -func PossibleAcsEmailDeliveryReportStatusValues() []AcsEmailDeliveryReportStatus { - return []AcsEmailDeliveryReportStatus{ +// PossibleACSEmailDeliveryReportStatusValues returns the possible values for the ACSEmailDeliveryReportStatus const type. +func PossibleACSEmailDeliveryReportStatusValues() []ACSEmailDeliveryReportStatus { + return []ACSEmailDeliveryReportStatus{ AcsEmailDeliveryReportStatusBounced, AcsEmailDeliveryReportStatusDelivered, AcsEmailDeliveryReportStatusFailed, @@ -39,27 +39,27 @@ func PossibleAcsEmailDeliveryReportStatusValues() []AcsEmailDeliveryReportStatus } } -// AcsRouterJobStatus - Router Job Received Job Status -type AcsRouterJobStatus string +// ACSRouterJobStatus - Router Job Received Job Status +type ACSRouterJobStatus string const ( - AcsRouterJobStatusAssigned AcsRouterJobStatus = "Assigned" - AcsRouterJobStatusCancelled AcsRouterJobStatus = "Cancelled" - AcsRouterJobStatusClassificationFailed AcsRouterJobStatus = "ClassificationFailed" - AcsRouterJobStatusClosed AcsRouterJobStatus = "Closed" - AcsRouterJobStatusCompleted AcsRouterJobStatus = "Completed" - AcsRouterJobStatusCreated AcsRouterJobStatus = "Created" - AcsRouterJobStatusPendingClassification AcsRouterJobStatus = "PendingClassification" - AcsRouterJobStatusPendingSchedule AcsRouterJobStatus = "PendingSchedule" - AcsRouterJobStatusQueued AcsRouterJobStatus = "Queued" - AcsRouterJobStatusScheduleFailed AcsRouterJobStatus = "ScheduleFailed" - AcsRouterJobStatusScheduled AcsRouterJobStatus = "Scheduled" - AcsRouterJobStatusWaitingForActivation AcsRouterJobStatus = "WaitingForActivation" + AcsRouterJobStatusAssigned ACSRouterJobStatus = "Assigned" + AcsRouterJobStatusCancelled ACSRouterJobStatus = "Cancelled" + AcsRouterJobStatusClassificationFailed ACSRouterJobStatus = "ClassificationFailed" + AcsRouterJobStatusClosed ACSRouterJobStatus = "Closed" + AcsRouterJobStatusCompleted ACSRouterJobStatus = "Completed" + AcsRouterJobStatusCreated ACSRouterJobStatus = "Created" + AcsRouterJobStatusPendingClassification ACSRouterJobStatus = "PendingClassification" + AcsRouterJobStatusPendingSchedule ACSRouterJobStatus = "PendingSchedule" + AcsRouterJobStatusQueued ACSRouterJobStatus = "Queued" + AcsRouterJobStatusScheduleFailed ACSRouterJobStatus = "ScheduleFailed" + AcsRouterJobStatusScheduled ACSRouterJobStatus = "Scheduled" + AcsRouterJobStatusWaitingForActivation ACSRouterJobStatus = "WaitingForActivation" ) -// PossibleAcsRouterJobStatusValues returns the possible values for the AcsRouterJobStatus const type. -func PossibleAcsRouterJobStatusValues() []AcsRouterJobStatus { - return []AcsRouterJobStatus{ +// PossibleACSRouterJobStatusValues returns the possible values for the ACSRouterJobStatus const type. +func PossibleACSRouterJobStatusValues() []ACSRouterJobStatus { + return []ACSRouterJobStatus{ AcsRouterJobStatusAssigned, AcsRouterJobStatusCancelled, AcsRouterJobStatusClassificationFailed, @@ -75,27 +75,27 @@ func PossibleAcsRouterJobStatusValues() []AcsRouterJobStatus { } } -// AcsRouterLabelOperator - Router Job Worker Selector Label Operator -type AcsRouterLabelOperator string +// ACSRouterLabelOperator - Router Job Worker Selector Label Operator +type ACSRouterLabelOperator string const ( - // AcsRouterLabelOperatorEqual - = - AcsRouterLabelOperatorEqual AcsRouterLabelOperator = "Equal" - // AcsRouterLabelOperatorGreater - > - AcsRouterLabelOperatorGreater AcsRouterLabelOperator = "Greater" - // AcsRouterLabelOperatorGreaterThanOrEqual - >= - AcsRouterLabelOperatorGreaterThanOrEqual AcsRouterLabelOperator = "GreaterThanOrEqual" - // AcsRouterLabelOperatorLess - < - AcsRouterLabelOperatorLess AcsRouterLabelOperator = "Less" - // AcsRouterLabelOperatorLessThanOrEqual - <= - AcsRouterLabelOperatorLessThanOrEqual AcsRouterLabelOperator = "LessThanOrEqual" - // AcsRouterLabelOperatorNotEqual - != - AcsRouterLabelOperatorNotEqual AcsRouterLabelOperator = "NotEqual" + // ACSRouterLabelOperatorEqual - = + AcsRouterLabelOperatorEqual ACSRouterLabelOperator = "Equal" + // ACSRouterLabelOperatorGreater - > + AcsRouterLabelOperatorGreater ACSRouterLabelOperator = "Greater" + // ACSRouterLabelOperatorGreaterThanOrEqual - >= + AcsRouterLabelOperatorGreaterThanOrEqual ACSRouterLabelOperator = "GreaterThanOrEqual" + // ACSRouterLabelOperatorLess - < + AcsRouterLabelOperatorLess ACSRouterLabelOperator = "Less" + // ACSRouterLabelOperatorLessThanOrEqual - <= + AcsRouterLabelOperatorLessThanOrEqual ACSRouterLabelOperator = "LessThanOrEqual" + // ACSRouterLabelOperatorNotEqual - != + AcsRouterLabelOperatorNotEqual ACSRouterLabelOperator = "NotEqual" ) -// PossibleAcsRouterLabelOperatorValues returns the possible values for the AcsRouterLabelOperator const type. -func PossibleAcsRouterLabelOperatorValues() []AcsRouterLabelOperator { - return []AcsRouterLabelOperator{ +// PossibleACSRouterLabelOperatorValues returns the possible values for the ACSRouterLabelOperator const type. +func PossibleACSRouterLabelOperatorValues() []ACSRouterLabelOperator { + return []ACSRouterLabelOperator{ AcsRouterLabelOperatorEqual, AcsRouterLabelOperatorGreater, AcsRouterLabelOperatorGreaterThanOrEqual, @@ -105,35 +105,61 @@ func PossibleAcsRouterLabelOperatorValues() []AcsRouterLabelOperator { } } -// AcsRouterWorkerSelectorState - Router Job Worker Selector State -type AcsRouterWorkerSelectorState string +// ACSRouterUpdatedWorkerProperty - An individual property updated in the Router Worker +type ACSRouterUpdatedWorkerProperty string const ( - // AcsRouterWorkerSelectorStateActive - Router Job Worker Selector is Active - AcsRouterWorkerSelectorStateActive AcsRouterWorkerSelectorState = "active" - // AcsRouterWorkerSelectorStateExpired - Router Job Worker Selector has Expire - AcsRouterWorkerSelectorStateExpired AcsRouterWorkerSelectorState = "expired" + AcsRouterUpdatedWorkerPropertyAvailableForOffers ACSRouterUpdatedWorkerProperty = "AvailableForOffers" + AcsRouterUpdatedWorkerPropertyChannelConfigurations ACSRouterUpdatedWorkerProperty = "ChannelConfigurations" + AcsRouterUpdatedWorkerPropertyLabels ACSRouterUpdatedWorkerProperty = "Labels" + AcsRouterUpdatedWorkerPropertyMaxConcurrentOffers ACSRouterUpdatedWorkerProperty = "MaxConcurrentOffers" + AcsRouterUpdatedWorkerPropertyQueueAssignments ACSRouterUpdatedWorkerProperty = "QueueAssignments" + AcsRouterUpdatedWorkerPropertyTags ACSRouterUpdatedWorkerProperty = "Tags" + AcsRouterUpdatedWorkerPropertyTotalCapacity ACSRouterUpdatedWorkerProperty = "TotalCapacity" ) -// PossibleAcsRouterWorkerSelectorStateValues returns the possible values for the AcsRouterWorkerSelectorState const type. -func PossibleAcsRouterWorkerSelectorStateValues() []AcsRouterWorkerSelectorState { - return []AcsRouterWorkerSelectorState{ +// PossibleACSRouterUpdatedWorkerPropertyValues returns the possible values for the ACSRouterUpdatedWorkerProperty const type. +func PossibleACSRouterUpdatedWorkerPropertyValues() []ACSRouterUpdatedWorkerProperty { + return []ACSRouterUpdatedWorkerProperty{ + AcsRouterUpdatedWorkerPropertyAvailableForOffers, + AcsRouterUpdatedWorkerPropertyChannelConfigurations, + AcsRouterUpdatedWorkerPropertyLabels, + AcsRouterUpdatedWorkerPropertyMaxConcurrentOffers, + AcsRouterUpdatedWorkerPropertyQueueAssignments, + AcsRouterUpdatedWorkerPropertyTags, + AcsRouterUpdatedWorkerPropertyTotalCapacity, + } +} + +// ACSRouterWorkerSelectorState - Router Job Worker Selector State +type ACSRouterWorkerSelectorState string + +const ( + // ACSRouterWorkerSelectorStateActive - Router Job Worker Selector is Active + AcsRouterWorkerSelectorStateActive ACSRouterWorkerSelectorState = "active" + // ACSRouterWorkerSelectorStateExpired - Router Job Worker Selector has Expire + AcsRouterWorkerSelectorStateExpired ACSRouterWorkerSelectorState = "expired" +) + +// PossibleACSRouterWorkerSelectorStateValues returns the possible values for the ACSRouterWorkerSelectorState const type. +func PossibleACSRouterWorkerSelectorStateValues() []ACSRouterWorkerSelectorState { + return []ACSRouterWorkerSelectorState{ AcsRouterWorkerSelectorStateActive, AcsRouterWorkerSelectorStateExpired, } } -// AcsUserEngagement - The type of engagement user have with email -type AcsUserEngagement string +// ACSUserEngagement - The type of engagement user have with email +type ACSUserEngagement string const ( - AcsUserEngagementClick AcsUserEngagement = "click" - AcsUserEngagementView AcsUserEngagement = "view" + AcsUserEngagementClick ACSUserEngagement = "click" + AcsUserEngagementView ACSUserEngagement = "view" ) -// PossibleAcsUserEngagementValues returns the possible values for the AcsUserEngagement const type. -func PossibleAcsUserEngagementValues() []AcsUserEngagement { - return []AcsUserEngagement{ +// PossibleACSUserEngagementValues returns the possible values for the ACSUserEngagement const type. +func PossibleACSUserEngagementValues() []ACSUserEngagement { + return []ACSUserEngagement{ AcsUserEngagementClick, AcsUserEngagementView, } @@ -223,6 +249,28 @@ func PossibleCommunicationCloudEnvironmentModelValues() []CommunicationCloudEnvi } } +// CommunicationIdentifierModelKind - The identifier kind, for example 'communicationUser' or 'phoneNumber'. +type CommunicationIdentifierModelKind string + +const ( + CommunicationIdentifierModelKindCommunicationUser CommunicationIdentifierModelKind = "communicationUser" + CommunicationIdentifierModelKindMicrosoftTeamsApp CommunicationIdentifierModelKind = "microsoftTeamsApp" + CommunicationIdentifierModelKindMicrosoftTeamsUser CommunicationIdentifierModelKind = "microsoftTeamsUser" + CommunicationIdentifierModelKindPhoneNumber CommunicationIdentifierModelKind = "phoneNumber" + CommunicationIdentifierModelKindUnknown CommunicationIdentifierModelKind = "unknown" +) + +// PossibleCommunicationIdentifierModelKindValues returns the possible values for the CommunicationIdentifierModelKind const type. +func PossibleCommunicationIdentifierModelKindValues() []CommunicationIdentifierModelKind { + return []CommunicationIdentifierModelKind{ + CommunicationIdentifierModelKindCommunicationUser, + CommunicationIdentifierModelKindMicrosoftTeamsApp, + CommunicationIdentifierModelKindMicrosoftTeamsUser, + CommunicationIdentifierModelKindPhoneNumber, + CommunicationIdentifierModelKindUnknown, + } +} + // DataBoxStageName - Schema of DataBox Stage Name enumeration. type DataBoxStageName string diff --git a/sdk/messaging/eventgrid/azsystemevents/models.go b/sdk/messaging/eventgrid/azsystemevents/models.go index 2a1251f2ad35..e2f95dfab701 100644 --- a/sdk/messaging/eventgrid/azsystemevents/models.go +++ b/sdk/messaging/eventgrid/azsystemevents/models.go @@ -887,7 +887,7 @@ type ACSEmailDeliveryReportReceivedEventData struct { DeliveryAttemptTimestamp *time.Time // Detailed information about the status if any - DeliveryStatusDetails *AcsEmailDeliveryReportStatusDetails + DeliveryStatusDetails *ACSEmailDeliveryReportStatusDetails // The Id of the email been sent MessageID *string @@ -899,11 +899,11 @@ type ACSEmailDeliveryReportReceivedEventData struct { Sender *string // The status of the email. Any value other than Delivered is considered failed. - Status *AcsEmailDeliveryReportStatus + Status *ACSEmailDeliveryReportStatus } -// AcsEmailDeliveryReportStatusDetails - Detailed information about the status if any -type AcsEmailDeliveryReportStatusDetails struct { +// ACSEmailDeliveryReportStatusDetails - Detailed information about the status if any +type ACSEmailDeliveryReportStatusDetails struct { // Detailed status message StatusMessage *string } @@ -912,7 +912,7 @@ type AcsEmailDeliveryReportStatusDetails struct { // event. type ACSEmailEngagementTrackingReportReceivedEventData struct { // The type of engagement user have with email - Engagement *AcsUserEngagement + Engagement *ACSUserEngagement // The context of the type of engagement user had with email EngagementContext *string @@ -933,8 +933,8 @@ type ACSEmailEngagementTrackingReportReceivedEventData struct { UserAgent *string } -// AcsIncomingCallCustomContext - Custom Context of Incoming Call -type AcsIncomingCallCustomContext struct { +// ACSIncomingCallCustomContext - Custom Context of Incoming Call +type ACSIncomingCallCustomContext struct { // Sip Headers for incoming call SipHeaders map[string]*string @@ -952,7 +952,7 @@ type ACSIncomingCallEventData struct { CorrelationID *string // Custom Context of Incoming Call - CustomContext *AcsIncomingCallCustomContext + CustomContext *ACSIncomingCallCustomContext // The communication identifier of the user who initiated the call. FromCommunicationIdentifier *CommunicationIdentifierModel @@ -1019,8 +1019,8 @@ type ACSRecordingStorageInfoProperties struct { RecordingChunks []ACSRecordingChunkInfoProperties } -// AcsRouterChannelConfiguration - Router Channel Configuration -type AcsRouterChannelConfiguration struct { +// ACSRouterChannelConfiguration - Router Channel Configuration +type ACSRouterChannelConfiguration struct { // Capacity Cost Per Job for Router Job CapacityCostPerJob *int32 @@ -1031,16 +1031,16 @@ type AcsRouterChannelConfiguration struct { MaxNumberOfJobs *int32 } -// AcsRouterCommunicationError - Router Communication Error -type AcsRouterCommunicationError struct { +// ACSRouterCommunicationError - Router Communication Error +type ACSRouterCommunicationError struct { // Router Communication Error Code Code *string // List of Router Communication Errors - Details []AcsRouterCommunicationError + Details []ACSRouterCommunicationError // Router Communication Inner Error - Innererror *AcsRouterCommunicationError + Innererror *ACSRouterCommunicationError // Router Communication Error Message Message *string @@ -1102,7 +1102,7 @@ type ACSRouterJobClassificationFailedEventData struct { ClassificationPolicyID *string // Router Job Classification Failed Errors - Errors []AcsRouterCommunicationError + Errors []ACSRouterCommunicationError // Router Event Job ID JobID *string @@ -1121,7 +1121,7 @@ type ACSRouterJobClassificationFailedEventData struct { // event type ACSRouterJobClassifiedEventData struct { // Router Job Attached Worker Selector - AttachedWorkerSelectors []AcsRouterWorkerSelector + AttachedWorkerSelectors []ACSRouterWorkerSelector // Router Event Channel ID ChannelID *string @@ -1142,7 +1142,7 @@ type ACSRouterJobClassifiedEventData struct { Priority *int32 // Router Job Queue Info - QueueDetails *AcsRouterQueueDetails + QueueDetails *ACSRouterQueueDetails // Router Job events Queue Id QueueID *string @@ -1285,7 +1285,7 @@ type ACSRouterJobExceptionTriggeredEventData struct { // event type ACSRouterJobQueuedEventData struct { // Router Job Queued Attached Worker Selector - AttachedWorkerSelectors []AcsRouterWorkerSelector + AttachedWorkerSelectors []ACSRouterWorkerSelector // Router Event Channel ID ChannelID *string @@ -1306,7 +1306,7 @@ type ACSRouterJobQueuedEventData struct { QueueID *string // Router Job Queued Requested Worker Selector - RequestedWorkerSelectors []AcsRouterWorkerSelector + RequestedWorkerSelectors []ACSRouterWorkerSelector // Router Jobs events Tags Tags map[string]*string @@ -1331,7 +1331,7 @@ type ACSRouterJobReceivedEventData struct { JobID *string // Router Job Received Job Status - JobStatus *AcsRouterJobStatus + JobStatus *ACSRouterJobStatus // Router Job events Labels Labels map[string]*string @@ -1343,7 +1343,7 @@ type ACSRouterJobReceivedEventData struct { QueueID *string // Router Job Received Requested Worker Selectors - RequestedWorkerSelectors []AcsRouterWorkerSelector + RequestedWorkerSelectors []ACSRouterWorkerSelector // Router Job Received Scheduled Time in UTC ScheduledOn *time.Time @@ -1362,10 +1362,10 @@ type ACSRouterJobSchedulingFailedEventData struct { ChannelReference *string // Router Job Scheduling Failed Attached Worker Selector Expired - ExpiredAttachedWorkerSelectors []AcsRouterWorkerSelector + ExpiredAttachedWorkerSelectors []ACSRouterWorkerSelector // Router Job Scheduling Failed Requested Worker Selector Expired - ExpiredRequestedWorkerSelectors []AcsRouterWorkerSelector + ExpiredRequestedWorkerSelectors []ACSRouterWorkerSelector // Router Job Scheduling Failed Reason FailureReason *string @@ -1430,10 +1430,10 @@ type ACSRouterJobWaitingForActivationEventData struct { ChannelReference *string // Router Job Waiting For Activation Worker Selector Expired - ExpiredAttachedWorkerSelectors []AcsRouterWorkerSelector + ExpiredAttachedWorkerSelectors []ACSRouterWorkerSelector // Router Job Waiting For Activation Requested Worker Selector Expired - ExpiredRequestedWorkerSelectors []AcsRouterWorkerSelector + ExpiredRequestedWorkerSelectors []ACSRouterWorkerSelector // Router Event Job ID JobID *string @@ -1464,10 +1464,10 @@ type ACSRouterJobWorkerSelectorsExpiredEventData struct { ChannelReference *string // Router Job Worker Selectors Expired Attached Worker Selectors - ExpiredAttachedWorkerSelectors []AcsRouterWorkerSelector + ExpiredAttachedWorkerSelectors []ACSRouterWorkerSelector // Router Job Worker Selectors Expired Requested Worker Selectors - ExpiredRequestedWorkerSelectors []AcsRouterWorkerSelector + ExpiredRequestedWorkerSelectors []ACSRouterWorkerSelector // Router Event Job ID JobID *string @@ -1482,8 +1482,8 @@ type ACSRouterJobWorkerSelectorsExpiredEventData struct { Tags map[string]*string } -// AcsRouterQueueDetails - Router Queue Details -type AcsRouterQueueDetails struct { +// ACSRouterQueueDetails - Router Queue Details +type ACSRouterQueueDetails struct { // Router Queue Id ID *string @@ -1685,13 +1685,13 @@ type ACSRouterWorkerOfferRevokedEventData struct { // event type ACSRouterWorkerRegisteredEventData struct { // Router Worker Registered Channel Configuration - ChannelConfigurations []AcsRouterChannelConfiguration + ChannelConfigurations []ACSRouterChannelConfiguration // Router Worker Registered Labels Labels map[string]*string // Router Worker Registered Queue Info - QueueAssignments []AcsRouterQueueDetails + QueueAssignments []ACSRouterQueueDetails // Router Worker Registered Tags Tags map[string]*string @@ -1703,8 +1703,8 @@ type ACSRouterWorkerRegisteredEventData struct { WorkerID *string } -// AcsRouterWorkerSelector - Router Job Worker Selector -type AcsRouterWorkerSelector struct { +// ACSRouterWorkerSelector - Router Job Worker Selector +type ACSRouterWorkerSelector struct { // Router Job Worker Selector Expiration Time ExpirationTime *time.Time @@ -1712,18 +1712,43 @@ type AcsRouterWorkerSelector struct { Key *string // Router Job Worker Selector Label Operator - LabelOperator *AcsRouterLabelOperator + LabelOperator *ACSRouterLabelOperator // Router Job Worker Selector Value LabelValue any // Router Job Worker Selector State - State *AcsRouterWorkerSelectorState + State *ACSRouterWorkerSelectorState // Router Job Worker Selector Time to Live in Seconds TimeToLive *float32 } +// ACSRouterWorkerUpdatedEventData - Schema of the Data property of an CloudEvent/EventGridEvent for a Microsoft.Communication.RouterWorkerUpdated +// event +type ACSRouterWorkerUpdatedEventData struct { + // Router Worker Updated Channel Configuration + ChannelConfigurations []ACSRouterChannelConfiguration + + // Router Worker Updated Labels + Labels map[string]*string + + // Router Worker Updated Queue Info + QueueAssignments []ACSRouterQueueDetails + + // Router Worker Updated Tags + Tags map[string]*string + + // Router Worker Updated Total Capacity + TotalCapacity *int32 + + // Router Worker Properties Updated + UpdatedWorkerProperties []ACSRouterUpdatedWorkerProperty + + // Router Worker Updated Worker Id + WorkerID *string +} + // ACSSmsDeliveryAttemptProperties - Schema for details of a delivery attempt type ACSSmsDeliveryAttemptProperties struct { // Number of segments whose delivery failed @@ -2050,12 +2075,18 @@ type AVSScriptExecutionStartedEventData struct { } // CommunicationIdentifierModel - Identifies a participant in Azure Communication services. A participant is, for example, -// a phone number or an Azure communication user. This model must be interpreted as a union: Apart from rawId, at -// most one further property may be set. +// a phone number or an Azure communication user. This model is polymorphic: Apart from kind and rawId, at most +// one further property may be set which must match the kind enum value. type CommunicationIdentifierModel struct { // The communication user. CommunicationUser *CommunicationUserIdentifierModel + // The identifier kind. Only required in responses. + Kind *CommunicationIdentifierModelKind + + // The Microsoft Teams application. + MicrosoftTeamsApp *MicrosoftTeamsAppIdentifierModel + // The Microsoft Teams user. MicrosoftTeamsUser *MicrosoftTeamsUserIdentifierModel @@ -3879,6 +3910,15 @@ type MediaLiveEventTrackDiscontinuityDetectedEventData struct { TrackType *string } +// MicrosoftTeamsAppIdentifierModel - A Microsoft Teams application. +type MicrosoftTeamsAppIdentifierModel struct { + // REQUIRED; The Id of the Microsoft Teams application. + AppID *string + + // The cloud that the Microsoft Teams application belongs to. By default 'public' if missing. + Cloud *CommunicationCloudEnvironmentModel +} + // MicrosoftTeamsUserIdentifierModel - A Microsoft Teams user. type MicrosoftTeamsUserIdentifierModel struct { // REQUIRED; The Id of the Microsoft Teams user. If not anonymous, this is the AAD object Id of the user. diff --git a/sdk/messaging/eventgrid/azsystemevents/models_serde.go b/sdk/messaging/eventgrid/azsystemevents/models_serde.go index 545b046eb30f..2b5587074d7e 100644 --- a/sdk/messaging/eventgrid/azsystemevents/models_serde.go +++ b/sdk/messaging/eventgrid/azsystemevents/models_serde.go @@ -2083,15 +2083,15 @@ func (a *ACSEmailDeliveryReportReceivedEventData) UnmarshalJSON(data []byte) err return nil } -// MarshalJSON implements the json.Marshaller interface for type AcsEmailDeliveryReportStatusDetails. -func (a AcsEmailDeliveryReportStatusDetails) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type ACSEmailDeliveryReportStatusDetails. +func (a ACSEmailDeliveryReportStatusDetails) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "statusMessage", a.StatusMessage) return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type AcsEmailDeliveryReportStatusDetails. -func (a *AcsEmailDeliveryReportStatusDetails) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSEmailDeliveryReportStatusDetails. +func (a *ACSEmailDeliveryReportStatusDetails) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -2161,16 +2161,16 @@ func (a *ACSEmailEngagementTrackingReportReceivedEventData) UnmarshalJSON(data [ return nil } -// MarshalJSON implements the json.Marshaller interface for type AcsIncomingCallCustomContext. -func (a AcsIncomingCallCustomContext) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type ACSIncomingCallCustomContext. +func (a ACSIncomingCallCustomContext) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "sipHeaders", a.SipHeaders) populate(objectMap, "voipHeaders", a.VoipHeaders) return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type AcsIncomingCallCustomContext. -func (a *AcsIncomingCallCustomContext) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSIncomingCallCustomContext. +func (a *ACSIncomingCallCustomContext) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -2368,8 +2368,8 @@ func (a *ACSRecordingStorageInfoProperties) UnmarshalJSON(data []byte) error { return nil } -// MarshalJSON implements the json.Marshaller interface for type AcsRouterChannelConfiguration. -func (a AcsRouterChannelConfiguration) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type ACSRouterChannelConfiguration. +func (a ACSRouterChannelConfiguration) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "capacityCostPerJob", a.CapacityCostPerJob) populate(objectMap, "channelId", a.ChannelID) @@ -2377,8 +2377,8 @@ func (a AcsRouterChannelConfiguration) MarshalJSON() ([]byte, error) { return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type AcsRouterChannelConfiguration. -func (a *AcsRouterChannelConfiguration) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSRouterChannelConfiguration. +func (a *ACSRouterChannelConfiguration) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -2403,8 +2403,8 @@ func (a *AcsRouterChannelConfiguration) UnmarshalJSON(data []byte) error { return nil } -// MarshalJSON implements the json.Marshaller interface for type AcsRouterCommunicationError. -func (a AcsRouterCommunicationError) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type ACSRouterCommunicationError. +func (a ACSRouterCommunicationError) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "code", a.Code) populate(objectMap, "details", a.Details) @@ -2414,8 +2414,8 @@ func (a AcsRouterCommunicationError) MarshalJSON() ([]byte, error) { return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type AcsRouterCommunicationError. -func (a *AcsRouterCommunicationError) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSRouterCommunicationError. +func (a *ACSRouterCommunicationError) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -3291,8 +3291,8 @@ func (a *ACSRouterJobWorkerSelectorsExpiredEventData) UnmarshalJSON(data []byte) return nil } -// MarshalJSON implements the json.Marshaller interface for type AcsRouterQueueDetails. -func (a AcsRouterQueueDetails) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type ACSRouterQueueDetails. +func (a ACSRouterQueueDetails) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "id", a.ID) populate(objectMap, "labels", a.Labels) @@ -3300,8 +3300,8 @@ func (a AcsRouterQueueDetails) MarshalJSON() ([]byte, error) { return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type AcsRouterQueueDetails. -func (a *AcsRouterQueueDetails) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSRouterQueueDetails. +func (a *ACSRouterQueueDetails) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -3765,20 +3765,20 @@ func (a *ACSRouterWorkerRegisteredEventData) UnmarshalJSON(data []byte) error { return nil } -// MarshalJSON implements the json.Marshaller interface for type AcsRouterWorkerSelector. -func (a AcsRouterWorkerSelector) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type ACSRouterWorkerSelector. +func (a ACSRouterWorkerSelector) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populateDateTimeRFC3339(objectMap, "expirationTime", a.ExpirationTime) populate(objectMap, "key", a.Key) populate(objectMap, "labelOperator", a.LabelOperator) - populateAny(objectMap, "labelValue", a.LabelValue) + populateAny(objectMap, "value", a.LabelValue) populate(objectMap, "state", a.State) populate(objectMap, "ttlSeconds", a.TimeToLive) return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type AcsRouterWorkerSelector. -func (a *AcsRouterWorkerSelector) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSRouterWorkerSelector. +func (a *ACSRouterWorkerSelector) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -3795,7 +3795,7 @@ func (a *AcsRouterWorkerSelector) UnmarshalJSON(data []byte) error { case "labelOperator": err = unpopulate(val, "LabelOperator", &a.LabelOperator) delete(rawMsg, key) - case "labelValue": + case "value": err = unpopulate(val, "LabelValue", &a.LabelValue) delete(rawMsg, key) case "state": @@ -3812,6 +3812,57 @@ func (a *AcsRouterWorkerSelector) UnmarshalJSON(data []byte) error { return nil } +// MarshalJSON implements the json.Marshaller interface for type ACSRouterWorkerUpdatedEventData. +func (a ACSRouterWorkerUpdatedEventData) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "channelConfigurations", a.ChannelConfigurations) + populate(objectMap, "labels", a.Labels) + populate(objectMap, "queueAssignments", a.QueueAssignments) + populate(objectMap, "tags", a.Tags) + populate(objectMap, "totalCapacity", a.TotalCapacity) + populate(objectMap, "updatedWorkerProperties", a.UpdatedWorkerProperties) + populate(objectMap, "workerId", a.WorkerID) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSRouterWorkerUpdatedEventData. +func (a *ACSRouterWorkerUpdatedEventData) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "channelConfigurations": + err = unpopulate(val, "ChannelConfigurations", &a.ChannelConfigurations) + delete(rawMsg, key) + case "labels": + err = unpopulate(val, "Labels", &a.Labels) + delete(rawMsg, key) + case "queueAssignments": + err = unpopulate(val, "QueueAssignments", &a.QueueAssignments) + delete(rawMsg, key) + case "tags": + err = unpopulate(val, "Tags", &a.Tags) + delete(rawMsg, key) + case "totalCapacity": + err = unpopulate(val, "TotalCapacity", &a.TotalCapacity) + delete(rawMsg, key) + case "updatedWorkerProperties": + err = unpopulate(val, "UpdatedWorkerProperties", &a.UpdatedWorkerProperties) + delete(rawMsg, key) + case "workerId": + err = unpopulate(val, "WorkerID", &a.WorkerID) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + // MarshalJSON implements the json.Marshaller interface for type ACSSmsDeliveryAttemptProperties. func (a ACSSmsDeliveryAttemptProperties) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) @@ -4688,6 +4739,8 @@ func (a *AVSScriptExecutionStartedEventData) UnmarshalJSON(data []byte) error { func (c CommunicationIdentifierModel) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "communicationUser", c.CommunicationUser) + populate(objectMap, "kind", c.Kind) + populate(objectMap, "microsoftTeamsApp", c.MicrosoftTeamsApp) populate(objectMap, "microsoftTeamsUser", c.MicrosoftTeamsUser) populate(objectMap, "phoneNumber", c.PhoneNumber) populate(objectMap, "rawId", c.RawID) @@ -4706,6 +4759,12 @@ func (c *CommunicationIdentifierModel) UnmarshalJSON(data []byte) error { case "communicationUser": err = unpopulate(val, "CommunicationUser", &c.CommunicationUser) delete(rawMsg, key) + case "kind": + err = unpopulate(val, "Kind", &c.Kind) + delete(rawMsg, key) + case "microsoftTeamsApp": + err = unpopulate(val, "MicrosoftTeamsApp", &c.MicrosoftTeamsApp) + delete(rawMsg, key) case "microsoftTeamsUser": err = unpopulate(val, "MicrosoftTeamsUser", &c.MicrosoftTeamsUser) delete(rawMsg, key) @@ -8861,6 +8920,37 @@ func (m *MediaLiveEventTrackDiscontinuityDetectedEventData) UnmarshalJSON(data [ return nil } +// MarshalJSON implements the json.Marshaller interface for type MicrosoftTeamsAppIdentifierModel. +func (m MicrosoftTeamsAppIdentifierModel) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "appId", m.AppID) + populate(objectMap, "cloud", m.Cloud) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type MicrosoftTeamsAppIdentifierModel. +func (m *MicrosoftTeamsAppIdentifierModel) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", m, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "appId": + err = unpopulate(val, "AppID", &m.AppID) + delete(rawMsg, key) + case "cloud": + err = unpopulate(val, "Cloud", &m.Cloud) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", m, err) + } + } + return nil +} + // MarshalJSON implements the json.Marshaller interface for type MicrosoftTeamsUserIdentifierModel. func (m MicrosoftTeamsUserIdentifierModel) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) diff --git a/sdk/messaging/eventgrid/azsystemevents/system_events.go b/sdk/messaging/eventgrid/azsystemevents/system_events.go index 803c4a2cc010..682365a7b510 100644 --- a/sdk/messaging/eventgrid/azsystemevents/system_events.go +++ b/sdk/messaging/eventgrid/azsystemevents/system_events.go @@ -100,6 +100,7 @@ const ( TypeACSRouterWorkerOfferIssued Type = "Microsoft.Communication.RouterWorkerOfferIssued" // maps to ACSRouterWorkerOfferIssuedEventData TypeACSRouterWorkerOfferRevoked Type = "Microsoft.Communication.RouterWorkerOfferRevoked" // maps to ACSRouterWorkerOfferRevokedEventData TypeACSRouterWorkerRegistered Type = "Microsoft.Communication.RouterWorkerRegistered" // maps to ACSRouterWorkerRegisteredEventData + TypeACSRouterWorkerUpdated Type = "Microsoft.Communication.RouterWorkerUpdated" // maps to ACSRouterWorkerUpdatedEventData TypeACSSmsDeliveryReportReceived Type = "Microsoft.Communication.SMSDeliveryReportReceived" // maps to ACSSmsDeliveryReportReceivedEventData TypeACSSmsReceived Type = "Microsoft.Communication.SMSReceived" // maps to ACSSmsReceivedEventData TypeACSUserDisconnected Type = "Microsoft.Communication.UserDisconnected" // maps to ACSUserDisconnectedEventData From df0c1397b0eb0b3d05ce5732b840e84045a1de93 Mon Sep 17 00:00:00 2001 From: ripark Date: Thu, 21 Mar 2024 01:35:02 +0000 Subject: [PATCH 02/12] Adding tests for previous events. --- .../azsystemevents/system_events5_test.go | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/sdk/messaging/eventgrid/azsystemevents/system_events5_test.go b/sdk/messaging/eventgrid/azsystemevents/system_events5_test.go index 895009073941..04bde3713796 100644 --- a/sdk/messaging/eventgrid/azsystemevents/system_events5_test.go +++ b/sdk/messaging/eventgrid/azsystemevents/system_events5_test.go @@ -9,6 +9,7 @@ package azsystemevents_test import ( "testing" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" "github.com/Azure/azure-sdk-for-go/sdk/messaging/eventgrid/azsystemevents" "github.com/stretchr/testify/require" @@ -574,3 +575,62 @@ func TestConsumeCloudEventResourceCreatedOrUpdatedEvent(t *testing.T) { "/subscriptions/319a9601-1ec0-0000-aebc-8fe82724c81e/resourceGroups/{rg-name}/providers/Microsoft.Storage/storageAccounts/{storageAccount-name}", *sysEvent.ResourceDetails.ID) } + +func TestConsumeCloudEventAPICenter(t *testing.T) { + // https://learn.microsoft.com/en-us/azure/event-grid/event-schema-api-center?tabs=cloud-event-schema + const addedEventText = `[{ + "source": "/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.ApiCenter/services", + "subject": "/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.ApiCenter/services/{api_center_name}/workspaces/default/apis/{api_name}/versions/{version_name}/definitions/{definition_name}", + "type": "Microsoft.ApiCenter.ApiDefinitionAdded", + "time": "2024-03-01T00:00:00.0000000Z", + "id": "00000000-0000-0000-0000-000000000000", + "data": { + "title": "OpenAPI", + "description": "Default spec", + "specification": { + "name": "openapi", + "version": "3.0.1" + } + }, + "specversion": "1.0" + }]` + + events := parseManyCloudEvents(t, addedEventText) + addedEvent := deserializeSystemEvent[azsystemevents.APICenterAPIDefinitionAddedEventData](t, events[0].Data) + require.Equal(t, azsystemevents.APICenterAPIDefinitionAddedEventData{ + Title: to.Ptr("OpenAPI"), + Description: to.Ptr("Default spec"), + Specification: &azsystemevents.APICenterAPISpecification{ + Name: to.Ptr("openapi"), + Version: to.Ptr("3.0.1"), + }, + }, addedEvent) + + const updatedEventText = `[{ + "source": "/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.ApiCenter/services", + "subject": "/subscriptions/{subscription_id}/resourceGroups/{resource_group_name}/providers/Microsoft.ApiCenter/services/{api_center_name}/workspaces/default/apis/{api_name}/versions/{version_name}/definitions/{definition_name}", + "type": "Microsoft.ApiCenter.ApiDefinitionUpdated", + "time": "2024-03-01T00:00:00.0000000Z", + "id": "00000000-0000-0000-0000-000000000000", + "data": { + "title": "OpenAPI", + "description": "Default spec", + "specification": { + "name": "openapi", + "version": "3.0.1" + } + }, + "specversion": "1.0" + }]` + + events = parseManyCloudEvents(t, updatedEventText) + updatedEvent := deserializeSystemEvent[azsystemevents.APICenterAPIDefinitionUpdatedEventData](t, events[0].Data) + require.Equal(t, azsystemevents.APICenterAPIDefinitionUpdatedEventData{ + Title: to.Ptr("OpenAPI"), + Description: to.Ptr("Default spec"), + Specification: &azsystemevents.APICenterAPISpecification{ + Name: to.Ptr("openapi"), + Version: to.Ptr("3.0.1"), + }, + }, updatedEvent) +} From 50d025910bf587bbf9c730fea2029f64410e07ca Mon Sep 17 00:00:00 2001 From: ripark Date: Fri, 22 Mar 2024 00:23:01 +0000 Subject: [PATCH 03/12] Fixing quite a few areas that weren't renamed properly in the last autorest/regex experiment I did. --- .../eventgrid/azsystemevents/autorest.md | 40 ---- .../eventgrid/azsystemevents/constants.go | 150 +++++++------- .../internal/generate/generate_enum.go | 192 +++++++++++++++++- .../azsystemevents/internal/gopls/gopls.go | 89 ++++++++ .../azsystemevents/internal/version.go | 2 +- .../azsystemevents/system_events2_test.go | 2 +- .../azsystemevents/system_events4_test.go | 2 +- .../azsystemevents/system_events5_test.go | 6 +- 8 files changed, 360 insertions(+), 123 deletions(-) create mode 100644 sdk/messaging/eventgrid/azsystemevents/internal/gopls/gopls.go diff --git a/sdk/messaging/eventgrid/azsystemevents/autorest.md b/sdk/messaging/eventgrid/azsystemevents/autorest.md index 14579178b538..b278023701fa 100644 --- a/sdk/messaging/eventgrid/azsystemevents/autorest.md +++ b/sdk/messaging/eventgrid/azsystemevents/autorest.md @@ -144,43 +144,3 @@ directive: } return $; ``` - -Fix acronyms so they match our naming convention. - -```yaml -directive: - - from: - - models.go - - models_serde.go - where: $ - transform: | - const acronyms = ["Acs", "Avs", "Iot"]; - for (let acr of acronyms) { - // ex: - // '// AcsChatMessageDeletedEventData - Schema' - // 'type AcsChatMessageDeletedEventData struct' - // 'Participants []AcsChatThreadParticipantProperties' - // 'ParticipantRemoved *AcsChatThreadParticipantProperties' - const re = new RegExp(`([ *\\]])${acr}([A-Za-z0-9]+?(?:EventData|Properties|Property|Details|Context|Configuration|Error|Selector))`, "sg"); - $ = $.replace(re, `$1${acr.toUpperCase()}$2`); - - // fix any fields that reference these models - const re2 = new RegExp(`([*])${acr}([A-Za-z0-9]+?)`, "sg"); - $ = $.replace(re2, `$1${acr.toUpperCase()}$2`); - } - - return $; - - from: - - constants.go - where: $ - debug: True - transform: | - const acronyms = ["Acs", "Avs", "Iot"]; - for (let acr of acronyms) { - // ex: - const re = new RegExp(`([ \\]]|Possible)${acr}([A-Za-z0-9]+?[ ,{(])`, "sg"); - $ = $.replace(re, `$1${acr.toUpperCase()}$2`); - } - - return $; -``` diff --git a/sdk/messaging/eventgrid/azsystemevents/constants.go b/sdk/messaging/eventgrid/azsystemevents/constants.go index 99a692702fd8..5866ebf54954 100644 --- a/sdk/messaging/eventgrid/azsystemevents/constants.go +++ b/sdk/messaging/eventgrid/azsystemevents/constants.go @@ -13,29 +13,29 @@ type ACSEmailDeliveryReportStatus string const ( // ACSEmailDeliveryReportStatusBounced - Hard bounce detected while sending the email - AcsEmailDeliveryReportStatusBounced ACSEmailDeliveryReportStatus = "Bounced" + ACSEmailDeliveryReportStatusBounced ACSEmailDeliveryReportStatus = "Bounced" // ACSEmailDeliveryReportStatusDelivered - The email was delivered - AcsEmailDeliveryReportStatusDelivered ACSEmailDeliveryReportStatus = "Delivered" + ACSEmailDeliveryReportStatusDelivered ACSEmailDeliveryReportStatus = "Delivered" // ACSEmailDeliveryReportStatusFailed - The email failed to be delivered - AcsEmailDeliveryReportStatusFailed ACSEmailDeliveryReportStatus = "Failed" + ACSEmailDeliveryReportStatusFailed ACSEmailDeliveryReportStatus = "Failed" // ACSEmailDeliveryReportStatusFilteredSpam - The message was identified spam and was rejected or blocked (not quarantined). - AcsEmailDeliveryReportStatusFilteredSpam ACSEmailDeliveryReportStatus = "FilteredSpam" + ACSEmailDeliveryReportStatusFilteredSpam ACSEmailDeliveryReportStatus = "FilteredSpam" // ACSEmailDeliveryReportStatusQuarantined - The message was quarantined (as spam, bulk mail, or phishing). For more information, // see Quarantined email messages in EOP (EXCHANGE ONLINE PROTECTION). - AcsEmailDeliveryReportStatusQuarantined ACSEmailDeliveryReportStatus = "Quarantined" + ACSEmailDeliveryReportStatusQuarantined ACSEmailDeliveryReportStatus = "Quarantined" // ACSEmailDeliveryReportStatusSuppressed - The email was suppressed - AcsEmailDeliveryReportStatusSuppressed ACSEmailDeliveryReportStatus = "Suppressed" + ACSEmailDeliveryReportStatusSuppressed ACSEmailDeliveryReportStatus = "Suppressed" ) -// PossibleACSEmailDeliveryReportStatusValues returns the possible values for the ACSEmailDeliveryReportStatus const type. +// PossibleACSEmailDeliveryReportStatusValues returns the possible values for the AcsEmailDeliveryReportStatus const type. func PossibleACSEmailDeliveryReportStatusValues() []ACSEmailDeliveryReportStatus { return []ACSEmailDeliveryReportStatus{ - AcsEmailDeliveryReportStatusBounced, - AcsEmailDeliveryReportStatusDelivered, - AcsEmailDeliveryReportStatusFailed, - AcsEmailDeliveryReportStatusFilteredSpam, - AcsEmailDeliveryReportStatusQuarantined, - AcsEmailDeliveryReportStatusSuppressed, + ACSEmailDeliveryReportStatusBounced, + ACSEmailDeliveryReportStatusDelivered, + ACSEmailDeliveryReportStatusFailed, + ACSEmailDeliveryReportStatusFilteredSpam, + ACSEmailDeliveryReportStatusQuarantined, + ACSEmailDeliveryReportStatusSuppressed, } } @@ -43,35 +43,35 @@ func PossibleACSEmailDeliveryReportStatusValues() []ACSEmailDeliveryReportStatus type ACSRouterJobStatus string const ( - AcsRouterJobStatusAssigned ACSRouterJobStatus = "Assigned" - AcsRouterJobStatusCancelled ACSRouterJobStatus = "Cancelled" - AcsRouterJobStatusClassificationFailed ACSRouterJobStatus = "ClassificationFailed" - AcsRouterJobStatusClosed ACSRouterJobStatus = "Closed" - AcsRouterJobStatusCompleted ACSRouterJobStatus = "Completed" - AcsRouterJobStatusCreated ACSRouterJobStatus = "Created" - AcsRouterJobStatusPendingClassification ACSRouterJobStatus = "PendingClassification" - AcsRouterJobStatusPendingSchedule ACSRouterJobStatus = "PendingSchedule" - AcsRouterJobStatusQueued ACSRouterJobStatus = "Queued" - AcsRouterJobStatusScheduleFailed ACSRouterJobStatus = "ScheduleFailed" - AcsRouterJobStatusScheduled ACSRouterJobStatus = "Scheduled" - AcsRouterJobStatusWaitingForActivation ACSRouterJobStatus = "WaitingForActivation" + ACSRouterJobStatusAssigned ACSRouterJobStatus = "Assigned" + ACSRouterJobStatusCancelled ACSRouterJobStatus = "Cancelled" + ACSRouterJobStatusClassificationFailed ACSRouterJobStatus = "ClassificationFailed" + ACSRouterJobStatusClosed ACSRouterJobStatus = "Closed" + ACSRouterJobStatusCompleted ACSRouterJobStatus = "Completed" + ACSRouterJobStatusCreated ACSRouterJobStatus = "Created" + ACSRouterJobStatusPendingClassification ACSRouterJobStatus = "PendingClassification" + ACSRouterJobStatusPendingSchedule ACSRouterJobStatus = "PendingSchedule" + ACSRouterJobStatusQueued ACSRouterJobStatus = "Queued" + ACSRouterJobStatusScheduleFailed ACSRouterJobStatus = "ScheduleFailed" + ACSRouterJobStatusScheduled ACSRouterJobStatus = "Scheduled" + ACSRouterJobStatusWaitingForActivation ACSRouterJobStatus = "WaitingForActivation" ) -// PossibleACSRouterJobStatusValues returns the possible values for the ACSRouterJobStatus const type. +// PossibleACSRouterJobStatusValues returns the possible values for the AcsRouterJobStatus const type. func PossibleACSRouterJobStatusValues() []ACSRouterJobStatus { return []ACSRouterJobStatus{ - AcsRouterJobStatusAssigned, - AcsRouterJobStatusCancelled, - AcsRouterJobStatusClassificationFailed, - AcsRouterJobStatusClosed, - AcsRouterJobStatusCompleted, - AcsRouterJobStatusCreated, - AcsRouterJobStatusPendingClassification, - AcsRouterJobStatusPendingSchedule, - AcsRouterJobStatusQueued, - AcsRouterJobStatusScheduleFailed, - AcsRouterJobStatusScheduled, - AcsRouterJobStatusWaitingForActivation, + ACSRouterJobStatusAssigned, + ACSRouterJobStatusCancelled, + ACSRouterJobStatusClassificationFailed, + ACSRouterJobStatusClosed, + ACSRouterJobStatusCompleted, + ACSRouterJobStatusCreated, + ACSRouterJobStatusPendingClassification, + ACSRouterJobStatusPendingSchedule, + ACSRouterJobStatusQueued, + ACSRouterJobStatusScheduleFailed, + ACSRouterJobStatusScheduled, + ACSRouterJobStatusWaitingForActivation, } } @@ -80,28 +80,28 @@ type ACSRouterLabelOperator string const ( // ACSRouterLabelOperatorEqual - = - AcsRouterLabelOperatorEqual ACSRouterLabelOperator = "Equal" + ACSRouterLabelOperatorEqual ACSRouterLabelOperator = "Equal" // ACSRouterLabelOperatorGreater - > - AcsRouterLabelOperatorGreater ACSRouterLabelOperator = "Greater" + ACSRouterLabelOperatorGreater ACSRouterLabelOperator = "Greater" // ACSRouterLabelOperatorGreaterThanOrEqual - >= - AcsRouterLabelOperatorGreaterThanOrEqual ACSRouterLabelOperator = "GreaterThanOrEqual" + ACSRouterLabelOperatorGreaterThanOrEqual ACSRouterLabelOperator = "GreaterThanOrEqual" // ACSRouterLabelOperatorLess - < - AcsRouterLabelOperatorLess ACSRouterLabelOperator = "Less" + ACSRouterLabelOperatorLess ACSRouterLabelOperator = "Less" // ACSRouterLabelOperatorLessThanOrEqual - <= - AcsRouterLabelOperatorLessThanOrEqual ACSRouterLabelOperator = "LessThanOrEqual" + ACSRouterLabelOperatorLessThanOrEqual ACSRouterLabelOperator = "LessThanOrEqual" // ACSRouterLabelOperatorNotEqual - != - AcsRouterLabelOperatorNotEqual ACSRouterLabelOperator = "NotEqual" + ACSRouterLabelOperatorNotEqual ACSRouterLabelOperator = "NotEqual" ) -// PossibleACSRouterLabelOperatorValues returns the possible values for the ACSRouterLabelOperator const type. +// PossibleACSRouterLabelOperatorValues returns the possible values for the AcsRouterLabelOperator const type. func PossibleACSRouterLabelOperatorValues() []ACSRouterLabelOperator { return []ACSRouterLabelOperator{ - AcsRouterLabelOperatorEqual, - AcsRouterLabelOperatorGreater, - AcsRouterLabelOperatorGreaterThanOrEqual, - AcsRouterLabelOperatorLess, - AcsRouterLabelOperatorLessThanOrEqual, - AcsRouterLabelOperatorNotEqual, + ACSRouterLabelOperatorEqual, + ACSRouterLabelOperatorGreater, + ACSRouterLabelOperatorGreaterThanOrEqual, + ACSRouterLabelOperatorLess, + ACSRouterLabelOperatorLessThanOrEqual, + ACSRouterLabelOperatorNotEqual, } } @@ -109,25 +109,25 @@ func PossibleACSRouterLabelOperatorValues() []ACSRouterLabelOperator { type ACSRouterUpdatedWorkerProperty string const ( - AcsRouterUpdatedWorkerPropertyAvailableForOffers ACSRouterUpdatedWorkerProperty = "AvailableForOffers" - AcsRouterUpdatedWorkerPropertyChannelConfigurations ACSRouterUpdatedWorkerProperty = "ChannelConfigurations" - AcsRouterUpdatedWorkerPropertyLabels ACSRouterUpdatedWorkerProperty = "Labels" - AcsRouterUpdatedWorkerPropertyMaxConcurrentOffers ACSRouterUpdatedWorkerProperty = "MaxConcurrentOffers" - AcsRouterUpdatedWorkerPropertyQueueAssignments ACSRouterUpdatedWorkerProperty = "QueueAssignments" - AcsRouterUpdatedWorkerPropertyTags ACSRouterUpdatedWorkerProperty = "Tags" - AcsRouterUpdatedWorkerPropertyTotalCapacity ACSRouterUpdatedWorkerProperty = "TotalCapacity" + ACSRouterUpdatedWorkerPropertyAvailableForOffers ACSRouterUpdatedWorkerProperty = "AvailableForOffers" + ACSRouterUpdatedWorkerPropertyChannelConfigurations ACSRouterUpdatedWorkerProperty = "ChannelConfigurations" + ACSRouterUpdatedWorkerPropertyLabels ACSRouterUpdatedWorkerProperty = "Labels" + ACSRouterUpdatedWorkerPropertyMaxConcurrentOffers ACSRouterUpdatedWorkerProperty = "MaxConcurrentOffers" + ACSRouterUpdatedWorkerPropertyQueueAssignments ACSRouterUpdatedWorkerProperty = "QueueAssignments" + ACSRouterUpdatedWorkerPropertyTags ACSRouterUpdatedWorkerProperty = "Tags" + ACSRouterUpdatedWorkerPropertyTotalCapacity ACSRouterUpdatedWorkerProperty = "TotalCapacity" ) -// PossibleACSRouterUpdatedWorkerPropertyValues returns the possible values for the ACSRouterUpdatedWorkerProperty const type. +// PossibleACSRouterUpdatedWorkerPropertyValues returns the possible values for the AcsRouterUpdatedWorkerProperty const type. func PossibleACSRouterUpdatedWorkerPropertyValues() []ACSRouterUpdatedWorkerProperty { return []ACSRouterUpdatedWorkerProperty{ - AcsRouterUpdatedWorkerPropertyAvailableForOffers, - AcsRouterUpdatedWorkerPropertyChannelConfigurations, - AcsRouterUpdatedWorkerPropertyLabels, - AcsRouterUpdatedWorkerPropertyMaxConcurrentOffers, - AcsRouterUpdatedWorkerPropertyQueueAssignments, - AcsRouterUpdatedWorkerPropertyTags, - AcsRouterUpdatedWorkerPropertyTotalCapacity, + ACSRouterUpdatedWorkerPropertyAvailableForOffers, + ACSRouterUpdatedWorkerPropertyChannelConfigurations, + ACSRouterUpdatedWorkerPropertyLabels, + ACSRouterUpdatedWorkerPropertyMaxConcurrentOffers, + ACSRouterUpdatedWorkerPropertyQueueAssignments, + ACSRouterUpdatedWorkerPropertyTags, + ACSRouterUpdatedWorkerPropertyTotalCapacity, } } @@ -136,16 +136,16 @@ type ACSRouterWorkerSelectorState string const ( // ACSRouterWorkerSelectorStateActive - Router Job Worker Selector is Active - AcsRouterWorkerSelectorStateActive ACSRouterWorkerSelectorState = "active" + ACSRouterWorkerSelectorStateActive ACSRouterWorkerSelectorState = "active" // ACSRouterWorkerSelectorStateExpired - Router Job Worker Selector has Expire - AcsRouterWorkerSelectorStateExpired ACSRouterWorkerSelectorState = "expired" + ACSRouterWorkerSelectorStateExpired ACSRouterWorkerSelectorState = "expired" ) // PossibleACSRouterWorkerSelectorStateValues returns the possible values for the ACSRouterWorkerSelectorState const type. func PossibleACSRouterWorkerSelectorStateValues() []ACSRouterWorkerSelectorState { return []ACSRouterWorkerSelectorState{ - AcsRouterWorkerSelectorStateActive, - AcsRouterWorkerSelectorStateExpired, + ACSRouterWorkerSelectorStateActive, + ACSRouterWorkerSelectorStateExpired, } } @@ -153,15 +153,15 @@ func PossibleACSRouterWorkerSelectorStateValues() []ACSRouterWorkerSelectorState type ACSUserEngagement string const ( - AcsUserEngagementClick ACSUserEngagement = "click" - AcsUserEngagementView ACSUserEngagement = "view" + ACSUserEngagementClick ACSUserEngagement = "click" + ACSUserEngagementView ACSUserEngagement = "view" ) -// PossibleACSUserEngagementValues returns the possible values for the ACSUserEngagement const type. +// PossibleACSUserEngagementValues returns the possible values for the AcsUserEngagement const type. func PossibleACSUserEngagementValues() []ACSUserEngagement { return []ACSUserEngagement{ - AcsUserEngagementClick, - AcsUserEngagementView, + ACSUserEngagementClick, + ACSUserEngagementView, } } diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_enum.go b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_enum.go index 5485576a3786..22d716925858 100644 --- a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_enum.go +++ b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_enum.go @@ -18,6 +18,8 @@ import ( "regexp" "sort" "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/messaging/eventgrid/azsystemevents/internal/gopls" ) var filesToDelete = []string{ @@ -62,7 +64,11 @@ func main() { case "download": err = writeEventFiles() case "generate": - err = generateConstants() + err = fixPrefixes() + + if err == nil { + err = generateSystemEventEnum() + } case "validate": var m map[string]bool m, err = readLines(pyOutputPath) @@ -160,7 +166,7 @@ func writeEventFiles() error { return nil } -func generateConstants() error { +func generateSystemEventEnum() error { reader, err := os.Open(goModelsFile) if err != nil { @@ -404,3 +410,185 @@ func cutPrefix(s, prefix string) (after string, found bool) { } return s[len(prefix):], true } + +type rename struct { + Orig gopls.Symbol + New string + FileName string +} + +func fixPrefixes() error { + constantSyms, err := gopls.TypeSymbols("constants.go") + + if err != nil { + return err + } + + modelsSyms, err := gopls.TypeSymbols("models.go") + + if err != nil { + return err + } + + constantRepls := getConstantsGoReplacements(constantSyms) + modelRepls := getModelsReplacements(modelsSyms) + + total := len(constantRepls) + len(modelRepls) + + for i, repl := range constantRepls { + fmt.Printf("%s[%d/%d]: %s -> %s\n", repl.FileName, i+1, total, repl.Orig.Name, repl.New) + if err := gopls.Rename(repl.FileName, repl.Orig, repl.New); err != nil { + return err + } + } + + for i, repl := range modelRepls { + idx := i + 1 + len(constantRepls) + fmt.Printf("%s[%d/%d]: %s -> %s\n", repl.FileName, idx, total, repl.Orig.Name, repl.New) + if err := gopls.Rename(repl.FileName, repl.Orig, repl.New); err != nil { + return err + } + } + + { + // one annoyance here is that if the type name is not a doc reference (like [typename]) then + // it doesn't get renamed, so we'll have to fix up the comments on our own. + modelsSerdeBytes, err := os.ReadFile("models_serde.go") + + if err != nil { + return err + } + + constantsBytes, err := os.ReadFile("constants.go") + + if err != nil { + return err + } + + for _, repl := range modelRepls { + modelsSerdeBytes = bytes.Replace(modelsSerdeBytes, []byte(repl.Orig.Name), []byte(repl.New), -1) + constantsBytes = bytes.Replace(constantsBytes, []byte(repl.Orig.Name), []byte(repl.New), -1) + } + + if err := os.WriteFile("models_serde.go", modelsSerdeBytes, 0700); err != nil { + return err + } + + if err := os.WriteFile("constants.go", constantsBytes, 0700); err != nil { + return err + } + } + + return nil +} + +func getConstantsGoReplacements(syms map[string]gopls.Symbol) []rename { + typeRE := regexp.MustCompile(`^(Acs|Avs|Iot)([A-Za-z0-9]+)$`) + possibleRE := regexp.MustCompile(`^(Possible)(Acs|Avs|Iot)([A-Za-z0-9]+)$`) + + var renames []rename + + for k, sym := range syms { + matches := typeRE.FindStringSubmatch(k) + + if matches != nil { + renames = append(renames, rename{ + FileName: "constants.go", + Orig: sym, + New: strings.ToUpper(matches[1]) + matches[2], + }) + } + + matches = possibleRE.FindStringSubmatch(k) + + if matches != nil { + renames = append(renames, rename{ + FileName: "constants.go", + Orig: sym, + New: matches[1] + strings.ToUpper(matches[2]) + matches[3], + }) + } + } + + sort.Slice(renames, func(i, j int) bool { + return renames[i].New < renames[j].New + }) + return renames +} + +func getModelsReplacements(syms map[string]gopls.Symbol) []rename { + typeRE := regexp.MustCompile(`^(Acs|Avs|Iot)([A-Za-z0-9]+)$`) + + var renames []rename + + for k, sym := range syms { + matches := typeRE.FindStringSubmatch(k) + + if matches != nil { + renames = append(renames, rename{ + FileName: "models.go", + Orig: sym, + New: strings.ToUpper(matches[1]) + matches[2], + }) + } + } + + return renames +} + +// func renameModels() error { +// const filepath = "models.go" +// syms, err := gopls.TypeSymbols(filepath) + +// if err != nil { +// return err +// } + +// modelsSerdeBytes, err := os.ReadFile("models_serde.go") + +// if err != nil { +// return err +// } + +// // there are some comments that linger after refactor that we need to touch up as well. +// // TODO: in the future we can wrap the type names in [] and the go refactor tool will do the +// // rename for us! +// constantsBytes, err := os.ReadFile("constants.go") + +// if err != nil { +// return err +// } + +// typeRE := regexp.MustCompile(`^(Acs|Avs|Iot)([A-Za-z0-9]+)$`) + +// for k, sym := range syms { +// matches := typeRE.FindStringSubmatch(k) + +// if matches != nil { +// repl := strings.ToUpper(matches[1]) + matches[2] + +// fmt.Printf("Renaming %s -> %s\n", sym.Name, repl) + +// err := gopls.Rename(filepath, sym, repl) + +// if err != nil { +// return err +// } + +// // one annoyance here is that if the type name is not a doc reference (like [typename]) then +// // it doesn't get renamed, so we'll have to fix up the comments on our own. +// modelsSerdeBytes = bytes.Replace(modelsSerdeBytes, []byte(sym.Name), []byte(repl), -1) +// constantsBytes = bytes.Replace(constantsBytes, []byte(sym.Name), []byte(repl), -1) +// } +// } + +// if err := os.WriteFile("models_serde.go", modelsSerdeBytes, 0700); err != nil { +// return err +// } + +// if err := os.WriteFile("constants.go", constantsBytes, 0700); err != nil { +// return err +// } + +// return nil +// } diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/gopls/gopls.go b/sdk/messaging/eventgrid/azsystemevents/internal/gopls/gopls.go new file mode 100644 index 000000000000..fea0bf658193 --- /dev/null +++ b/sdk/messaging/eventgrid/azsystemevents/internal/gopls/gopls.go @@ -0,0 +1,89 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package gopls + +import ( + "bufio" + "bytes" + "fmt" + "os" + "os/exec" + "strings" +) + +type Symbol struct { + Name string + Type string + Position string +} + +func Rename(filename string, sym Symbol, newName string) error { + cmd := exec.Command("gopls", "rename", "-w", filename+":"+sym.Position, newName) + + if err := cmd.Run(); err != nil { + return err + } + + return nil +} + +func TypeSymbols(filename string) (map[string]Symbol, error) { + if _, err := os.Stat(filename); err != nil { + return nil, err + } + + // ex: PossibleRecordingChannelTypeValues Function 1003:6-1003:40 + cmd := exec.Command("gopls", "symbols", filename) + stdout := &bytes.Buffer{} + cmd.Stdout = stdout + cmd.Stderr = os.Stderr + + if err := cmd.Run(); err != nil { + return nil, err + } + + allBytes := stdout.Bytes() + + scanner := bufio.NewScanner(bytes.NewReader(allBytes)) + + m := map[string]Symbol{} + + for scanner.Scan() { + // ex: + // + // Top level types are listed like this: + // RecordingFormatTypeMp3 Constant 1030:2-1030:24 + // + // Fields are listed like this - skipping those for now since I'm mostly concerned with + // renaming types. + // Address Field 5379:2-5379:9 + + if len(scanner.Text()) > 0 && scanner.Text()[0] == '\t' { + continue + } + + fields := strings.Split(scanner.Text(), " ") + + if len(fields) != 3 { + return nil, fmt.Errorf("failed to parse %q into three fields, got %d", scanner.Text(), len(fields)) + } + + sym := Symbol{ + Name: fields[0], + Type: fields[1], + Position: fields[2], + } + + if _, exists := m[sym.Name]; exists { + return nil, fmt.Errorf("%s was in the map twice", sym.Name) + } + + m[sym.Name] = sym + } + + return m, nil +} diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/version.go b/sdk/messaging/eventgrid/azsystemevents/internal/version.go index d5c908fb3af5..13c31dc4c774 100644 --- a/sdk/messaging/eventgrid/azsystemevents/internal/version.go +++ b/sdk/messaging/eventgrid/azsystemevents/internal/version.go @@ -9,5 +9,5 @@ const ( ModuleName = "azsystemevents" // ModuleVersion is the semantic version (see http://semver.org) of this module. - ModuleVersion = "v0.2.0" + ModuleVersion = "v0.2.1" ) diff --git a/sdk/messaging/eventgrid/azsystemevents/system_events2_test.go b/sdk/messaging/eventgrid/azsystemevents/system_events2_test.go index 3ac97906e28e..9f2d74d6f71d 100644 --- a/sdk/messaging/eventgrid/azsystemevents/system_events2_test.go +++ b/sdk/messaging/eventgrid/azsystemevents/system_events2_test.go @@ -1417,7 +1417,7 @@ func TestConsumeAcsEmailDeliveryReportReceivedEvent(t *testing.T) { emailEvent := deserializeSystemEvent[azsystemevents.ACSEmailDeliveryReportReceivedEventData](t, event.Data) require.Equal(t, "test2@contoso.org", *emailEvent.Sender) require.Equal(t, "test1@contoso.com", *emailEvent.Recipient) - require.Equal(t, azsystemevents.AcsEmailDeliveryReportStatusDelivered, *emailEvent.Status) + require.Equal(t, azsystemevents.ACSEmailDeliveryReportStatusDelivered, *emailEvent.Status) require.Equal(t, "DestinationMailboxFull", *emailEvent.DeliveryStatusDetails.StatusMessage) require.Equal(t, mustParseTime(t, "2023-02-09T19:46:12.2480265+00:00"), *emailEvent.DeliveryAttemptTimestamp) } diff --git a/sdk/messaging/eventgrid/azsystemevents/system_events4_test.go b/sdk/messaging/eventgrid/azsystemevents/system_events4_test.go index 9b4959b09e4b..228adf99b012 100644 --- a/sdk/messaging/eventgrid/azsystemevents/system_events4_test.go +++ b/sdk/messaging/eventgrid/azsystemevents/system_events4_test.go @@ -867,7 +867,7 @@ func TestConsumeCloudEventAcsEmailDeliveryReportReceivedEvent(t *testing.T) { sysEvent := deserializeSystemEvent[azsystemevents.ACSEmailDeliveryReportReceivedEventData](t, event.Data) require.Equal(t, "test2@contoso.org", *sysEvent.Sender) require.Equal(t, "test1@contoso.com", *sysEvent.Recipient) - require.Equal(t, azsystemevents.AcsEmailDeliveryReportStatusDelivered, *sysEvent.Status) + require.Equal(t, azsystemevents.ACSEmailDeliveryReportStatusDelivered, *sysEvent.Status) require.Equal(t, "DestinationMailboxFull", *sysEvent.DeliveryStatusDetails.StatusMessage) require.Equal(t, mustParseTime(t, "2023-02-09T19:46:12.2480265+00:00"), *sysEvent.DeliveryAttemptTimestamp) } diff --git a/sdk/messaging/eventgrid/azsystemevents/system_events5_test.go b/sdk/messaging/eventgrid/azsystemevents/system_events5_test.go index 04bde3713796..760e86c79c14 100644 --- a/sdk/messaging/eventgrid/azsystemevents/system_events5_test.go +++ b/sdk/messaging/eventgrid/azsystemevents/system_events5_test.go @@ -67,11 +67,11 @@ func TestConsumeCloudEventAcsRouterJobQueuedEvent(t *testing.T) { require.Equal(t, 1, len(selectors)) require.Equal(t, float32(1000), *selectors[0].TimeToLive) - require.Equal(t, azsystemevents.AcsRouterLabelOperatorEqual, *selectors[0].LabelOperator) + require.Equal(t, azsystemevents.ACSRouterLabelOperatorEqual, *selectors[0].LabelOperator) // TODO: might have been a field rename? //require.Equal(t, azsystemevents.AcsRouterLabelOperatorEqual, selectors[0].Operator) - require.Equal(t, azsystemevents.AcsRouterWorkerSelectorStateActive, *selectors[0].State) + require.Equal(t, azsystemevents.ACSRouterWorkerSelectorStateActive, *selectors[0].State) // TODO: might have been a field rename? //require.Equal(t, azsystemevents.AcsRouterWorkerSelectorStateActive, selectors[0].SelectorState) } @@ -121,7 +121,7 @@ func TestConsumeCloudEventAcsRouterJobReceivedEvent(t *testing.T) { event := parseCloudEvent(t, requestContent) sysEvent := deserializeSystemEvent[azsystemevents.ACSRouterJobReceivedEventData](t, event.Data) - require.Equal(t, azsystemevents.AcsRouterJobStatusPendingClassification, *sysEvent.JobStatus) + require.Equal(t, azsystemevents.ACSRouterJobStatusPendingClassification, *sysEvent.JobStatus) // TODO: don't have a .Status field? //require.Equal(t, Azure.Messaging.EventGrid.azsystemevents.AcsRouterJobStatus.PendingClassification, sysEvent.Status) From 119270281616830527d2b86075707f8506e625ab Mon Sep 17 00:00:00 2001 From: ripark Date: Fri, 22 Mar 2024 01:30:33 +0000 Subject: [PATCH 04/12] Cleaning things up a bit more, fixing InnerError --- .../eventgrid/azsystemevents/build.go | 2 +- .../internal/generate/generate.go | 379 +++++++++++ .../internal/generate/generate_enum.go | 594 ------------------ .../azsystemevents/internal/gopls/gopls.go | 33 +- .../eventgrid/azsystemevents/models.go | 2 +- .../eventgrid/azsystemevents/models_serde.go | 4 +- 6 files changed, 411 insertions(+), 603 deletions(-) create mode 100644 sdk/messaging/eventgrid/azsystemevents/internal/generate/generate.go delete mode 100644 sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_enum.go diff --git a/sdk/messaging/eventgrid/azsystemevents/build.go b/sdk/messaging/eventgrid/azsystemevents/build.go index d970c45fcfa1..8a4766377468 100644 --- a/sdk/messaging/eventgrid/azsystemevents/build.go +++ b/sdk/messaging/eventgrid/azsystemevents/build.go @@ -6,7 +6,7 @@ //go:generate autorest ./autorest.md //go:generate goimports -w ./.. -//go:generate go run ./internal/generate generate +//go:generate go run ./internal/generate //go:generate goimports -w ./.. package azsystemevents diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate.go b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate.go new file mode 100644 index 000000000000..c150a8adcd9a --- /dev/null +++ b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate.go @@ -0,0 +1,379 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package main + +import ( + "bufio" + "bytes" + "fmt" + "io" + "log" + "os" + "regexp" + "sort" + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/messaging/eventgrid/azsystemevents/internal/gopls" +) + +var filesToDelete = []string{ + "options.go", + "responses.go", + "clientdeleteme_client.go", +} + +const systemEventsGoFile = "system_events.go" +const modelsGoFile = "models.go" +const constantsGoFile = "constants.go" + +const header = `//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azsystemevents + +// Type represents the value set in EventData.EventType or messaging.CloudEvent.Type +// for system events. +type Type string + +const ( +` + +const footer = `)` + +func main() { + fn := func() error { + if err := doRenames(); err != nil { + return err + } + + if err := generateSystemEventEnum(); err != nil { + return err + } + + deleteUnneededFiles() + return nil + } + + if err := fn(); err != nil { + fmt.Printf("Failed with error: %s\n", err) + os.Exit(1) + } + + fmt.Printf("DONE\n") +} + +func generateSystemEventEnum() error { + reader, err := os.Open(modelsGoFile) + + if err != nil { + return fmt.Errorf("Failed to open %s: %w", modelsGoFile, err) + } + + defer reader.Close() + + constants, err := getConstantValues(reader) + + if err != nil { + return fmt.Errorf("Failed to get constant values from file: %w", err) + } + + if err := writeConstantsFile(systemEventsGoFile, constants); err != nil { + log.Fatalf("Failed to write constants file %s: %s", systemEventsGoFile, err) + } + + return nil +} + +func deleteUnneededFiles() { + // we don't need these files since we're (intentionally) not exporting a Client from this + // package. + fmt.Printf("Deleting unneeded files\n") + + for _, file := range filesToDelete { + fmt.Printf("Deleting %s since it only has client types\n", file) + if _, err := os.Stat(file); err == nil { + _ = os.Remove(file) + } + } +} + +type constant struct { + ConstantName string + GoType string + ConstantValue string +} + +func getConstantValues(reader io.ReadCloser) (map[string]constant, error) { + data, err := io.ReadAll(reader) + + if err != nil { + return nil, err + } + + scanner := bufio.NewScanner(bytes.NewReader(data)) + + var currentComment []string + + var comments []struct { + Text string + ForType string + } + + for scanner.Scan() { + line := scanner.Text() + + if commentText, found := cutPrefix(line, "// "); found { + currentComment = append(currentComment, commentText) + } else if len(currentComment) > 0 && strings.HasPrefix(line, "type ") { + comments = append(comments, struct { + Text string + ForType string + }{ + Text: strings.Join(currentComment, " "), + ForType: strings.Split(line, " ")[1], + }) + currentComment = nil + } + } + + consts := map[string]constant{} + // ex: 'StorageBlobCreatedEventData - Schema of the Data property of an Event for a Microsoft.Storage.BlobCreated event.' + // 'IotHubDeviceConnectedEventData - Event data for Microsoft.Devices.DeviceConnected event.' + typeRE := regexp.MustCompile(`([^ ]+) -.+?([A-Za-z0-9]+(?:\.[A-Za-z0-9]+){2,3})`) + + ignoredTypes := []string{ + "DeviceConnectionStateEventProperties", + "DeviceLifeCycleEventProperties", + "DeviceTelemetryEventProperties", + "EventGridMQTTClientEventData", + "MapsGeofenceEventProperties", + } + + for _, comment := range comments { + matches := typeRE.FindStringSubmatch(comment.Text) + + if strings.Contains(comment.Text, "Schema of the Data") && len(matches) == 0 { + ignorable := false + + // we have a few types that we can ignore - they're not top-level SystemEvents (they're + // embedded or used by other events). + for _, prefix := range ignoredTypes { + if strings.HasPrefix(comment.Text, prefix) { + ignorable = true + break + } + } + + if !ignorable { + log.Printf("===========> DIDN'T MATCH REGEX: %q ", comment) + } + } + + if len(matches) == 0 { + continue + } + + goTypeName, stringValue := matches[1], matches[2] + constantName := strings.Replace(goTypeName, "EventData", "", 1) + + consts[stringValue] = constant{ + ConstantName: "Type" + constantName, + GoType: goTypeName, + ConstantValue: stringValue, + } + } + + return consts, nil +} + +func writeConstantsFile(path string, constants map[string]constant) error { + writer, err := os.Create(path) + + if err != nil { + return err + } + + defer writer.Close() + + if _, err := writer.Write([]byte(header)); err != nil { + return err + } + + for _, key := range sortedKeys(constants) { + c := constants[key] + + // ex: + // TypeAPIManagementAPICreated Type = "Microsoft.ApiManagement.APICreated" // maps to APIManagementAPICreatedEventData + buff := fmt.Sprintf("%s Type = \"%s\" // maps to %s\n", c.ConstantName, c.ConstantValue, c.GoType) + _, err := writer.WriteString(buff) + + if err != nil { + return err + } + } + + if _, err := writer.Write([]byte(footer)); err != nil { + return err + } + + return nil +} + +func sortedKeys[T any](m map[string]T) []string { + var keys []string + for k := range m { + keys = append(keys, k) + } + + sort.Strings(keys) + return keys +} + +// copy of strings.CutPrefix, which doesn't exist in our oldest support compiler (1.18) +func cutPrefix(s, prefix string) (after string, found bool) { + if !strings.HasPrefix(s, prefix) { + return s, false + } + return s[len(prefix):], true +} + +type rename struct { + Orig gopls.Symbol + New string + FileName string +} + +func doRenames() error { + constantSyms, err := gopls.Symbols(constantsGoFile) + + if err != nil { + return err + } + + modelsSyms, err := gopls.Symbols(modelsGoFile) + + if err != nil { + return err + } + + phase1Repls := getConstantsReplacements(constantSyms) + + phase1Repls = append(phase1Repls, rename{ + FileName: "models.go", + Orig: modelsSyms["AcsRouterCommunicationError.Innererror"], + New: "InnerError", + }) + + modelRepls := getModelsReplacements(modelsSyms) + + total := len(phase1Repls) + len(modelRepls) + + for i, repl := range phase1Repls { + fmt.Printf("%s[%d/%d]: %s -> %s\n", repl.FileName, i+1, total, repl.Orig.Name, repl.New) + if err := gopls.Rename(repl.FileName, repl.Orig, repl.New); err != nil { + return err + } + } + + for i, repl := range modelRepls { + idx := 1 + i + len(phase1Repls) + fmt.Printf("%s[%d/%d]: %s -> %s\n", repl.FileName, idx, total, repl.Orig.Name, repl.New) + if err := gopls.Rename(repl.FileName, repl.Orig, repl.New); err != nil { + return err + } + } + + return fixComments(modelRepls) +} + +func fixComments(modelRepls []rename) error { + // one annoyance here is that if the type name is not a doc reference (like [typename]) then + // it doesn't get renamed, so we'll have to fix up the comments on our own. + modelsSerdeBytes, err := os.ReadFile("models_serde.go") + + if err != nil { + return err + } + + constantsBytes, err := os.ReadFile(constantsGoFile) + + if err != nil { + return err + } + + for _, repl := range modelRepls { + modelsSerdeBytes = bytes.Replace(modelsSerdeBytes, []byte(repl.Orig.Name), []byte(repl.New), -1) + constantsBytes = bytes.Replace(constantsBytes, []byte(repl.Orig.Name), []byte(repl.New), -1) + } + + if err := os.WriteFile("models_serde.go", modelsSerdeBytes, 0700); err != nil { + return err + } + + return os.WriteFile(constantsGoFile, constantsBytes, 0700) +} + +func getConstantsReplacements(syms map[string]gopls.Symbol) []rename { + typeRE := regexp.MustCompile(`^(Acs|Avs|Iot)([A-Za-z0-9]+)$`) + possibleRE := regexp.MustCompile(`^(Possible)(Acs|Avs|Iot)([A-Za-z0-9]+)$`) + + var renames []rename + + for k, sym := range syms { + matches := typeRE.FindStringSubmatch(k) + + if matches != nil { + renames = append(renames, rename{ + FileName: constantsGoFile, + Orig: sym, + New: strings.ToUpper(matches[1]) + matches[2], + }) + } + + matches = possibleRE.FindStringSubmatch(k) + + if matches != nil { + renames = append(renames, rename{ + FileName: constantsGoFile, + Orig: sym, + New: matches[1] + strings.ToUpper(matches[2]) + matches[3], + }) + } + } + + sort.Slice(renames, func(i, j int) bool { + return renames[i].New < renames[j].New + }) + return renames +} + +func getModelsReplacements(syms map[string]gopls.Symbol) []rename { + typeRE := regexp.MustCompile(`^(Acs|Avs|Iot)([A-Za-z0-9]+)$`) + + var renames []rename + + for k, sym := range syms { + matches := typeRE.FindStringSubmatch(k) + + if matches != nil { + renames = append(renames, rename{ + FileName: modelsGoFile, + Orig: sym, + New: strings.ToUpper(matches[1]) + matches[2], + }) + } + } + + sort.Slice(renames, func(i, j int) bool { + return renames[i].Orig.Name < renames[j].Orig.Name + }) + + return renames +} diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_enum.go b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_enum.go deleted file mode 100644 index 22d716925858..000000000000 --- a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_enum.go +++ /dev/null @@ -1,594 +0,0 @@ -//go:build go1.18 -// +build go1.18 - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -package main - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "io" - "log" - "net/http" - "os" - "regexp" - "sort" - "strings" - - "github.com/Azure/azure-sdk-for-go/sdk/messaging/eventgrid/azsystemevents/internal/gopls" -) - -var filesToDelete = []string{ - "options.go", - "responses.go", - "clientdeleteme_client.go", -} - -const systemEventsPath = "system_events.go" -const goModelsFile = "models.go" - -const tsOutputPath = "./internal/generate/testdata/tsevents.txt" -const javaOutputPath = "./internal/generate/testdata/javaevents.txt" -const pyOutputPath = "./internal/generate/testdata/pyevents.txt" -const goOutputPath = "./internal/generate/testdata/goevents.txt" - -const header = `//go:build go1.18 -// +build go1.18 - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -package azsystemevents - -// Type represents the value set in EventData.EventType or messaging.CloudEvent.Type -// for system events. -type Type string - -const ( -` - -const footer = `)` - -func main() { - if len(os.Args) < 2 { - fmt.Printf("Usage: generate_system_events (generate|validate|download)") - os.Exit(1) - } - - var err error - switch os.Args[1] { - case "download": - err = writeEventFiles() - case "generate": - err = fixPrefixes() - - if err == nil { - err = generateSystemEventEnum() - } - case "validate": - var m map[string]bool - m, err = readLines(pyOutputPath) - - if err != nil { - break - } - - err = validateAgainstAnotherLang(m) - default: - err = errors.New(os.Args[1] + " is not a valid command") - } - - if err != nil { - log.Fatalf("Failed with error: %s", err) - } -} - -func downloadEventTypes(url string, lineRE *regexp.Regexp, outputFile string) error { - resp, err := http.Get(url) - - if err != nil { - return err - } - - defer resp.Body.Close() - - return writeEvents(resp.Body, lineRE, outputFile) -} - -func writeEvents(reader io.Reader, lineRE *regexp.Regexp, outputPath string) error { - scanner := bufio.NewScanner(reader) - - allMatches := map[string]bool{} - - for scanner.Scan() { - matches := lineRE.FindStringSubmatch(scanner.Text()) - - if len(matches) == 0 { - continue - } - allMatches[matches[1]] = true - } - - writer, err := os.Create(outputPath) - - if err != nil { - return err - } - - defer writer.Close() - - for _, key := range sortedKeys(allMatches) { - if _, err := writer.WriteString(fmt.Sprintf("%s\n", key)); err != nil { - return err - } - } - - return nil -} - -func writeEventFiles() error { - err := downloadEventTypes("https://raw.githubusercontent.com/Azure/azure-sdk-for-js/main/sdk/eventgrid/eventgrid/src/predicates.ts", regexp.MustCompile(`^\s+"([^"]+)"`), tsOutputPath) - - if err != nil { - return err - } - - err = downloadEventTypes("https://raw.githubusercontent.com/Azure/azure-sdk-for-java/main/sdk/eventgrid/azure-messaging-eventgrid/src/main/java/com/azure/messaging/eventgrid/SystemEventNames.java", regexp.MustCompile(`"([^"]+?)"`), javaOutputPath) - - if err != nil { - return err - } - - err = downloadEventTypes("https://raw.githubusercontent.com/Azure/azure-sdk-for-python/main/sdk/eventgrid/azure-eventgrid/azure/eventgrid/_event_mappings.py", regexp.MustCompile(`^.+ = '([^']+)'`), pyOutputPath) - - if err != nil { - return err - } - - reader, err := os.Open(goModelsFile) - - if err != nil { - return err - } - - defer reader.Close() - - err = writeEvents(reader, regexp.MustCompile(`([A-Za-z0-9]+(?:\.[A-Za-z0-9]+){2,3})`), goOutputPath) - - if err != nil { - return err - } - - return nil -} - -func generateSystemEventEnum() error { - reader, err := os.Open(goModelsFile) - - if err != nil { - return fmt.Errorf("Failed to open %s: %w", goModelsFile, err) - } - - defer reader.Close() - - constants, err := getConstantValues(reader) - - if err != nil { - return fmt.Errorf("Failed to get constant values from file: %w", err) - } - - if err := writeConstantsFile(systemEventsPath, constants); err != nil { - log.Fatalf("Failed to write constants file %s: %s", systemEventsPath, err) - } - - // we don't need these files since we're (intentionally) not exporting a Client from this - // package. - log.Printf("Deleting unneeded files\n") - - for _, file := range filesToDelete { - log.Printf("Deleting %s since it only has client types", file) - if _, err := os.Stat(file); err == nil { - if err := os.Remove(file); err != nil { - return err - } - } - } - - return nil -} - -func validateAgainstAnotherLang(otherLang map[string]bool) error { - reader, err := os.Open(goModelsFile) - - if err != nil { - return err - } - - defer reader.Close() - - consts, err := getConstantValues(reader) - - if err != nil { - return err - } - - constsMap := map[string]constant{} - - for _, c := range consts { - constsMap[c.ConstantValue] = c - } - - var missingConstants []string - - // now cross-check our generated models against the models that we _should_ have - // if we are caught up to the latest production Event Grid package for Java. - for value := range otherLang { - if _, ok := constsMap[value]; !ok { - - // there are some events that were deprecated - if value == "Microsoft.Communication.ChatMemberAddedToThreadWithUser" || value == "Microsoft.Communication.ChatMemberRemovedFromThreadWithUser" { - continue - } - - // we're missing a value! - missingConstants = append(missingConstants, value) - } - } - - if len(missingConstants) > 0 { - sort.Strings(missingConstants) - return errors.New("Missing constants:\n" + strings.Join(missingConstants, "\n")) - } - - return nil -} - -type constant struct { - ConstantName string - GoType string - ConstantValue string -} - -func getConstantValues(reader io.ReadCloser) (map[string]constant, error) { - data, err := io.ReadAll(reader) - - if err != nil { - return nil, err - } - - scanner := bufio.NewScanner(bytes.NewReader(data)) - - var currentComment []string - - var comments []struct { - Text string - ForType string - } - - for scanner.Scan() { - line := scanner.Text() - - if commentText, found := cutPrefix(line, "// "); found { - currentComment = append(currentComment, commentText) - } else if len(currentComment) > 0 && strings.HasPrefix(line, "type ") { - comments = append(comments, struct { - Text string - ForType string - }{ - Text: strings.Join(currentComment, " "), - ForType: strings.Split(line, " ")[1], - }) - currentComment = nil - } - } - - consts := map[string]constant{} - // ex: 'StorageBlobCreatedEventData - Schema of the Data property of an Event for a Microsoft.Storage.BlobCreated event.' - // 'IotHubDeviceConnectedEventData - Event data for Microsoft.Devices.DeviceConnected event.' - typeRE := regexp.MustCompile(`([^ ]+) -.+?([A-Za-z0-9]+(?:\.[A-Za-z0-9]+){2,3})`) - - ignoredTypes := []string{ - "DeviceConnectionStateEventProperties", - "DeviceLifeCycleEventProperties", - "DeviceTelemetryEventProperties", - "EventGridMQTTClientEventData", - "MapsGeofenceEventProperties", - } - - for _, comment := range comments { - matches := typeRE.FindStringSubmatch(comment.Text) - - if strings.Contains(comment.Text, "Schema of the Data") && len(matches) == 0 { - ignorable := false - - // we have a few types that we can ignore - they're not top-level SystemEvents (they're - // embedded or used by other events). - for _, prefix := range ignoredTypes { - if strings.HasPrefix(comment.Text, prefix) { - ignorable = true - break - } - } - - if !ignorable { - log.Printf("===========> DIDN'T MATCH REGEX: %q ", comment) - } - } - - if len(matches) == 0 { - continue - } - - goTypeName, stringValue := matches[1], matches[2] - constantName := strings.Replace(goTypeName, "EventData", "", 1) - - consts[stringValue] = constant{ - ConstantName: "Type" + constantName, - GoType: goTypeName, - ConstantValue: stringValue, - } - } - - return consts, nil -} - -func writeConstantsFile(path string, constants map[string]constant) error { - writer, err := os.Create(path) - - if err != nil { - return err - } - - defer writer.Close() - - if _, err := writer.Write([]byte(header)); err != nil { - return err - } - - for _, key := range sortedKeys(constants) { - c := constants[key] - - // ex: - // TypeAPIManagementAPICreated Type = "Microsoft.ApiManagement.APICreated" // maps to APIManagementAPICreatedEventData - buff := fmt.Sprintf("%s Type = \"%s\" // maps to %s\n", c.ConstantName, c.ConstantValue, c.GoType) - _, err := writer.WriteString(buff) - - if err != nil { - return err - } - } - - if _, err := writer.Write([]byte(footer)); err != nil { - return err - } - - return nil -} - -func sortedKeys[T any](m map[string]T) []string { - var keys []string - for k := range m { - keys = append(keys, k) - } - - sort.Strings(keys) - return keys -} - -func readLines(path string) (map[string]bool, error) { - reader, err := os.Open(path) - - if err != nil { - return nil, err - } - - scanner := bufio.NewScanner(reader) - - m := map[string]bool{} - - for scanner.Scan() { - m[scanner.Text()] = true - } - - return m, nil -} - -/** -"ServiceBusDeadletterMessagesAvailableWithNoListenersEventData" => "ServiceBusDeadletterMessagesAvailableWithNoListener", -"SubscriptionDeletedEventData" => "EventGridSubscriptionDeleted", -"SubscriptionValidationEventData" => "EventGridSubscriptionValidation", -*/ - -// copy of strings.CutPrefix, which doesn't exist in our oldest support compiler (1.18) -func cutPrefix(s, prefix string) (after string, found bool) { - if !strings.HasPrefix(s, prefix) { - return s, false - } - return s[len(prefix):], true -} - -type rename struct { - Orig gopls.Symbol - New string - FileName string -} - -func fixPrefixes() error { - constantSyms, err := gopls.TypeSymbols("constants.go") - - if err != nil { - return err - } - - modelsSyms, err := gopls.TypeSymbols("models.go") - - if err != nil { - return err - } - - constantRepls := getConstantsGoReplacements(constantSyms) - modelRepls := getModelsReplacements(modelsSyms) - - total := len(constantRepls) + len(modelRepls) - - for i, repl := range constantRepls { - fmt.Printf("%s[%d/%d]: %s -> %s\n", repl.FileName, i+1, total, repl.Orig.Name, repl.New) - if err := gopls.Rename(repl.FileName, repl.Orig, repl.New); err != nil { - return err - } - } - - for i, repl := range modelRepls { - idx := i + 1 + len(constantRepls) - fmt.Printf("%s[%d/%d]: %s -> %s\n", repl.FileName, idx, total, repl.Orig.Name, repl.New) - if err := gopls.Rename(repl.FileName, repl.Orig, repl.New); err != nil { - return err - } - } - - { - // one annoyance here is that if the type name is not a doc reference (like [typename]) then - // it doesn't get renamed, so we'll have to fix up the comments on our own. - modelsSerdeBytes, err := os.ReadFile("models_serde.go") - - if err != nil { - return err - } - - constantsBytes, err := os.ReadFile("constants.go") - - if err != nil { - return err - } - - for _, repl := range modelRepls { - modelsSerdeBytes = bytes.Replace(modelsSerdeBytes, []byte(repl.Orig.Name), []byte(repl.New), -1) - constantsBytes = bytes.Replace(constantsBytes, []byte(repl.Orig.Name), []byte(repl.New), -1) - } - - if err := os.WriteFile("models_serde.go", modelsSerdeBytes, 0700); err != nil { - return err - } - - if err := os.WriteFile("constants.go", constantsBytes, 0700); err != nil { - return err - } - } - - return nil -} - -func getConstantsGoReplacements(syms map[string]gopls.Symbol) []rename { - typeRE := regexp.MustCompile(`^(Acs|Avs|Iot)([A-Za-z0-9]+)$`) - possibleRE := regexp.MustCompile(`^(Possible)(Acs|Avs|Iot)([A-Za-z0-9]+)$`) - - var renames []rename - - for k, sym := range syms { - matches := typeRE.FindStringSubmatch(k) - - if matches != nil { - renames = append(renames, rename{ - FileName: "constants.go", - Orig: sym, - New: strings.ToUpper(matches[1]) + matches[2], - }) - } - - matches = possibleRE.FindStringSubmatch(k) - - if matches != nil { - renames = append(renames, rename{ - FileName: "constants.go", - Orig: sym, - New: matches[1] + strings.ToUpper(matches[2]) + matches[3], - }) - } - } - - sort.Slice(renames, func(i, j int) bool { - return renames[i].New < renames[j].New - }) - return renames -} - -func getModelsReplacements(syms map[string]gopls.Symbol) []rename { - typeRE := regexp.MustCompile(`^(Acs|Avs|Iot)([A-Za-z0-9]+)$`) - - var renames []rename - - for k, sym := range syms { - matches := typeRE.FindStringSubmatch(k) - - if matches != nil { - renames = append(renames, rename{ - FileName: "models.go", - Orig: sym, - New: strings.ToUpper(matches[1]) + matches[2], - }) - } - } - - return renames -} - -// func renameModels() error { -// const filepath = "models.go" -// syms, err := gopls.TypeSymbols(filepath) - -// if err != nil { -// return err -// } - -// modelsSerdeBytes, err := os.ReadFile("models_serde.go") - -// if err != nil { -// return err -// } - -// // there are some comments that linger after refactor that we need to touch up as well. -// // TODO: in the future we can wrap the type names in [] and the go refactor tool will do the -// // rename for us! -// constantsBytes, err := os.ReadFile("constants.go") - -// if err != nil { -// return err -// } - -// typeRE := regexp.MustCompile(`^(Acs|Avs|Iot)([A-Za-z0-9]+)$`) - -// for k, sym := range syms { -// matches := typeRE.FindStringSubmatch(k) - -// if matches != nil { -// repl := strings.ToUpper(matches[1]) + matches[2] - -// fmt.Printf("Renaming %s -> %s\n", sym.Name, repl) - -// err := gopls.Rename(filepath, sym, repl) - -// if err != nil { -// return err -// } - -// // one annoyance here is that if the type name is not a doc reference (like [typename]) then -// // it doesn't get renamed, so we'll have to fix up the comments on our own. -// modelsSerdeBytes = bytes.Replace(modelsSerdeBytes, []byte(sym.Name), []byte(repl), -1) -// constantsBytes = bytes.Replace(constantsBytes, []byte(sym.Name), []byte(repl), -1) -// } -// } - -// if err := os.WriteFile("models_serde.go", modelsSerdeBytes, 0700); err != nil { -// return err -// } - -// if err := os.WriteFile("constants.go", constantsBytes, 0700); err != nil { -// return err -// } - -// return nil -// } diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/gopls/gopls.go b/sdk/messaging/eventgrid/azsystemevents/internal/gopls/gopls.go index fea0bf658193..a3f3bcdddabc 100644 --- a/sdk/messaging/eventgrid/azsystemevents/internal/gopls/gopls.go +++ b/sdk/messaging/eventgrid/azsystemevents/internal/gopls/gopls.go @@ -9,6 +9,7 @@ package gopls import ( "bufio" "bytes" + "errors" "fmt" "os" "os/exec" @@ -16,12 +17,23 @@ import ( ) type Symbol struct { - Name string + Name string + // Either: + // - Constant + // - Class (type ACSRouterJobStatus string) + // - Struct + // - Field + // - Function + // - Method Type string Position string } func Rename(filename string, sym Symbol, newName string) error { + if sym.Name == "" && sym.Position == "" && sym.Type == "" { + return errors.New("attempted to rename with an empty symbol") + } + cmd := exec.Command("gopls", "rename", "-w", filename+":"+sym.Position, newName) if err := cmd.Run(); err != nil { @@ -31,7 +43,7 @@ func Rename(filename string, sym Symbol, newName string) error { return nil } -func TypeSymbols(filename string) (map[string]Symbol, error) { +func Symbols(filename string) (map[string]Symbol, error) { if _, err := os.Stat(filename); err != nil { return nil, err } @@ -51,6 +63,7 @@ func TypeSymbols(filename string) (map[string]Symbol, error) { scanner := bufio.NewScanner(bytes.NewReader(allBytes)) m := map[string]Symbol{} + prevParent := "" for scanner.Scan() { // ex: @@ -62,11 +75,17 @@ func TypeSymbols(filename string) (map[string]Symbol, error) { // renaming types. // Address Field 5379:2-5379:9 + var fields []string + if len(scanner.Text()) > 0 && scanner.Text()[0] == '\t' { - continue - } + // this is a field - we'll add it and "parent" it to the last non-field symbol before it + // (and clip out the first char, which is a tab) + fields = strings.Split(scanner.Text()[1:], " ") - fields := strings.Split(scanner.Text(), " ") + fields[0] = prevParent + "." + fields[0] + } else { + fields = strings.Split(scanner.Text(), " ") + } if len(fields) != 3 { return nil, fmt.Errorf("failed to parse %q into three fields, got %d", scanner.Text(), len(fields)) @@ -83,6 +102,10 @@ func TypeSymbols(filename string) (map[string]Symbol, error) { } m[sym.Name] = sym + + if sym.Type != "Field" { + prevParent = sym.Name + } } return m, nil diff --git a/sdk/messaging/eventgrid/azsystemevents/models.go b/sdk/messaging/eventgrid/azsystemevents/models.go index e2f95dfab701..36608484161f 100644 --- a/sdk/messaging/eventgrid/azsystemevents/models.go +++ b/sdk/messaging/eventgrid/azsystemevents/models.go @@ -1040,7 +1040,7 @@ type ACSRouterCommunicationError struct { Details []ACSRouterCommunicationError // Router Communication Inner Error - Innererror *ACSRouterCommunicationError + InnerError *ACSRouterCommunicationError // Router Communication Error Message Message *string diff --git a/sdk/messaging/eventgrid/azsystemevents/models_serde.go b/sdk/messaging/eventgrid/azsystemevents/models_serde.go index 2b5587074d7e..4248408f6287 100644 --- a/sdk/messaging/eventgrid/azsystemevents/models_serde.go +++ b/sdk/messaging/eventgrid/azsystemevents/models_serde.go @@ -2408,7 +2408,7 @@ func (a ACSRouterCommunicationError) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "code", a.Code) populate(objectMap, "details", a.Details) - populate(objectMap, "innererror", a.Innererror) + populate(objectMap, "innererror", a.InnerError) populate(objectMap, "message", a.Message) populate(objectMap, "target", a.Target) return json.Marshal(objectMap) @@ -2430,7 +2430,7 @@ func (a *ACSRouterCommunicationError) UnmarshalJSON(data []byte) error { err = unpopulate(val, "Details", &a.Details) delete(rawMsg, key) case "innererror": - err = unpopulate(val, "Innererror", &a.Innererror) + err = unpopulate(val, "Innererror", &a.InnerError) delete(rawMsg, key) case "message": err = unpopulate(val, "Message", &a.Message) From c995d8eeed0be88800018b26371f849fceb6eb82 Mon Sep 17 00:00:00 2001 From: ripark Date: Fri, 22 Mar 2024 17:41:23 +0000 Subject: [PATCH 05/12] Little generator cleanup --- .../internal/generate/generate.go | 168 +--------------- .../internal/generate/generate_constants.go | 180 ++++++++++++++++++ 2 files changed, 185 insertions(+), 163 deletions(-) create mode 100644 sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_constants.go diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate.go b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate.go index c150a8adcd9a..fc74ca9a5c6e 100644 --- a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate.go +++ b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate.go @@ -7,15 +7,14 @@ package main import ( - "bufio" "bytes" "fmt" - "io" "log" "os" "regexp" "sort" "strings" + "time" "github.com/Azure/azure-sdk-for-go/sdk/messaging/eventgrid/azsystemevents/internal/gopls" ) @@ -26,27 +25,6 @@ var filesToDelete = []string{ "clientdeleteme_client.go", } -const systemEventsGoFile = "system_events.go" -const modelsGoFile = "models.go" -const constantsGoFile = "constants.go" - -const header = `//go:build go1.18 -// +build go1.18 - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -package azsystemevents - -// Type represents the value set in EventData.EventType or messaging.CloudEvent.Type -// for system events. -type Type string - -const ( -` - -const footer = `)` - func main() { fn := func() error { if err := doRenames(); err != nil { @@ -104,146 +82,6 @@ func deleteUnneededFiles() { } } -type constant struct { - ConstantName string - GoType string - ConstantValue string -} - -func getConstantValues(reader io.ReadCloser) (map[string]constant, error) { - data, err := io.ReadAll(reader) - - if err != nil { - return nil, err - } - - scanner := bufio.NewScanner(bytes.NewReader(data)) - - var currentComment []string - - var comments []struct { - Text string - ForType string - } - - for scanner.Scan() { - line := scanner.Text() - - if commentText, found := cutPrefix(line, "// "); found { - currentComment = append(currentComment, commentText) - } else if len(currentComment) > 0 && strings.HasPrefix(line, "type ") { - comments = append(comments, struct { - Text string - ForType string - }{ - Text: strings.Join(currentComment, " "), - ForType: strings.Split(line, " ")[1], - }) - currentComment = nil - } - } - - consts := map[string]constant{} - // ex: 'StorageBlobCreatedEventData - Schema of the Data property of an Event for a Microsoft.Storage.BlobCreated event.' - // 'IotHubDeviceConnectedEventData - Event data for Microsoft.Devices.DeviceConnected event.' - typeRE := regexp.MustCompile(`([^ ]+) -.+?([A-Za-z0-9]+(?:\.[A-Za-z0-9]+){2,3})`) - - ignoredTypes := []string{ - "DeviceConnectionStateEventProperties", - "DeviceLifeCycleEventProperties", - "DeviceTelemetryEventProperties", - "EventGridMQTTClientEventData", - "MapsGeofenceEventProperties", - } - - for _, comment := range comments { - matches := typeRE.FindStringSubmatch(comment.Text) - - if strings.Contains(comment.Text, "Schema of the Data") && len(matches) == 0 { - ignorable := false - - // we have a few types that we can ignore - they're not top-level SystemEvents (they're - // embedded or used by other events). - for _, prefix := range ignoredTypes { - if strings.HasPrefix(comment.Text, prefix) { - ignorable = true - break - } - } - - if !ignorable { - log.Printf("===========> DIDN'T MATCH REGEX: %q ", comment) - } - } - - if len(matches) == 0 { - continue - } - - goTypeName, stringValue := matches[1], matches[2] - constantName := strings.Replace(goTypeName, "EventData", "", 1) - - consts[stringValue] = constant{ - ConstantName: "Type" + constantName, - GoType: goTypeName, - ConstantValue: stringValue, - } - } - - return consts, nil -} - -func writeConstantsFile(path string, constants map[string]constant) error { - writer, err := os.Create(path) - - if err != nil { - return err - } - - defer writer.Close() - - if _, err := writer.Write([]byte(header)); err != nil { - return err - } - - for _, key := range sortedKeys(constants) { - c := constants[key] - - // ex: - // TypeAPIManagementAPICreated Type = "Microsoft.ApiManagement.APICreated" // maps to APIManagementAPICreatedEventData - buff := fmt.Sprintf("%s Type = \"%s\" // maps to %s\n", c.ConstantName, c.ConstantValue, c.GoType) - _, err := writer.WriteString(buff) - - if err != nil { - return err - } - } - - if _, err := writer.Write([]byte(footer)); err != nil { - return err - } - - return nil -} - -func sortedKeys[T any](m map[string]T) []string { - var keys []string - for k := range m { - keys = append(keys, k) - } - - sort.Strings(keys) - return keys -} - -// copy of strings.CutPrefix, which doesn't exist in our oldest support compiler (1.18) -func cutPrefix(s, prefix string) (after string, found bool) { - if !strings.HasPrefix(s, prefix) { - return s, false - } - return s[len(prefix):], true -} - type rename struct { Orig gopls.Symbol New string @@ -275,6 +113,8 @@ func doRenames() error { total := len(phase1Repls) + len(modelRepls) + now := time.Now() + for i, repl := range phase1Repls { fmt.Printf("%s[%d/%d]: %s -> %s\n", repl.FileName, i+1, total, repl.Orig.Name, repl.New) if err := gopls.Rename(repl.FileName, repl.Orig, repl.New); err != nil { @@ -290,6 +130,8 @@ func doRenames() error { } } + fmt.Printf("Took %s to do gopls based renames\n", time.Since(now)) + return fixComments(modelRepls) } diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_constants.go b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_constants.go new file mode 100644 index 000000000000..7b3d00f5f33a --- /dev/null +++ b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_constants.go @@ -0,0 +1,180 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package main + +import ( + "bufio" + "bytes" + "fmt" + "io" + "log" + "os" + "regexp" + "sort" + "strings" +) + +const systemEventsGoFile = "system_events.go" +const modelsGoFile = "models.go" +const constantsGoFile = "constants.go" + +const header = `//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azsystemevents + +// Type represents the value set in EventData.EventType or messaging.CloudEvent.Type +// for system events. +type Type string + +const ( +` + +const footer = `)` + +type constant struct { + ConstantName string + GoType string + ConstantValue string +} + +func getConstantValues(reader io.ReadCloser) (map[string]constant, error) { + data, err := io.ReadAll(reader) + + if err != nil { + return nil, err + } + + scanner := bufio.NewScanner(bytes.NewReader(data)) + + var currentComment []string + + var comments []struct { + Text string + ForType string + } + + for scanner.Scan() { + line := scanner.Text() + + if commentText, found := cutPrefix(line, "// "); found { + currentComment = append(currentComment, commentText) + } else if len(currentComment) > 0 && strings.HasPrefix(line, "type ") { + comments = append(comments, struct { + Text string + ForType string + }{ + Text: strings.Join(currentComment, " "), + ForType: strings.Split(line, " ")[1], + }) + currentComment = nil + } + } + + consts := map[string]constant{} + // ex: 'StorageBlobCreatedEventData - Schema of the Data property of an Event for a Microsoft.Storage.BlobCreated event.' + // 'IotHubDeviceConnectedEventData - Event data for Microsoft.Devices.DeviceConnected event.' + typeRE := regexp.MustCompile(`([^ ]+) -.+?([A-Za-z0-9]+(?:\.[A-Za-z0-9]+){2,3})`) + + ignoredTypes := []string{ + "DeviceConnectionStateEventProperties", + "DeviceLifeCycleEventProperties", + "DeviceTelemetryEventProperties", + "EventGridMQTTClientEventData", + "MapsGeofenceEventProperties", + } + + for _, comment := range comments { + matches := typeRE.FindStringSubmatch(comment.Text) + + if strings.Contains(comment.Text, "Schema of the Data") && len(matches) == 0 { + ignorable := false + + // we have a few types that we can ignore - they're not top-level SystemEvents (they're + // embedded or used by other events). + for _, prefix := range ignoredTypes { + if strings.HasPrefix(comment.Text, prefix) { + ignorable = true + break + } + } + + if !ignorable { + log.Printf("===========> DIDN'T MATCH REGEX: %q ", comment) + } + } + + if len(matches) == 0 { + continue + } + + goTypeName, stringValue := matches[1], matches[2] + constantName := strings.Replace(goTypeName, "EventData", "", 1) + + consts[stringValue] = constant{ + ConstantName: "Type" + constantName, + GoType: goTypeName, + ConstantValue: stringValue, + } + } + + return consts, nil +} + +func writeConstantsFile(path string, constants map[string]constant) error { + writer, err := os.Create(path) + + if err != nil { + return err + } + + defer writer.Close() + + if _, err := writer.Write([]byte(header)); err != nil { + return err + } + + for _, key := range sortedKeys(constants) { + c := constants[key] + + // ex: + // TypeAPIManagementAPICreated Type = "Microsoft.ApiManagement.APICreated" // maps to APIManagementAPICreatedEventData + buff := fmt.Sprintf("%s Type = \"%s\" // maps to %s\n", c.ConstantName, c.ConstantValue, c.GoType) + _, err := writer.WriteString(buff) + + if err != nil { + return err + } + } + + if _, err := writer.Write([]byte(footer)); err != nil { + return err + } + + return nil +} + +func sortedKeys[T any](m map[string]T) []string { + var keys []string + for k := range m { + keys = append(keys, k) + } + + sort.Strings(keys) + return keys +} + +// copy of strings.CutPrefix, which doesn't exist in our oldest support compiler (1.18) +func cutPrefix(s, prefix string) (after string, found bool) { + if !strings.HasPrefix(s, prefix) { + return s, false + } + return s[len(prefix):], true +} From 469fdf60aeef11180e1445ad38dc0a5de95908d5 Mon Sep 17 00:00:00 2001 From: ripark Date: Fri, 22 Mar 2024 17:50:46 +0000 Subject: [PATCH 06/12] Updating to Josh Love's latest rev: c25006263b7c15ad5da755a5ef864e4301e56b54 --- .../eventgrid/azsystemevents/autorest.md | 2 +- .../eventgrid/azsystemevents/constants.go | 36 ++ .../eventgrid/azsystemevents/models.go | 151 +++++++ .../eventgrid/azsystemevents/models_serde.go | 386 ++++++++++++++++++ .../eventgrid/azsystemevents/system_events.go | 2 + 5 files changed, 576 insertions(+), 1 deletion(-) diff --git a/sdk/messaging/eventgrid/azsystemevents/autorest.md b/sdk/messaging/eventgrid/azsystemevents/autorest.md index b278023701fa..0b527f83e25c 100644 --- a/sdk/messaging/eventgrid/azsystemevents/autorest.md +++ b/sdk/messaging/eventgrid/azsystemevents/autorest.md @@ -6,7 +6,7 @@ description: Azure Event Grid system events generated-metadata: false clear-output-folder: false go: true -require: https://github.com/Azure/azure-rest-api-specs/blob/a02f2ba78bfb988c3bd195886c0492024f0ea7fc/specification/eventgrid/data-plane/readme.md +require: https://github.com/Azure/azure-rest-api-specs/blob/c25006263b7c15ad5da755a5ef864e4301e56b54/specification/eventgrid/data-plane/readme.md license-header: MICROSOFT_MIT_NO_VERSION openapi-type: "data-plane" output-folder: ../azsystemevents diff --git a/sdk/messaging/eventgrid/azsystemevents/constants.go b/sdk/messaging/eventgrid/azsystemevents/constants.go index 5866ebf54954..c556bb9f0eae 100644 --- a/sdk/messaging/eventgrid/azsystemevents/constants.go +++ b/sdk/messaging/eventgrid/azsystemevents/constants.go @@ -39,6 +39,42 @@ func PossibleACSEmailDeliveryReportStatusValues() []ACSEmailDeliveryReportStatus } } +// ACSInteractiveReplyType - The Message interactive reply type +type ACSInteractiveReplyType string + +const ( + // ACSInteractiveReplyTypeButtonReply - Messaged interactive reply type is ButtonReply + ACSInteractiveReplyTypeButtonReply ACSInteractiveReplyType = "buttonReply" + // ACSInteractiveReplyTypeListReply - Messaged interactive reply type is ListReply + ACSInteractiveReplyTypeListReply ACSInteractiveReplyType = "listReply" + // ACSInteractiveReplyTypeUnknown - Messaged interactive reply type is Unknown + ACSInteractiveReplyTypeUnknown ACSInteractiveReplyType = "unknown" +) + +// PossibleACSInteractiveReplyTypeValues returns the possible values for the AcsInteractiveReplyType const type. +func PossibleACSInteractiveReplyTypeValues() []ACSInteractiveReplyType { + return []ACSInteractiveReplyType{ + ACSInteractiveReplyTypeButtonReply, + ACSInteractiveReplyTypeListReply, + ACSInteractiveReplyTypeUnknown, + } +} + +// ACSMessageChannelType - The The messaged received channel type +type ACSMessageChannelType string + +const ( + // ACSMessageChannelTypeWhatsapp - Updated messaged channel type is Whatsapp + ACSMessageChannelTypeWhatsapp ACSMessageChannelType = "whatsapp" +) + +// PossibleACSMessageChannelTypeValues returns the possible values for the AcsMessageChannelType const type. +func PossibleACSMessageChannelTypeValues() []ACSMessageChannelType { + return []ACSMessageChannelType{ + ACSMessageChannelTypeWhatsapp, + } +} + // ACSRouterJobStatus - Router Job Received Job Status type ACSRouterJobStatus string diff --git a/sdk/messaging/eventgrid/azsystemevents/models.go b/sdk/messaging/eventgrid/azsystemevents/models.go index 36608484161f..dd7e486df01f 100644 --- a/sdk/messaging/eventgrid/azsystemevents/models.go +++ b/sdk/messaging/eventgrid/azsystemevents/models.go @@ -279,6 +279,157 @@ type APIManagementUserUpdatedEventData struct { ResourceURI *string } +// ACSAdvancedMessageButtonContent - Advanced Message Button Content +type ACSAdvancedMessageButtonContent struct { + // The Payload of the button which was clicked by the user, setup by the business + Payload *string + + // The Text of the button + Text *string +} + +// ACSAdvancedMessageChannelEventError - Advanced Message Channel Event Error +type ACSAdvancedMessageChannelEventError struct { + // The channel error code + ChannelCode *string + + // The channel error message + ChannelMessage *string +} + +// ACSAdvancedMessageContext - Advanced Message Context +type ACSAdvancedMessageContext struct { + // The WhatsApp ID for the customer who replied to an inbound message. + From *string + + // The message ID for the sent message for an inbound reply + ID *string +} + +// ACSAdvancedMessageDeliveryStatusUpdatedEventData - Schema of the Data property of an CloudEvent/EventGridEvent for a Microsoft.Communication.AdvancedMessageDeliveryStatusUpdated +// event. +type ACSAdvancedMessageDeliveryStatusUpdatedEventData struct { + // The updated message channel type + ChannelType *ACSMessageChannelType + + // The channel event error + Error *ACSAdvancedMessageChannelEventError + + // The message sender + From *string + + // The message id + MessageID *string + + // The time message was received + ReceivedTimestamp *time.Time + + // The updated message status + Status *string + + // The message recipient + To *string +} + +// ACSAdvancedMessageEventData - Schema of common properties of all chat thread events +type ACSAdvancedMessageEventData struct { + // The channel event error + Error *ACSAdvancedMessageChannelEventError + + // The message sender + From *string + + // The time message was received + ReceivedTimestamp *time.Time + + // The message recipient + To *string +} + +// ACSAdvancedMessageInteractiveButtonReplyContent - Advanced Message Interactive button reply content for a user to business +// message +type ACSAdvancedMessageInteractiveButtonReplyContent struct { + // The ID of the button + ID *string + + // The title of the button + Title *string +} + +// ACSAdvancedMessageInteractiveContent - Advanced Message Interactive Content +type ACSAdvancedMessageInteractiveContent struct { + // The Message Sent when a customer clicks a button + ButtonReply *ACSAdvancedMessageInteractiveButtonReplyContent + + // The Message Sent when a customer selects an item from a list + ListReply *ACSAdvancedMessageInteractiveListReplyContent + + // The Message interactive reply type + Type *ACSInteractiveReplyType +} + +// ACSAdvancedMessageInteractiveListReplyContent - Advanced Message Interactive list reply content for a user to business +// message +type ACSAdvancedMessageInteractiveListReplyContent struct { + // The sescription of the selected row + Description *string + + // The ID of the selected list item + ID *string + + // The title of the selected list item + Title *string +} + +// ACSAdvancedMessageMediaContent - Advanced Message Media Content +type ACSAdvancedMessageMediaContent struct { + // The caption for the media object, if supported and provided + Caption *string + + // The filename of the underlying media file as specified when uploaded + FileName *string + + // The media identifier + ID *string + + // The MIME type of the file this media represents + MimeType *string +} + +// ACSAdvancedMessageReceivedEventData - Schema of the Data property of an CloudEvent/EventGridEvent for a Microsoft.Communication.AdvancedMessageReceived +// event. +type ACSAdvancedMessageReceivedEventData struct { + // The The messaged received button content + Button *ACSAdvancedMessageButtonContent + + // The The messaged received channel type + ChannelType *ACSMessageChannelType + + // The The messaged received content + Content *string + + // The The messaged received context + Context *ACSAdvancedMessageContext + + // The channel event error + Error *ACSAdvancedMessageChannelEventError + + // The message sender + From *string + + // The The messaged received interactive content + Interactive *ACSAdvancedMessageInteractiveContent + + // The messaged received media content + Media *ACSAdvancedMessageMediaContent + + // The time message was received + ReceivedTimestamp *time.Time + + // The message recipient + To *string +} + // ACSChatEventBaseProperties - Schema of common properties of all chat events type ACSChatEventBaseProperties struct { // The communication identifier of the target user diff --git a/sdk/messaging/eventgrid/azsystemevents/models_serde.go b/sdk/messaging/eventgrid/azsystemevents/models_serde.go index 4248408f6287..acc791aee8d9 100644 --- a/sdk/messaging/eventgrid/azsystemevents/models_serde.go +++ b/sdk/messaging/eventgrid/azsystemevents/models_serde.go @@ -819,6 +819,392 @@ func (a *APIManagementUserUpdatedEventData) UnmarshalJSON(data []byte) error { return nil } +// MarshalJSON implements the json.Marshaller interface for type ACSAdvancedMessageButtonContent. +func (a ACSAdvancedMessageButtonContent) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "payload", a.Payload) + populate(objectMap, "text", a.Text) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSAdvancedMessageButtonContent. +func (a *ACSAdvancedMessageButtonContent) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "payload": + err = unpopulate(val, "Payload", &a.Payload) + delete(rawMsg, key) + case "text": + err = unpopulate(val, "Text", &a.Text) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ACSAdvancedMessageChannelEventError. +func (a ACSAdvancedMessageChannelEventError) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "channelCode", a.ChannelCode) + populate(objectMap, "channelMessage", a.ChannelMessage) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSAdvancedMessageChannelEventError. +func (a *ACSAdvancedMessageChannelEventError) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "channelCode": + err = unpopulate(val, "ChannelCode", &a.ChannelCode) + delete(rawMsg, key) + case "channelMessage": + err = unpopulate(val, "ChannelMessage", &a.ChannelMessage) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ACSAdvancedMessageContext. +func (a ACSAdvancedMessageContext) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "from", a.From) + populate(objectMap, "id", a.ID) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSAdvancedMessageContext. +func (a *ACSAdvancedMessageContext) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "from": + err = unpopulate(val, "From", &a.From) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &a.ID) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ACSAdvancedMessageDeliveryStatusUpdatedEventData. +func (a ACSAdvancedMessageDeliveryStatusUpdatedEventData) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "channelType", a.ChannelType) + populate(objectMap, "error", a.Error) + populate(objectMap, "from", a.From) + populate(objectMap, "messageId", a.MessageID) + populateDateTimeRFC3339(objectMap, "receivedTimestamp", a.ReceivedTimestamp) + populate(objectMap, "status", a.Status) + populate(objectMap, "to", a.To) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSAdvancedMessageDeliveryStatusUpdatedEventData. +func (a *ACSAdvancedMessageDeliveryStatusUpdatedEventData) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "channelType": + err = unpopulate(val, "ChannelType", &a.ChannelType) + delete(rawMsg, key) + case "error": + err = unpopulate(val, "Error", &a.Error) + delete(rawMsg, key) + case "from": + err = unpopulate(val, "From", &a.From) + delete(rawMsg, key) + case "messageId": + err = unpopulate(val, "MessageID", &a.MessageID) + delete(rawMsg, key) + case "receivedTimestamp": + err = unpopulateDateTimeRFC3339(val, "ReceivedTimestamp", &a.ReceivedTimestamp) + delete(rawMsg, key) + case "status": + err = unpopulate(val, "Status", &a.Status) + delete(rawMsg, key) + case "to": + err = unpopulate(val, "To", &a.To) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ACSAdvancedMessageEventData. +func (a ACSAdvancedMessageEventData) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "error", a.Error) + populate(objectMap, "from", a.From) + populateDateTimeRFC3339(objectMap, "receivedTimestamp", a.ReceivedTimestamp) + populate(objectMap, "to", a.To) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSAdvancedMessageEventData. +func (a *ACSAdvancedMessageEventData) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "error": + err = unpopulate(val, "Error", &a.Error) + delete(rawMsg, key) + case "from": + err = unpopulate(val, "From", &a.From) + delete(rawMsg, key) + case "receivedTimestamp": + err = unpopulateDateTimeRFC3339(val, "ReceivedTimestamp", &a.ReceivedTimestamp) + delete(rawMsg, key) + case "to": + err = unpopulate(val, "To", &a.To) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ACSAdvancedMessageInteractiveButtonReplyContent. +func (a ACSAdvancedMessageInteractiveButtonReplyContent) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "id", a.ID) + populate(objectMap, "title", a.Title) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSAdvancedMessageInteractiveButtonReplyContent. +func (a *ACSAdvancedMessageInteractiveButtonReplyContent) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "id": + err = unpopulate(val, "ID", &a.ID) + delete(rawMsg, key) + case "title": + err = unpopulate(val, "Title", &a.Title) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ACSAdvancedMessageInteractiveContent. +func (a ACSAdvancedMessageInteractiveContent) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "buttonReply", a.ButtonReply) + populate(objectMap, "listReply", a.ListReply) + populate(objectMap, "type", a.Type) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSAdvancedMessageInteractiveContent. +func (a *ACSAdvancedMessageInteractiveContent) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "buttonReply": + err = unpopulate(val, "ButtonReply", &a.ButtonReply) + delete(rawMsg, key) + case "listReply": + err = unpopulate(val, "ListReply", &a.ListReply) + delete(rawMsg, key) + case "type": + err = unpopulate(val, "Type", &a.Type) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ACSAdvancedMessageInteractiveListReplyContent. +func (a ACSAdvancedMessageInteractiveListReplyContent) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "description", a.Description) + populate(objectMap, "id", a.ID) + populate(objectMap, "title", a.Title) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSAdvancedMessageInteractiveListReplyContent. +func (a *ACSAdvancedMessageInteractiveListReplyContent) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "description": + err = unpopulate(val, "Description", &a.Description) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &a.ID) + delete(rawMsg, key) + case "title": + err = unpopulate(val, "Title", &a.Title) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ACSAdvancedMessageMediaContent. +func (a ACSAdvancedMessageMediaContent) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "caption", a.Caption) + populate(objectMap, "fileName", a.FileName) + populate(objectMap, "id", a.ID) + populate(objectMap, "mimeType", a.MimeType) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSAdvancedMessageMediaContent. +func (a *ACSAdvancedMessageMediaContent) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "caption": + err = unpopulate(val, "Caption", &a.Caption) + delete(rawMsg, key) + case "fileName": + err = unpopulate(val, "FileName", &a.FileName) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &a.ID) + delete(rawMsg, key) + case "mimeType": + err = unpopulate(val, "MimeType", &a.MimeType) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ACSAdvancedMessageReceivedEventData. +func (a ACSAdvancedMessageReceivedEventData) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "button", a.Button) + populate(objectMap, "channelType", a.ChannelType) + populate(objectMap, "content", a.Content) + populate(objectMap, "context", a.Context) + populate(objectMap, "error", a.Error) + populate(objectMap, "from", a.From) + populate(objectMap, "interactive", a.Interactive) + populate(objectMap, "media", a.Media) + populateDateTimeRFC3339(objectMap, "receivedTimestamp", a.ReceivedTimestamp) + populate(objectMap, "to", a.To) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ACSAdvancedMessageReceivedEventData. +func (a *ACSAdvancedMessageReceivedEventData) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "button": + err = unpopulate(val, "Button", &a.Button) + delete(rawMsg, key) + case "channelType": + err = unpopulate(val, "ChannelType", &a.ChannelType) + delete(rawMsg, key) + case "content": + err = unpopulate(val, "Content", &a.Content) + delete(rawMsg, key) + case "context": + err = unpopulate(val, "Context", &a.Context) + delete(rawMsg, key) + case "error": + err = unpopulate(val, "Error", &a.Error) + delete(rawMsg, key) + case "from": + err = unpopulate(val, "From", &a.From) + delete(rawMsg, key) + case "interactive": + err = unpopulate(val, "Interactive", &a.Interactive) + delete(rawMsg, key) + case "media": + err = unpopulate(val, "Media", &a.Media) + delete(rawMsg, key) + case "receivedTimestamp": + err = unpopulateDateTimeRFC3339(val, "ReceivedTimestamp", &a.ReceivedTimestamp) + delete(rawMsg, key) + case "to": + err = unpopulate(val, "To", &a.To) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + // MarshalJSON implements the json.Marshaller interface for type ACSChatEventBaseProperties. func (a ACSChatEventBaseProperties) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) diff --git a/sdk/messaging/eventgrid/azsystemevents/system_events.go b/sdk/messaging/eventgrid/azsystemevents/system_events.go index 682365a7b510..f8a77481775e 100644 --- a/sdk/messaging/eventgrid/azsystemevents/system_events.go +++ b/sdk/messaging/eventgrid/azsystemevents/system_events.go @@ -59,6 +59,8 @@ const ( TypeRedisImportRDBCompleted Type = "Microsoft.Cache.ImportRDBCompleted" // maps to RedisImportRDBCompletedEventData TypeRedisPatchingCompleted Type = "Microsoft.Cache.PatchingCompleted" // maps to RedisPatchingCompletedEventData TypeRedisScalingCompleted Type = "Microsoft.Cache.ScalingCompleted" // maps to RedisScalingCompletedEventData + TypeACSAdvancedMessageDeliveryStatusUpdated Type = "Microsoft.Communication.AdvancedMessageDeliveryStatusUpdated" // maps to ACSAdvancedMessageDeliveryStatusUpdatedEventData + TypeACSAdvancedMessageReceived Type = "Microsoft.Communication.AdvancedMessageReceived" // maps to ACSAdvancedMessageReceivedEventData TypeACSChatMessageDeleted Type = "Microsoft.Communication.ChatMessageDeleted" // maps to ACSChatMessageDeletedEventData TypeACSChatMessageDeletedInThread Type = "Microsoft.Communication.ChatMessageDeletedInThread" // maps to ACSChatMessageDeletedInThreadEventData TypeACSChatMessageEdited Type = "Microsoft.Communication.ChatMessageEdited" // maps to ACSChatMessageEditedEventData From bdb24fb4183f967ebd2dd0b11bc69c57fcfc19c9 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Fri, 22 Mar 2024 19:57:36 -0700 Subject: [PATCH 07/12] Updating with our own custom error, lest we lose detail that apparently might be filled in! --- .../eventgrid/azsystemevents/custom_events.go | 61 ++++++++ .../azsystemevents/custom_events_test.go | 114 ++++++++++++++ .../eventgrid/azsystemevents/error.go | 26 ++++ .../internal/generate/generate.go | 127 ++++++++++++---- .../internal/generate/generate_constants.go | 1 + .../internal/generate/generate_test.go | 142 ++++++++++++++++++ .../internal/generate/regex_helpers.go | 116 ++++++++++++++ .../azsystemevents/internal/gopls/gopls.go | 105 ++++++++++--- .../eventgrid/azsystemevents/models.go | 20 +-- .../eventgrid/azsystemevents/models_serde.go | 24 +-- .../azsystemevents/system_events4_test.go | 4 +- 11 files changed, 668 insertions(+), 72 deletions(-) create mode 100644 sdk/messaging/eventgrid/azsystemevents/custom_events_test.go create mode 100644 sdk/messaging/eventgrid/azsystemevents/error.go create mode 100644 sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_test.go create mode 100644 sdk/messaging/eventgrid/azsystemevents/internal/generate/regex_helpers.go diff --git a/sdk/messaging/eventgrid/azsystemevents/custom_events.go b/sdk/messaging/eventgrid/azsystemevents/custom_events.go index 08226522b65f..17e6135807cd 100644 --- a/sdk/messaging/eventgrid/azsystemevents/custom_events.go +++ b/sdk/messaging/eventgrid/azsystemevents/custom_events.go @@ -6,6 +6,11 @@ package azsystemevents +import ( + "encoding/json" + "fmt" +) + //type IotHubDeviceConnectedEventData DeviceConnectionStateEventProperties func fixNAValue(s **string) { @@ -13,3 +18,59 @@ func fixNAValue(s **string) { *s = nil } } + +func unmarshalInternalACSAdvancedMessageChannelEventError(val json.RawMessage, fn string, re **Error) error { + var realErr *internalACSAdvancedMessageChannelEventError + + if err := json.Unmarshal(val, &realErr); err != nil { + return fmt.Errorf("struct field %s: %v", fn, err) + } + + *re = &Error{ + Code: *realErr.ChannelCode, + message: *realErr.ChannelMessage, + } + + return nil +} + +func unmarshalInternalACSRouterCommunicationError(val json.RawMessage, fn string, re *[]*Error) error { + type superError struct { + Code string + InnerError *superError + Details []*superError + Message string + } + + var unpack func(err *superError) *Error + + unpack = func(err *superError) *Error { + if err == nil { + return nil + } + + e := &Error{ + Code: err.Code, + message: err.Message, + InnerError: unpack(err.InnerError), + } + + for _, detailErr := range err.Details { + e.Details = append(e.Details, unpack(detailErr)) + } + + return e + } + + var tmp []*superError + + if err := json.Unmarshal(val, &tmp); err != nil { + return fmt.Errorf("struct field %s: %v", fn, err) + } + + for _, se := range tmp { + *re = append(*re, unpack(se)) + } + + return nil +} diff --git a/sdk/messaging/eventgrid/azsystemevents/custom_events_test.go b/sdk/messaging/eventgrid/azsystemevents/custom_events_test.go new file mode 100644 index 000000000000..60296dd395d3 --- /dev/null +++ b/sdk/messaging/eventgrid/azsystemevents/custom_events_test.go @@ -0,0 +1,114 @@ +package azsystemevents + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestUnmarshalInternalACSRouterCommunicationError(t *testing.T) { + t.Run("single", func(t *testing.T) { + text := `[ + { + "code": "Failure", + "message": "Classification failed due to ", + "target": null, + "innererror": { + "code": "InnerFailure", + "message": "Classification failed due to ", + "target": null}, + "details": null + } + ]` + + var unmarshalledErrs []*Error + err := unmarshalInternalACSRouterCommunicationError(json.RawMessage(text), "FieldName", &unmarshalledErrs) + require.NoError(t, err) + require.Equal(t, []*Error{ + { + Code: "Failure", + message: "Classification failed due to ", + InnerError: &Error{ + Code: "InnerFailure", message: "Classification failed due to ", + }, + }, + }, unmarshalledErrs) + }) + + t.Run("Multiple", func(t *testing.T) { + text := `[ + { + "code": "Failure", + "message": "Classification failed due to " + }, + { + "code": "FailureAsWell", + "message": "Classification failed due to " + } + ]` + + var unmarshalledErrs []*Error + err := unmarshalInternalACSRouterCommunicationError(json.RawMessage(text), "FieldName", &unmarshalledErrs) + require.NoError(t, err) + require.Equal(t, []*Error{ + {Code: "Failure", message: "Classification failed due to "}, + {Code: "FailureAsWell", message: "Classification failed due to "}, + }, unmarshalledErrs) + }) + + t.Run("Recursive", func(t *testing.T) { + text := `[ + { + "code": "Failure", + "message": "FailureMessage", + "innererror": { + "code": "InnerFailure", + "message": "InnerFailureMessage", + "innererror": { + "code": "Inner.InnerFailure", + "message": "Inner.InnerFailureMessage" + } + }, + "details": [ + { + "code": "Detail", + "message": "DetailMessage", + "innererror": { + "code": "Detail.InnerFailure", + "message": "Detail.InnerFailure.Message" + } + } + ] + } + ]` + + var unmarshalledErrs []*Error + err := unmarshalInternalACSRouterCommunicationError(json.RawMessage(text), "FieldName", &unmarshalledErrs) + require.NoError(t, err) + require.Equal(t, []*Error{ + { + Code: "Failure", + message: "FailureMessage", + InnerError: &Error{ + Code: "InnerFailure", + message: "InnerFailureMessage", + InnerError: &Error{ + Code: "Inner.InnerFailure", + message: "Inner.InnerFailureMessage", + }, + }, + Details: []*Error{ + { + Code: "Detail", + message: "DetailMessage", + InnerError: &Error{ + Code: "Detail.InnerFailure", + message: "Detail.InnerFailure.Message", + }, + }, + }, + }, + }, unmarshalledErrs) + }) +} diff --git a/sdk/messaging/eventgrid/azsystemevents/error.go b/sdk/messaging/eventgrid/azsystemevents/error.go new file mode 100644 index 000000000000..374b7f429ba7 --- /dev/null +++ b/sdk/messaging/eventgrid/azsystemevents/error.go @@ -0,0 +1,26 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azsystemevents + +// Error is an error that is included as part of a system event. +type Error struct { + // Code is an error code from the service producing the system event. + Code string + + // InnerError can provide more information about the origin of this error. + InnerError *Error + + // Details contains related errors for this error. + Details []*Error + + message string +} + +// Error returns human-readable text describing the error. +func (e *Error) Error() string { + return e.message +} diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate.go b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate.go index fc74ca9a5c6e..70c5a6a6979a 100644 --- a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate.go +++ b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate.go @@ -27,6 +27,10 @@ var filesToDelete = []string{ func main() { fn := func() error { + if err := swapErrorTypes(); err != nil { + return err + } + if err := doRenames(); err != nil { return err } @@ -47,6 +51,77 @@ func main() { fmt.Printf("DONE\n") } +// swapErrorTypes handles turning most of the auto-generated errors into a single consistent error type. +// The key is that the Error type doesn't export human readable strings as fields - it's all contained in +// the Error() field. +func swapErrorTypes() error { + syms, err := gopls.Symbols(modelsGoFile) + + if err != nil { + return err + } + + { + if err := gopls.Rename(syms.Get("AcsAdvancedMessageChannelEventError"), "internalACSAdvancedMessageChannelEventError"); err != nil { + return err + } + + if err := SwapType(syms.Get("AcsAdvancedMessageReceivedEventData.Error"), "*Error"); err != nil { + return err + } + + if err := UseCustomUnpopulate(modelsSerdeGoFile, "AcsAdvancedMessageReceivedEventData.Error", "unmarshalInternalACSAdvancedMessageChannelEventError"); err != nil { + return err + } + } + + { + if err := SwapType(syms.Get("AcsRouterJobClassificationFailedEventData.Errors"), "[]*Error"); err != nil { + return err + } + + if err := UseCustomUnpopulate(modelsSerdeGoFile, "AcsRouterJobClassificationFailedEventData.Errors", "unmarshalInternalACSRouterCommunicationError"); err != nil { + return err + } + } + + { + if err := gopls.Rename(syms.Get("AcsRouterCommunicationError"), "internalAcsRouterCommunicationError"); err != nil { + return err + } + + if err := SwapType(syms.Get("AcsRouterJobClassificationFailedEventData.Errors"), "[]*Error"); err != nil { + return err + } + + if err := UseCustomUnpopulate(modelsSerdeGoFile, "AcsRouterJobClassificationFailedEventData.Errors", "unmarshalInternalACSRouterCommunicationError"); err != nil { + return err + } + } + + syms, err = gopls.Symbols(modelsGoFile) + + if err != nil { + return err + } + + allowedErrs := map[string]bool{ + "MediaJobError": true, + } + + for _, sym := range syms.All() { + if allowedErrs[sym.Name] { + continue + } + + if strings.HasSuffix(sym.Name, "Error") && !strings.HasPrefix(sym.Name, "internal") && sym.Type == "Struct" { + return fmt.Errorf("found redundant unhandled error type %s\n", sym.Name) + } + } + + return nil +} + func generateSystemEventEnum() error { reader, err := os.Open(modelsGoFile) @@ -83,9 +158,8 @@ func deleteUnneededFiles() { } type rename struct { - Orig gopls.Symbol - New string - FileName string + Orig *gopls.Symbol + New string } func doRenames() error { @@ -103,11 +177,11 @@ func doRenames() error { phase1Repls := getConstantsReplacements(constantSyms) - phase1Repls = append(phase1Repls, rename{ - FileName: "models.go", - Orig: modelsSyms["AcsRouterCommunicationError.Innererror"], - New: "InnerError", - }) + // We don't need to do this since we're not holding onto this error type anymore. + // phase1Repls = append(phase1Repls, rename{ + // Orig: modelsSyms.Get("AcsRouterCommunicationError.Innererror"), + // New: "InnerError", + // }) modelRepls := getModelsReplacements(modelsSyms) @@ -116,16 +190,16 @@ func doRenames() error { now := time.Now() for i, repl := range phase1Repls { - fmt.Printf("%s[%d/%d]: %s -> %s\n", repl.FileName, i+1, total, repl.Orig.Name, repl.New) - if err := gopls.Rename(repl.FileName, repl.Orig, repl.New); err != nil { + fmt.Printf("%s[%d/%d]: %s -> %s\n", repl.Orig.File, i+1, total, repl.Orig.Name, repl.New) + if err := gopls.Rename(repl.Orig, repl.New); err != nil { return err } } for i, repl := range modelRepls { idx := 1 + i + len(phase1Repls) - fmt.Printf("%s[%d/%d]: %s -> %s\n", repl.FileName, idx, total, repl.Orig.Name, repl.New) - if err := gopls.Rename(repl.FileName, repl.Orig, repl.New); err != nil { + fmt.Printf("%s[%d/%d]: %s -> %s\n", repl.Orig.File, idx, total, repl.Orig.Name, repl.New) + if err := gopls.Rename(repl.Orig, repl.New); err != nil { return err } } @@ -162,30 +236,28 @@ func fixComments(modelRepls []rename) error { return os.WriteFile(constantsGoFile, constantsBytes, 0700) } -func getConstantsReplacements(syms map[string]gopls.Symbol) []rename { +func getConstantsReplacements(syms *gopls.SymbolMap) []rename { typeRE := regexp.MustCompile(`^(Acs|Avs|Iot)([A-Za-z0-9]+)$`) possibleRE := regexp.MustCompile(`^(Possible)(Acs|Avs|Iot)([A-Za-z0-9]+)$`) var renames []rename - for k, sym := range syms { - matches := typeRE.FindStringSubmatch(k) + for _, sym := range syms.All() { + matches := typeRE.FindStringSubmatch(sym.Name) if matches != nil { renames = append(renames, rename{ - FileName: constantsGoFile, - Orig: sym, - New: strings.ToUpper(matches[1]) + matches[2], + Orig: sym, + New: strings.ToUpper(matches[1]) + matches[2], }) } - matches = possibleRE.FindStringSubmatch(k) + matches = possibleRE.FindStringSubmatch(sym.Name) if matches != nil { renames = append(renames, rename{ - FileName: constantsGoFile, - Orig: sym, - New: matches[1] + strings.ToUpper(matches[2]) + matches[3], + Orig: sym, + New: matches[1] + strings.ToUpper(matches[2]) + matches[3], }) } } @@ -196,19 +268,18 @@ func getConstantsReplacements(syms map[string]gopls.Symbol) []rename { return renames } -func getModelsReplacements(syms map[string]gopls.Symbol) []rename { +func getModelsReplacements(syms *gopls.SymbolMap) []rename { typeRE := regexp.MustCompile(`^(Acs|Avs|Iot)([A-Za-z0-9]+)$`) var renames []rename - for k, sym := range syms { - matches := typeRE.FindStringSubmatch(k) + for _, sym := range syms.All() { + matches := typeRE.FindStringSubmatch(sym.Name) if matches != nil { renames = append(renames, rename{ - FileName: modelsGoFile, - Orig: sym, - New: strings.ToUpper(matches[1]) + matches[2], + Orig: sym, + New: strings.ToUpper(matches[1]) + matches[2], }) } } diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_constants.go b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_constants.go index 7b3d00f5f33a..0818bf465252 100644 --- a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_constants.go +++ b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_constants.go @@ -20,6 +20,7 @@ import ( const systemEventsGoFile = "system_events.go" const modelsGoFile = "models.go" +const modelsSerdeGoFile = "models_serde.go" const constantsGoFile = "constants.go" const header = `//go:build go1.18 diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_test.go b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_test.go new file mode 100644 index 000000000000..5989e0f9efe1 --- /dev/null +++ b/sdk/messaging/eventgrid/azsystemevents/internal/generate/generate_test.go @@ -0,0 +1,142 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package main + +import ( + "os" + "os/exec" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/messaging/eventgrid/azsystemevents/internal/gopls" + "github.com/stretchr/testify/require" +) + +func checkGopls(t *testing.T) { + cmd := exec.Command("gopls", "--help") + + if err := cmd.Run(); err != nil { + t.Skipf("Skipping gopls based test since gopls is not on the path. Install with `go install golang.org/x/tools/gopls@latest`") + } +} + +func TestUseCustomUnpopulate(t *testing.T) { + goCode := `// UnmarshalJSON implements the json.Unmarshaller interface for type MyTypeName. +func (a *MyTypeName) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "context": + err = unpopulate(val, "Context", &a.Context) + delete(rawMsg, key) + case "error": + err = unpopulate(val, "Error", &a.Error) + delete(rawMsg, key) + case "from": + err = unpopulate(val, "From", &a.From) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} +` + + expectedGoCode := `// UnmarshalJSON implements the json.Unmarshaller interface for type MyTypeName. +func (a *MyTypeName) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "context": + err = unpopulate(val, "Context", &a.Context) + delete(rawMsg, key) + case "error": + err = customUnmarshaller(val, "Error", &a.Error) + delete(rawMsg, key) + case "from": + err = unpopulate(val, "From", &a.From) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} +` + + tmpFileName := writeTempFile(t, goCode) + + err := UseCustomUnpopulate(tmpFileName, "MyTypeName.Error", "customUnmarshaller") + require.NoError(t, err) + + buff, err := os.ReadFile(tmpFileName) + require.NoError(t, err) + + require.Equal(t, expectedGoCode, string(buff)) +} + +func TestSwapType(t *testing.T) { + checkGopls(t) + + goCode := ` +package main + +type MyStruct struct { + TestField string + SomeOtherField string +} +` + + expectedGoCode := ` +package main + +type MyStruct struct { + TestField *ANewType + SomeOtherField string +} +` + + tmpFileName := writeTempFile(t, goCode) + + symbols, err := gopls.Symbols(tmpFileName) + require.NoError(t, err) + require.NotEmpty(t, symbols) + + sym := symbols.Get("MyStruct.TestField") + err = SwapType(sym, "*ANewType") + require.NoError(t, err) + + newBuff, err := os.ReadFile(tmpFileName) + require.NoError(t, err) + + require.Equal(t, expectedGoCode, string(newBuff)) +} + +func writeTempFile(t *testing.T, contents string) string { + tmpFile, err := os.CreateTemp("", "tempfile*.go") + require.NoError(t, err) + + t.Cleanup(func() { os.Remove(tmpFile.Name()) }) + + _, err = tmpFile.Write([]byte(contents)) + require.NoError(t, err) + + err = tmpFile.Close() + require.NoError(t, err) + + return tmpFile.Name() +} diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/generate/regex_helpers.go b/sdk/messaging/eventgrid/azsystemevents/internal/generate/regex_helpers.go new file mode 100644 index 000000000000..33bf7477293e --- /dev/null +++ b/sdk/messaging/eventgrid/azsystemevents/internal/generate/regex_helpers.go @@ -0,0 +1,116 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package main + +import ( + "bufio" + "bytes" + "fmt" + "os" + "regexp" + "strings" + + "github.com/Azure/azure-sdk-for-go/sdk/messaging/eventgrid/azsystemevents/internal/gopls" +) + +// DeleteType removes a type from models.go and it's associated marshalling functions from models_serde.go. +func DeleteType(model string) error { + deleteModelTypeRE := regexp.MustCompile(fmt.Sprintf(`(?s)// %s -.+?\n}\n`, model)) + deleteModelFuncsRE := regexp.MustCompile(fmt.Sprintf(`(?s)// (UnmarshalJSON) implements the (json\.Unmarshaller) interface for type %s.+?\n}\n`, model)) + + modelsGoBytes, err := os.ReadFile(modelsGoFile) + + if err != nil { + return err + } + + newModelsGoBytes := deleteModelTypeRE.ReplaceAll(modelsGoBytes, nil) + + if bytes.Equal(modelsGoBytes, newModelsGoBytes) { + return fmt.Errorf("no match or changes in %s for model %s. Is the type name correct?", modelsGoFile, model) + } + + if err := os.WriteFile(modelsGoFile, newModelsGoBytes, 0700); err != nil { + return err + } + + modelsSerdeGoBytes, err := os.ReadFile(modelsSerdeGoFile) + + if err != nil { + return err + } + + newModelsSerdeGoBytes := deleteModelFuncsRE.ReplaceAll(modelsSerdeGoBytes, nil) + + if bytes.Equal(modelsSerdeGoBytes, newModelsSerdeGoBytes) { + return fmt.Errorf("no match or changes in %s for model %s. Is the type name correct?", modelsGoFile, model) + } + + return os.WriteFile(modelsSerdeGoFile, newModelsSerdeGoBytes, 0700) +} + +// SwapType changes the declared type for the symbol, which is expected to be a field +func SwapType(sym *gopls.Symbol, newType string) error { + if sym.Type != gopls.SymbolTypeField { + return fmt.Errorf("can only swap types for a field, not a %s", sym.Type) + } + + lineNum, err := sym.StartLine() + + if err != nil { + return err + } + + file, err := os.Open(sym.File) + + if err != nil { + return err + } + + defer file.Close() + + b := strings.Builder{} + scanner := bufio.NewScanner(file) + + i := int64(0) + for scanner.Scan() { + i++ + + if lineNum == i { + // splitting something like "FieldName string" + parts := strings.SplitN(scanner.Text(), " ", 2) + b.WriteString(parts[0] + " " + newType + "\n") + } else { + b.WriteString(scanner.Text() + "\n") + } + } + + if err := file.Close(); err != nil { + return err + } + + return os.WriteFile(sym.File, []byte(b.String()), 0600) +} + +func UseCustomUnpopulate(filename string, symbolName string, newFuncCall string) error { + parts := strings.Split(symbolName, ".") + buff, err := os.ReadFile(filename) + + if err != nil { + return err + } + + re := regexp.MustCompile( + // ex: 'func (a *AcsAdvancedMessageReceivedEventData) UnmarshalJSON(data []byte) error {' + `(?s)(func \([a-zA-Z]+? \*` + parts[0] + `\) UnmarshalJSON\(data \[\]byte\) error \{.+?` + + // ex: 'err = unpopulate(val, "Content", &a.Content)' + `err = )unpopulate(\(val, "` + parts[1] + `")`) + + newBuff := re.ReplaceAll(buff, []byte("$1 "+newFuncCall+"$2")) + + return os.WriteFile(filename, newBuff, 0600) +} diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/gopls/gopls.go b/sdk/messaging/eventgrid/azsystemevents/internal/gopls/gopls.go index a3f3bcdddabc..c17fb520db9a 100644 --- a/sdk/messaging/eventgrid/azsystemevents/internal/gopls/gopls.go +++ b/sdk/messaging/eventgrid/azsystemevents/internal/gopls/gopls.go @@ -9,32 +9,95 @@ package gopls import ( "bufio" "bytes" - "errors" "fmt" + "log" "os" "os/exec" + "regexp" + "strconv" "strings" ) +// SymbolType maps to the second field in the `gopls symbols` output. +type SymbolType string + +const ( + SymbolTypeConstant SymbolType = "Constant" + SymbolTypeClass SymbolType = "Class" // (ex: ACSRouterJobStatus, from 'type ACSRouterJobStatus string') + SymbolTypeStruct SymbolType = "Struct" + SymbolTypeField SymbolType = "Field" + SymbolTypeFunction SymbolType = "Function" + SymbolTypeMethod SymbolType = "Method" // ex: '(*WebBackupOperationCompletedEventData).UnmarshalJSON' +) + type Symbol struct { Name string - // Either: - // - Constant - // - Class (type ACSRouterJobStatus string) - // - Struct - // - Field - // - Function - // - Method - Type string + Type SymbolType + + // Position is a start and end range for a symbol + // ex: 36:2-36:7 + // (line 36, columns 2 - 7) Position string + + File string +} + +type SymbolMap struct { + m map[string]*Symbol } -func Rename(filename string, sym Symbol, newName string) error { - if sym.Name == "" && sym.Position == "" && sym.Type == "" { - return errors.New("attempted to rename with an empty symbol") +func NewSymbolMap(m map[string]*Symbol) *SymbolMap { + newM := map[string]*Symbol{} + + for k, v := range m { + newM[strings.ToLower(k)] = v } - cmd := exec.Command("gopls", "rename", "-w", filename+":"+sym.Position, newName) + return &SymbolMap{m: newM} +} + +// Get retrieves a symbol, ignoring casing. +func (s SymbolMap) Get(name string) *Symbol { + v, exists := s.m[strings.ToLower(name)] + + if !exists { + log.Fatalf("No key exists for %q", name) + } + + return v +} + +// All gets all the symbols within our map, in no specific order. +func (s SymbolMap) All() []*Symbol { + var all []*Symbol + + for _, v := range s.m { + all = append(all, v) + } + + return all +} + +// ex: 36:2-36:7 +var posRE = regexp.MustCompile(`(\d+):(\d+)-(\d+):(\d+)`) + +// StartLine returns the starting line for this symbol. +func (s Symbol) StartLine() (int64, error) { + var matches = posRE.FindStringSubmatch(s.Position) + + if matches == nil { + return 0, fmt.Errorf("couldn't parse position %q", s.Position) + } + + return strconv.ParseInt(matches[1], 10, 64) +} + +// Rename renames a given symbol to a new name. This naming will propagate +// throughout, including references to the type, the type name itself and +// any comments that contain the type name in godoc's reference format +// with '[typename]'. +func Rename(sym *Symbol, newName string) error { + cmd := exec.Command("gopls", "rename", "-w", sym.File+":"+sym.Position, newName) if err := cmd.Run(); err != nil { return err @@ -43,7 +106,8 @@ func Rename(filename string, sym Symbol, newName string) error { return nil } -func Symbols(filename string) (map[string]Symbol, error) { +// Symbols parses the output of `gopls symbols`. +func Symbols(filename string) (*SymbolMap, error) { if _, err := os.Stat(filename); err != nil { return nil, err } @@ -55,14 +119,14 @@ func Symbols(filename string) (map[string]Symbol, error) { cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { - return nil, err + return nil, fmt.Errorf("failed getting symbols for %s: %w", filename, err) } allBytes := stdout.Bytes() scanner := bufio.NewScanner(bytes.NewReader(allBytes)) - m := map[string]Symbol{} + m := map[string]*Symbol{} prevParent := "" for scanner.Scan() { @@ -93,20 +157,21 @@ func Symbols(filename string) (map[string]Symbol, error) { sym := Symbol{ Name: fields[0], - Type: fields[1], + Type: SymbolType(fields[1]), Position: fields[2], + File: filename, } if _, exists := m[sym.Name]; exists { return nil, fmt.Errorf("%s was in the map twice", sym.Name) } - m[sym.Name] = sym + m[sym.Name] = &sym - if sym.Type != "Field" { + if sym.Type != SymbolTypeField { prevParent = sym.Name } } - return m, nil + return NewSymbolMap(m), nil } diff --git a/sdk/messaging/eventgrid/azsystemevents/models.go b/sdk/messaging/eventgrid/azsystemevents/models.go index dd7e486df01f..d3a24cc3bbac 100644 --- a/sdk/messaging/eventgrid/azsystemevents/models.go +++ b/sdk/messaging/eventgrid/azsystemevents/models.go @@ -288,8 +288,8 @@ type ACSAdvancedMessageButtonContent struct { Text *string } -// ACSAdvancedMessageChannelEventError - Advanced Message Channel Event Error -type ACSAdvancedMessageChannelEventError struct { +// internalACSAdvancedMessageChannelEventError - Advanced Message Channel Event Error +type internalACSAdvancedMessageChannelEventError struct { // The channel error code ChannelCode *string @@ -313,7 +313,7 @@ type ACSAdvancedMessageDeliveryStatusUpdatedEventData struct { ChannelType *ACSMessageChannelType // The channel event error - Error *ACSAdvancedMessageChannelEventError + Error *internalACSAdvancedMessageChannelEventError // The message sender From *string @@ -334,7 +334,7 @@ type ACSAdvancedMessageDeliveryStatusUpdatedEventData struct { // ACSAdvancedMessageEventData - Schema of common properties of all chat thread events type ACSAdvancedMessageEventData struct { // The channel event error - Error *ACSAdvancedMessageChannelEventError + Error *internalACSAdvancedMessageChannelEventError // The message sender From *string @@ -412,7 +412,7 @@ type ACSAdvancedMessageReceivedEventData struct { Context *ACSAdvancedMessageContext // The channel event error - Error *ACSAdvancedMessageChannelEventError + Error *Error // The message sender From *string @@ -1182,16 +1182,16 @@ type ACSRouterChannelConfiguration struct { MaxNumberOfJobs *int32 } -// ACSRouterCommunicationError - Router Communication Error -type ACSRouterCommunicationError struct { +// internalAcsRouterCommunicationError - Router Communication Error +type internalAcsRouterCommunicationError struct { // Router Communication Error Code Code *string // List of Router Communication Errors - Details []ACSRouterCommunicationError + Details []internalAcsRouterCommunicationError // Router Communication Inner Error - InnerError *ACSRouterCommunicationError + Innererror *internalAcsRouterCommunicationError // Router Communication Error Message Message *string @@ -1253,7 +1253,7 @@ type ACSRouterJobClassificationFailedEventData struct { ClassificationPolicyID *string // Router Job Classification Failed Errors - Errors []ACSRouterCommunicationError + Errors []*Error // Router Event Job ID JobID *string diff --git a/sdk/messaging/eventgrid/azsystemevents/models_serde.go b/sdk/messaging/eventgrid/azsystemevents/models_serde.go index acc791aee8d9..37322763f501 100644 --- a/sdk/messaging/eventgrid/azsystemevents/models_serde.go +++ b/sdk/messaging/eventgrid/azsystemevents/models_serde.go @@ -850,16 +850,16 @@ func (a *ACSAdvancedMessageButtonContent) UnmarshalJSON(data []byte) error { return nil } -// MarshalJSON implements the json.Marshaller interface for type ACSAdvancedMessageChannelEventError. -func (a ACSAdvancedMessageChannelEventError) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type AcsAdvancedMessageChannelEventError. +func (a internalACSAdvancedMessageChannelEventError) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "channelCode", a.ChannelCode) populate(objectMap, "channelMessage", a.ChannelMessage) return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type ACSAdvancedMessageChannelEventError. -func (a *ACSAdvancedMessageChannelEventError) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type AcsAdvancedMessageChannelEventError. +func (a *internalACSAdvancedMessageChannelEventError) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -1180,7 +1180,7 @@ func (a *ACSAdvancedMessageReceivedEventData) UnmarshalJSON(data []byte) error { err = unpopulate(val, "Context", &a.Context) delete(rawMsg, key) case "error": - err = unpopulate(val, "Error", &a.Error) + err = unmarshalInternalACSAdvancedMessageChannelEventError(val, "Error", &a.Error) delete(rawMsg, key) case "from": err = unpopulate(val, "From", &a.From) @@ -2789,19 +2789,19 @@ func (a *ACSRouterChannelConfiguration) UnmarshalJSON(data []byte) error { return nil } -// MarshalJSON implements the json.Marshaller interface for type ACSRouterCommunicationError. -func (a ACSRouterCommunicationError) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type AcsRouterCommunicationError. +func (a internalAcsRouterCommunicationError) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "code", a.Code) populate(objectMap, "details", a.Details) - populate(objectMap, "innererror", a.InnerError) + populate(objectMap, "innererror", a.Innererror) populate(objectMap, "message", a.Message) populate(objectMap, "target", a.Target) return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type ACSRouterCommunicationError. -func (a *ACSRouterCommunicationError) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type AcsRouterCommunicationError. +func (a *internalAcsRouterCommunicationError) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -2816,7 +2816,7 @@ func (a *ACSRouterCommunicationError) UnmarshalJSON(data []byte) error { err = unpopulate(val, "Details", &a.Details) delete(rawMsg, key) case "innererror": - err = unpopulate(val, "Innererror", &a.InnerError) + err = unpopulate(val, "Innererror", &a.Innererror) delete(rawMsg, key) case "message": err = unpopulate(val, "Message", &a.Message) @@ -2955,7 +2955,7 @@ func (a *ACSRouterJobClassificationFailedEventData) UnmarshalJSON(data []byte) e err = unpopulate(val, "ClassificationPolicyID", &a.ClassificationPolicyID) delete(rawMsg, key) case "errors": - err = unpopulate(val, "Errors", &a.Errors) + err = unmarshalInternalACSRouterCommunicationError(val, "Errors", &a.Errors) delete(rawMsg, key) case "jobId": err = unpopulate(val, "JobID", &a.JobID) diff --git a/sdk/messaging/eventgrid/azsystemevents/system_events4_test.go b/sdk/messaging/eventgrid/azsystemevents/system_events4_test.go index 228adf99b012..a444fb1e68d6 100644 --- a/sdk/messaging/eventgrid/azsystemevents/system_events4_test.go +++ b/sdk/messaging/eventgrid/azsystemevents/system_events4_test.go @@ -974,6 +974,6 @@ func TestConsumeCloudEventAcsRouterJobClassificationFailedEvent(t *testing.T) { var errors = sysEvent.Errors require.Equal(t, 1, len(errors)) - require.Equal(t, "Failure", *errors[0].Code) - require.Equal(t, "Classification failed due to ", *errors[0].Message) + require.Equal(t, "Failure", (*errors[0]).Code) + require.Equal(t, "Classification failed due to ", (*errors[0]).Error()) } From 9757d431df698af405599f08c41427da98d8e44b Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 25 Mar 2024 17:18:28 -0700 Subject: [PATCH 08/12] Format errors rather than returning them. --- .../eventgrid/azsystemevents/custom_events.go | 61 +++-- .../azsystemevents/custom_events_test.go | 227 +++++++++++++----- .../eventgrid/azsystemevents/error.go | 6 - 3 files changed, 212 insertions(+), 82 deletions(-) diff --git a/sdk/messaging/eventgrid/azsystemevents/custom_events.go b/sdk/messaging/eventgrid/azsystemevents/custom_events.go index 17e6135807cd..fdb376bc5347 100644 --- a/sdk/messaging/eventgrid/azsystemevents/custom_events.go +++ b/sdk/messaging/eventgrid/azsystemevents/custom_events.go @@ -9,6 +9,7 @@ package azsystemevents import ( "encoding/json" "fmt" + "strings" ) //type IotHubDeviceConnectedEventData DeviceConnectionStateEventProperties @@ -34,42 +35,60 @@ func unmarshalInternalACSAdvancedMessageChannelEventError(val json.RawMessage, f return nil } -func unmarshalInternalACSRouterCommunicationError(val json.RawMessage, fn string, re *[]*Error) error { - type superError struct { - Code string - InnerError *superError - Details []*superError - Message string +func unpackMsg(err *internalAcsRouterCommunicationError, indent string) string { + if err == nil { + return "" } - var unpack func(err *superError) *Error + sb := strings.Builder{} - unpack = func(err *superError) *Error { - if err == nil { - return nil - } + code := "" + if err.Code != nil { + code = *err.Code + } - e := &Error{ - Code: err.Code, - message: err.Message, - InnerError: unpack(err.InnerError), - } + message := "" + if err.Message != nil { + message = *err.Message + } + + sb.WriteString(fmt.Sprintf("%sCode: %s\n%sMessage: %s\n", indent, code, indent, message)) - for _, detailErr := range err.Details { - e.Details = append(e.Details, unpack(detailErr)) + if len(err.Details) > 0 { + for i, detailErr := range err.Details { + sb.WriteString(fmt.Sprintf("%sDetails[%d]:\n%s", indent, i, unpackMsg(&detailErr, indent+" "))) } + } - return e + if err.Innererror != nil { + sb.WriteString(fmt.Sprintf("%sInnerError:\n%s", indent, unpackMsg(err.Innererror, indent+" "))) } - var tmp []*superError + return sb.String() +} + +func unmarshalInternalACSRouterCommunicationError(val json.RawMessage, fn string, re *[]*Error) error { + var tmp []internalAcsRouterCommunicationError if err := json.Unmarshal(val, &tmp); err != nil { return fmt.Errorf("struct field %s: %v", fn, err) } for _, se := range tmp { - *re = append(*re, unpack(se)) + code := "" + + if se.Code != nil { + code = *se.Code + } + + e := &Error{ + Code: code, + // we're going to compress the remainder of these details into a + // string. + message: unpackMsg(&se, ""), + } + + *re = append(*re, e) } return nil diff --git a/sdk/messaging/eventgrid/azsystemevents/custom_events_test.go b/sdk/messaging/eventgrid/azsystemevents/custom_events_test.go index 60296dd395d3..7ddd3936df74 100644 --- a/sdk/messaging/eventgrid/azsystemevents/custom_events_test.go +++ b/sdk/messaging/eventgrid/azsystemevents/custom_events_test.go @@ -4,10 +4,22 @@ import ( "encoding/json" "testing" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" "github.com/stretchr/testify/require" ) func TestUnmarshalInternalACSRouterCommunicationError(t *testing.T) { + t.Run("null", func(t *testing.T) { + var unmarshalledErrs []*Error + err := unmarshalInternalACSRouterCommunicationError(json.RawMessage("null"), "FieldName", &unmarshalledErrs) + require.NoError(t, err) + require.Empty(t, unmarshalledErrs) + + err = unmarshalInternalACSRouterCommunicationError(json.RawMessage("[{ \"Code\": null }]"), "FieldName", &unmarshalledErrs) + require.NoError(t, err) + require.Empty(t, unmarshalledErrs[0].Code) + }) + t.Run("single", func(t *testing.T) { text := `[ { @@ -25,15 +37,13 @@ func TestUnmarshalInternalACSRouterCommunicationError(t *testing.T) { var unmarshalledErrs []*Error err := unmarshalInternalACSRouterCommunicationError(json.RawMessage(text), "FieldName", &unmarshalledErrs) require.NoError(t, err) - require.Equal(t, []*Error{ - { - Code: "Failure", - message: "Classification failed due to ", - InnerError: &Error{ - Code: "InnerFailure", message: "Classification failed due to ", - }, - }, - }, unmarshalledErrs) + + require.Equal(t, "Failure", unmarshalledErrs[0].Code) + require.Equal(t, "Code: Failure\n"+ + "Message: Classification failed due to \n"+ + "InnerError:\n"+ + " Code: InnerFailure\n"+ + " Message: Classification failed due to \n", unmarshalledErrs[0].Error()) }) t.Run("Multiple", func(t *testing.T) { @@ -51,64 +61,171 @@ func TestUnmarshalInternalACSRouterCommunicationError(t *testing.T) { var unmarshalledErrs []*Error err := unmarshalInternalACSRouterCommunicationError(json.RawMessage(text), "FieldName", &unmarshalledErrs) require.NoError(t, err) - require.Equal(t, []*Error{ - {Code: "Failure", message: "Classification failed due to "}, - {Code: "FailureAsWell", message: "Classification failed due to "}, - }, unmarshalledErrs) + + require.Equal(t, "Failure", unmarshalledErrs[0].Code) + require.Equal(t, "Code: Failure\n"+ + "Message: Classification failed due to \n", unmarshalledErrs[0].Error()) + require.Equal(t, "FailureAsWell", unmarshalledErrs[1].Code) + require.Equal(t, "Code: FailureAsWell\n"+ + "Message: Classification failed due to \n", unmarshalledErrs[1].Error()) }) +} - t.Run("Recursive", func(t *testing.T) { - text := `[ - { - "code": "Failure", - "message": "FailureMessage", +func TestUnmarshalInternalAcsRouterCCSmunicationErrorRecursive(t *testing.T) { + text := `[ + { + "code": "Root.Failure", + "message": "Root.Message", + "innererror": { + "code": "Root->Inner.Failure", + "message": "Root->Inner.Message", "innererror": { - "code": "InnerFailure", - "message": "InnerFailureMessage", - "innererror": { - "code": "Inner.InnerFailure", - "message": "Inner.InnerFailureMessage" - } + "code": "Root->Inner->Inner.Failure", + "message": "Root->Inner->Inner.Message" }, "details": [ { - "code": "Detail", - "message": "DetailMessage", + "code": "Root->Inner->Details[0].Failure", + "message": "Root->Inner->Details[0].Message", "innererror": { - "code": "Detail.InnerFailure", - "message": "Detail.InnerFailure.Message" + "code": "Root->Inner->Details[0].Inner.Failure", + "message": "Root->Inner->Details[0].Inner.Message" } - } + } ] - } - ]` + }, + "details": [ + { + "code": "Root->Details[0].Failure", + "message": "Root->Details[0].Message", + "innererror": { + "code": "Root->Details[0]->Inner.Failure", + "message": "Root->Details[0]->Inner.Message" + } + } + ] + } + ]` - var unmarshalledErrs []*Error - err := unmarshalInternalACSRouterCommunicationError(json.RawMessage(text), "FieldName", &unmarshalledErrs) - require.NoError(t, err) - require.Equal(t, []*Error{ - { - Code: "Failure", - message: "FailureMessage", - InnerError: &Error{ - Code: "InnerFailure", - message: "InnerFailureMessage", - InnerError: &Error{ - Code: "Inner.InnerFailure", - message: "Inner.InnerFailureMessage", - }, + var unmarshalledErrs []*Error + err := unmarshalInternalACSRouterCommunicationError(json.RawMessage(text), "FieldName", &unmarshalledErrs) + require.NoError(t, err) + + require.NotEmpty(t, unmarshalledErrs) + require.Equal(t, "Root.Failure", unmarshalledErrs[0].Code) + + expectedMsg := "Code: Root.Failure\n" + + "Message: Root.Message\n" + + "Details[0]:\n" + + " Code: Root->Details[0].Failure\n" + + " Message: Root->Details[0].Message\n" + + " InnerError:\n" + + " Code: Root->Details[0]->Inner.Failure\n" + + " Message: Root->Details[0]->Inner.Message\n" + + "InnerError:\n" + + " Code: Root->Inner.Failure\n" + + " Message: Root->Inner.Message\n" + + " Details[0]:\n" + + " Code: Root->Inner->Details[0].Failure\n" + + " Message: Root->Inner->Details[0].Message\n" + + " InnerError:\n" + + " Code: Root->Inner->Details[0].Inner.Failure\n" + + " Message: Root->Inner->Details[0].Inner.Message\n" + + " InnerError:\n" + + " Code: Root->Inner->Inner.Failure\n" + + " Message: Root->Inner->Inner.Message\n" + + require.Equal(t, expectedMsg, unmarshalledErrs[0].Error()) +} + +func TestFormattingErrors(t *testing.T) { + t.Run("simple", func(t *testing.T) { + msg := unpackMsg(&internalAcsRouterCommunicationError{ + Code: to.Ptr("code"), + Message: to.Ptr("message"), + }, "") + + require.Equal(t, "Code: code\n"+ + "Message: message\n", msg) + }) + + t.Run("InnerError", func(t *testing.T) { + msg := unpackMsg(&internalAcsRouterCommunicationError{ + Code: to.Ptr("code"), + Message: to.Ptr("message"), + Innererror: &internalAcsRouterCommunicationError{ + Code: to.Ptr("inner.code"), + Message: to.Ptr("inner.message"), + }, + }, "") + + require.Equal(t, "Code: code\n"+ + "Message: message\n"+ + "InnerError:\n"+ + " Code: inner.code\n"+ + " Message: inner.message\n", msg) + }) + + t.Run("InnerInnerError", func(t *testing.T) { + msg := unpackMsg(&internalAcsRouterCommunicationError{ + Code: to.Ptr("code"), + Message: to.Ptr("message"), + Innererror: &internalAcsRouterCommunicationError{ + Code: to.Ptr("inner.code"), + Message: to.Ptr("inner.message"), + Innererror: &internalAcsRouterCommunicationError{ + Code: to.Ptr("inner->inner.code"), + Message: to.Ptr("inner->inner.message"), }, - Details: []*Error{ - { - Code: "Detail", - message: "DetailMessage", - InnerError: &Error{ - Code: "Detail.InnerFailure", - message: "Detail.InnerFailure.Message", + }, + }, "") + + require.Equal(t, "Code: code\n"+ + "Message: message\n"+ + "InnerError:\n"+ + " Code: inner.code\n"+ + " Message: inner.message\n"+ + " InnerError:\n"+ + " Code: inner->inner.code\n"+ + " Message: inner->inner.message\n", msg) + }) + + t.Run("Details", func(t *testing.T) { + msg := unpackMsg(&internalAcsRouterCommunicationError{ + Code: to.Ptr("code"), + Message: to.Ptr("message"), + Details: []internalAcsRouterCommunicationError{ + { + Code: to.Ptr("details[0].code"), + Message: to.Ptr("details[0].message"), + Details: []internalAcsRouterCommunicationError{ + { + Code: to.Ptr("details[0]->details[0].code"), + Message: to.Ptr("details[0]->details[0].message"), }, - }, - }, + { + Code: to.Ptr("details[0]->details[1].code"), + Message: to.Ptr("details[0]->details[1].message"), + }, + }}, }, - }, unmarshalledErrs) + }, "") + + require.Equal(t, "Code: code\n"+ + "Message: message\n"+ + "Details[0]:\n"+ + " Code: details[0].code\n"+ + " Message: details[0].message\n"+ + " Details[0]:\n"+ + " Code: details[0]->details[0].code\n"+ + " Message: details[0]->details[0].message\n"+ + " Details[1]:\n"+ + " Code: details[0]->details[1].code\n"+ + " Message: details[0]->details[1].message\n", msg) + }) + + t.Run("Errors", func(t *testing.T) { + require.Empty(t, unpackMsg(nil, "")) + require.Equal(t, "Code: \nMessage: \n", unpackMsg(&internalAcsRouterCommunicationError{}, "")) }) } diff --git a/sdk/messaging/eventgrid/azsystemevents/error.go b/sdk/messaging/eventgrid/azsystemevents/error.go index 374b7f429ba7..222e7d50be17 100644 --- a/sdk/messaging/eventgrid/azsystemevents/error.go +++ b/sdk/messaging/eventgrid/azsystemevents/error.go @@ -11,12 +11,6 @@ type Error struct { // Code is an error code from the service producing the system event. Code string - // InnerError can provide more information about the origin of this error. - InnerError *Error - - // Details contains related errors for this error. - Details []*Error - message string } From e291f1caab55c71084bf780ad418e277429a1eb8 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 25 Mar 2024 17:39:32 -0700 Subject: [PATCH 09/12] Fixing test --- .../eventgrid/azsystemevents/system_events4_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sdk/messaging/eventgrid/azsystemevents/system_events4_test.go b/sdk/messaging/eventgrid/azsystemevents/system_events4_test.go index a444fb1e68d6..e2b6afec19b5 100644 --- a/sdk/messaging/eventgrid/azsystemevents/system_events4_test.go +++ b/sdk/messaging/eventgrid/azsystemevents/system_events4_test.go @@ -975,5 +975,9 @@ func TestConsumeCloudEventAcsRouterJobClassificationFailedEvent(t *testing.T) { var errors = sysEvent.Errors require.Equal(t, 1, len(errors)) require.Equal(t, "Failure", (*errors[0]).Code) - require.Equal(t, "Classification failed due to ", (*errors[0]).Error()) + require.Equal(t, "Code: Failure\n"+ + "Message: Classification failed due to \n"+ + "InnerError:\n"+ + " Code: InnerFailure\n"+ + " Message: Classification failed due to \n", (*errors[0]).Error()) } From 0d117a907738c7b5323821f6663e51e57f7772ea Mon Sep 17 00:00:00 2001 From: ripark Date: Tue, 26 Mar 2024 17:29:40 +0000 Subject: [PATCH 10/12] Updating changelog --- sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md b/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md index e52289768d92..dd25646937f4 100644 --- a/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md +++ b/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md @@ -4,7 +4,7 @@ ### Features Added -- Added ACSRouterWorkerUpdatedEventData. +- Added events ACSRouterWorkerUpdatedEventData and ACSAdvancedMessageDeliveryStatusUpdatedEventData. (PR#TBD) ### Breaking Changes From 310758018691e2caa569e343afe6f7c5faaf8d61 Mon Sep 17 00:00:00 2001 From: ripark Date: Tue, 26 Mar 2024 17:31:30 +0000 Subject: [PATCH 11/12] Updating PR number. --- sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md b/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md index dd25646937f4..e7b50b1d121e 100644 --- a/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md +++ b/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md @@ -4,7 +4,7 @@ ### Features Added -- Added events ACSRouterWorkerUpdatedEventData and ACSAdvancedMessageDeliveryStatusUpdatedEventData. (PR#TBD) +- Added events ACSRouterWorkerUpdatedEventData and ACSAdvancedMessageDeliveryStatusUpdatedEventData. (PR#22638) ### Breaking Changes From 09d858e672976fa988fbbae4e28c95b2b6b66cb6 Mon Sep 17 00:00:00 2001 From: ripark Date: Tue, 26 Mar 2024 18:39:32 +0000 Subject: [PATCH 12/12] Bump version to account for breaking changes. --- sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md | 2 +- sdk/messaging/eventgrid/azsystemevents/internal/version.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md b/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md index e7b50b1d121e..f323fcdc87b5 100644 --- a/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md +++ b/sdk/messaging/eventgrid/azsystemevents/CHANGELOG.md @@ -1,6 +1,6 @@ # Release History -## 0.2.1 (TBD) +## 0.3.0 (TBD) ### Features Added diff --git a/sdk/messaging/eventgrid/azsystemevents/internal/version.go b/sdk/messaging/eventgrid/azsystemevents/internal/version.go index 13c31dc4c774..ce7daf2eed71 100644 --- a/sdk/messaging/eventgrid/azsystemevents/internal/version.go +++ b/sdk/messaging/eventgrid/azsystemevents/internal/version.go @@ -9,5 +9,5 @@ const ( ModuleName = "azsystemevents" // ModuleVersion is the semantic version (see http://semver.org) of this module. - ModuleVersion = "v0.2.1" + ModuleVersion = "v0.3.0" )