From f839de425de7ed3a53cc96eba7ecdf3c42af70c2 Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Mon, 31 Jul 2023 07:48:07 -0700 Subject: [PATCH] [azcore/azeventgrid] Remove json.RawMessage usage in the public API (#21282) * azcore: Removing the json.RawMessage dependency in the public API (it wasn't part of the signature (formally) but it was part of the returned type. * Consume new pre-release azcore in azeventgrid. --- sdk/azcore/CHANGELOG.md | 3 ++ sdk/azcore/messaging/cloud_event.go | 8 ++-- sdk/azcore/messaging/cloud_event_test.go | 2 +- .../messaging/example_usingcloudevent_test.go | 2 +- sdk/messaging/azeventgrid/client_test.go | 6 +-- .../example_publish_and_receive_test.go | 45 ++++++++++++++----- sdk/messaging/azeventgrid/go.mod | 7 ++- 7 files changed, 52 insertions(+), 21 deletions(-) diff --git a/sdk/azcore/CHANGELOG.md b/sdk/azcore/CHANGELOG.md index 6c2ef0c5cf07..2fc41a00887e 100644 --- a/sdk/azcore/CHANGELOG.md +++ b/sdk/azcore/CHANGELOG.md @@ -7,6 +7,9 @@ * Added function `SanitizePagerPollerPath` to the `server` package to centralize sanitization and formalize the contract. ### Breaking Changes + +* `messaging.CloudEvent` deserializes JSON objects as `[]byte`, instead of `json.RawMessage`. See the documentation for CloudEvent.Data for more information. + > These changes affect only code written against beta versions `v1.7.0-beta.2` and `v1.8.0-beta.1`. * Removed parameter from method `Span.End()` and its type `tracing.SpanEndOptions`. This API GA'ed in `v1.2.0` so we cannot change it. diff --git a/sdk/azcore/messaging/cloud_event.go b/sdk/azcore/messaging/cloud_event.go index 22d5855a0dd3..7cac3ed26342 100644 --- a/sdk/azcore/messaging/cloud_event.go +++ b/sdk/azcore/messaging/cloud_event.go @@ -44,12 +44,12 @@ type CloudEvent struct { // Data is the payload for the event. // * []byte will be serialized and deserialized as []byte. // * Any other type will be serialized to a JSON object and deserialized into - // a [json.RawMessage]. + // a []byte, containing the JSON text. // - // To deserialize a [json.RawMessage] into your chosen type: + // To deserialize into your chosen type: // // var yourData *YourType - // json.Unmarshal(cloudEvent.Data.(json.RawMessage), &yourData) + // json.Unmarshal(cloudEvent.Data.([]byte), &yourData) // Data any @@ -240,7 +240,7 @@ func updateFieldFromValue(ce *CloudEvent, k string, raw json.RawMessage) error { // case "data": // let the user deserialize so they can put it into their own native type. - ce.Data = raw + ce.Data = []byte(raw) case "datacontenttype": return json.Unmarshal(raw, &ce.DataContentType) case "dataschema": diff --git a/sdk/azcore/messaging/cloud_event_test.go b/sdk/azcore/messaging/cloud_event_test.go index 1cd168ad1471..4e8567b81df1 100644 --- a/sdk/azcore/messaging/cloud_event_test.go +++ b/sdk/azcore/messaging/cloud_event_test.go @@ -62,7 +62,7 @@ func TestCloudEventJSONData(t *testing.T) { actualCE := roundTrip(t, ce) var dest *map[string]string - require.NoError(t, json.Unmarshal(actualCE.Data.(json.RawMessage), &dest)) + require.NoError(t, json.Unmarshal(actualCE.Data.([]byte), &dest)) require.Equal(t, data, *dest) } diff --git a/sdk/azcore/messaging/example_usingcloudevent_test.go b/sdk/azcore/messaging/example_usingcloudevent_test.go index 1f262db6df1e..0766f0d49f40 100644 --- a/sdk/azcore/messaging/example_usingcloudevent_test.go +++ b/sdk/azcore/messaging/example_usingcloudevent_test.go @@ -32,7 +32,7 @@ func Example_usingCloudEvent() { var receivedData *sampleType - if err := json.Unmarshal(receivedEvent.Data.(json.RawMessage), &receivedData); err != nil { + if err := json.Unmarshal(receivedEvent.Data.([]byte), &receivedData); err != nil { panic(err) } diff --git a/sdk/messaging/azeventgrid/client_test.go b/sdk/messaging/azeventgrid/client_test.go index 0d1441b5972d..98d8ed0235ca 100644 --- a/sdk/messaging/azeventgrid/client_test.go +++ b/sdk/messaging/azeventgrid/client_test.go @@ -237,7 +237,7 @@ func TestPublishingAndReceivingCloudEvents(t *testing.T) { SpecVersion: "1.0", Source: "hello-source", Type: "eventType", - Data: json.RawMessage("\"hello world 1\""), + Data: []byte("\"hello world 1\""), }, resp.Value[0].Event) requireEqualCloudEvent(t, messaging.CloudEvent{ @@ -245,7 +245,7 @@ func TestPublishingAndReceivingCloudEvents(t *testing.T) { Source: "hello-source", Type: "eventType", DataSchema: to.Ptr("https://dataschema"), - Data: json.RawMessage("\"hello world 2\""), + Data: []byte("\"hello world 2\""), DataContentType: to.Ptr("data content type"), Subject: to.Ptr("subject"), Extensions: map[string]any{ @@ -260,7 +260,7 @@ func TestPublishingAndReceivingCloudEvents(t *testing.T) { SpecVersion: "1.0", Source: "hello-source", Type: "eventType", - Data: json.RawMessage(bytes), + Data: []byte(bytes), }, resp.Value[2].Event) ackArgs := azeventgrid.AcknowledgeOptions{} diff --git a/sdk/messaging/azeventgrid/example_publish_and_receive_test.go b/sdk/messaging/azeventgrid/example_publish_and_receive_test.go index 5060af75b631..bad8775ed79f 100644 --- a/sdk/messaging/azeventgrid/example_publish_and_receive_test.go +++ b/sdk/messaging/azeventgrid/example_publish_and_receive_test.go @@ -5,7 +5,6 @@ package azeventgrid_test import ( "context" - "encoding/hex" "encoding/json" "errors" "fmt" @@ -22,32 +21,54 @@ func Example_publishAndReceiveCloudEvents() { topicName := os.Getenv("EVENTGRID_TOPIC") subscriptionName := os.Getenv("EVENTGRID_SUBSCRIPTION") + if endpoint == "" || key == "" || topicName == "" || subscriptionName == "" { + return + } + client, err := azeventgrid.NewClientWithSharedKeyCredential(endpoint, key, nil) if err != nil { panic(err) } + // + // Publish an event with a string payload + // + fmt.Fprintf(os.Stderr, "Published event with a string payload 'hello world'\n") eventWithString, err := publishAndReceiveEvent(client, topicName, subscriptionName, "hello world") if err != nil { panic(err) } - fmt.Printf("ID: %s\n", eventWithString.Event.ID) - fmt.Printf(" Body: %s\n", eventWithString.Event.Data.(string)) - fmt.Printf(" Delivery count: %d\n", eventWithString.BrokerProperties.DeliveryCount) + fmt.Fprintf(os.Stderr, "Received an event with a string payload\n") + fmt.Fprintf(os.Stderr, "ID: %s\n", eventWithString.Event.ID) + + var str *string + + if err := json.Unmarshal(eventWithString.Event.Data.([]byte), &str); err != nil { + panic(err) + } + + fmt.Fprintf(os.Stderr, " Body: %s\n", *str) // prints 'Body: hello world' + fmt.Fprintf(os.Stderr, " Delivery count: %d\n", eventWithString.BrokerProperties.DeliveryCount) + // + // Publish an event with a []byte payload + // eventWithBytes, err := publishAndReceiveEvent(client, topicName, subscriptionName, []byte{0, 1, 2}) if err != nil { panic(err) } - fmt.Printf("ID: %s\n", eventWithBytes.Event.ID) - fmt.Printf(" Body: %s\n", hex.EncodeToString(eventWithBytes.Event.Data.([]byte))) - fmt.Printf(" Delivery count: %d\n", eventWithBytes.BrokerProperties.DeliveryCount) + fmt.Fprintf(os.Stderr, "ID: %s\n", eventWithBytes.Event.ID) + fmt.Fprintf(os.Stderr, " Body: %#v\n", eventWithBytes.Event.Data.([]byte)) // prints 'Body: []byte{0x0, 0x1, 0x2}' + fmt.Fprintf(os.Stderr, " Delivery count: %d\n", eventWithBytes.BrokerProperties.DeliveryCount) + // + // Publish an event with a struct as the payload + // type SampleData struct { Name string `json:"name"` } @@ -59,13 +80,15 @@ func Example_publishAndReceiveCloudEvents() { } var sampleData *SampleData - if err := json.Unmarshal(eventWithStruct.Event.Data.(json.RawMessage), &sampleData); err != nil { + if err := json.Unmarshal(eventWithStruct.Event.Data.([]byte), &sampleData); err != nil { panic(err) } - fmt.Printf("ID: %s\n", eventWithStruct.Event.ID) - fmt.Printf(" Body: %#v\n", sampleData) - fmt.Printf(" Delivery count: %d\n", eventWithStruct.BrokerProperties.DeliveryCount) + fmt.Fprintf(os.Stderr, "ID: %s\n", eventWithStruct.Event.ID) + fmt.Fprintf(os.Stderr, " Body: %#v\n", sampleData) // prints 'Body: &azeventgrid_test.SampleData{Name:"hello"}' + fmt.Fprintf(os.Stderr, " Delivery count: %d\n", eventWithStruct.BrokerProperties.DeliveryCount) + + // Output: } func publishAndReceiveEvent(client *azeventgrid.Client, topicName string, subscriptionName string, payload any) (azeventgrid.ReceiveDetails, error) { diff --git a/sdk/messaging/azeventgrid/go.mod b/sdk/messaging/azeventgrid/go.mod index aaef664ce88e..5c5f59692a01 100644 --- a/sdk/messaging/azeventgrid/go.mod +++ b/sdk/messaging/azeventgrid/go.mod @@ -3,12 +3,17 @@ module github.com/Azure/azure-sdk-for-go/sdk/messaging/azeventgrid go 1.18 require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0-beta.1 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0-beta.2 github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 github.com/joho/godotenv v1.5.1 github.com/stretchr/testify v1.7.0 ) +replace ( + // temporary until we officially release the next beta. + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0-beta.2 => ../../azcore +) + require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dnaeon/go-vcr v1.1.0 // indirect