From 01147e559dbf0ddae5ef4e553b73f63bd2c86564 Mon Sep 17 00:00:00 2001 From: Artur Souza Date: Thu, 14 Jan 2021 14:28:52 -0800 Subject: [PATCH] Refactor and fix contenttype logic for pubsub. (#602) Co-authored-by: Yaron Schneider --- contenttype/utils.go | 39 +++++++++++++++++++++++++++++++++++++++ pubsub/envelope.go | 10 +++++----- pubsub/envelope_test.go | 17 +++++++++-------- 3 files changed, 53 insertions(+), 13 deletions(-) create mode 100644 contenttype/utils.go diff --git a/contenttype/utils.go b/contenttype/utils.go new file mode 100644 index 000000000..5f07904f9 --- /dev/null +++ b/contenttype/utils.go @@ -0,0 +1,39 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package contenttype + +import "strings" + +const ( + // CloudEventContentType is the content type for cloud event. + CloudEventContentType = "application/cloudevents+json" + // JSONContentType is the content type for JSON. + JSONContentType = "application/json" +) + +// IsCloudEventContentType checks for content type. +func IsCloudEventContentType(contentType string) bool { + return isContentType(contentType, CloudEventContentType) +} + +// IsJSONContentType checks for content type. +func IsJSONContentType(contentType string) bool { + return isContentType(contentType, JSONContentType) +} + +func isContentType(contentType string, expected string) bool { + lowerContentType := strings.ToLower(contentType) + if lowerContentType == expected { + return true + } + + semiColonPos := strings.Index(lowerContentType, ";") + if semiColonPos >= 0 { + return lowerContentType[0:semiColonPos] == expected + } + + return false +} diff --git a/pubsub/envelope.go b/pubsub/envelope.go index 58ad73cfe..bc1e08359 100644 --- a/pubsub/envelope.go +++ b/pubsub/envelope.go @@ -9,6 +9,7 @@ import ( "fmt" "time" + contrib_contenttype "github.com/dapr/components-contrib/contenttype" contrib_metadata "github.com/dapr/components-contrib/metadata" "github.com/google/uuid" jsoniter "github.com/json-iterator/go" @@ -19,9 +20,6 @@ const ( DefaultCloudEventType = "com.dapr.event.sent" // CloudEventsSpecVersion is the specversion used by Dapr for the cloud events implementation CloudEventsSpecVersion = "1.0" - // ContentType is the Cloud Events HTTP content type - ContentType = "application/cloudevents+json" - JSONContentType = "application/json" // DefaultCloudEventSource is the default event source DefaultCloudEventSource = "Dapr" // DefaultCloudEventDataContentType is the default content-type for the data attribute @@ -57,11 +55,13 @@ func NewCloudEventsEnvelope(id, source, eventType, subject string, topic string, var ceData interface{} var err error - if dataContentType == JSONContentType { + if contrib_contenttype.IsJSONContentType(dataContentType) { err = jsoniter.Unmarshal(data, &ceData) + } else { + ceData = string(data) } - if err != nil || dataContentType != JSONContentType { + if err != nil { ceData = string(data) } diff --git a/pubsub/envelope_test.go b/pubsub/envelope_test.go index f2b2c1ddf..258e23864 100644 --- a/pubsub/envelope_test.go +++ b/pubsub/envelope_test.go @@ -56,15 +56,16 @@ func TestCreateFromJSON(t *testing.T) { envelope := NewCloudEventsEnvelope("a", "source", "", "", "", "mypubsub", "application/json", data, "1") t.Logf("data: %v", envelope[DataField]) assert.Equal(t, "application/json", envelope[DataContentTypeField]) + assert.Equal(t, map[string]interface{}{"Val1": "test", "Val2": float64(1)}, envelope[DataField]) + }) - obj2 := struct { - Val1 string - Val2 int - }{} - err := json.Unmarshal(data, &obj2) - assert.NoError(t, err) - assert.Equal(t, obj1.Val1, obj2.Val1) - assert.Equal(t, obj1.Val2, obj2.Val2) + t.Run("has JSON string with rich contenttype", func(t *testing.T) { + obj1 := "message" + data, _ := json.Marshal(obj1) + envelope := NewCloudEventsEnvelope("a", "source", "", "", "", "mypubsub", "application/JSON; charset=utf-8", data, "1") + t.Logf("data: %v", envelope[DataField]) + assert.Equal(t, "application/JSON; charset=utf-8", envelope[DataContentTypeField]) + assert.Equal(t, "message", envelope[DataField]) }) }