Пример #1
0
        public void CanRoundTripStream()
        {
            var data   = new byte[] { 1, 2, 3 };
            var stream = new MemoryStream(data);

            stream.Position = 0;
            var time       = DateTimeOffset.Now;
            var cloudEvent = new CloudEvent("source", "type", BinaryData.FromStream(stream), "application/octet-stream")
            {
                Subject    = "subject",
                DataSchema = "schema",
                Id         = "id",
                Time       = time,
            };
            var        serializer   = new JsonObjectSerializer();
            BinaryData serialized   = serializer.Serialize(cloudEvent);
            CloudEvent deserialized = CloudEvent.ParseMany(serialized)[0];

            Assert.AreEqual("source", deserialized.Source);
            Assert.AreEqual("type", deserialized.Type);
            Assert.AreEqual(data, deserialized.Data.ToArray());
            Assert.AreEqual("subject", deserialized.Subject);
            Assert.AreEqual("schema", deserialized.DataSchema);
            Assert.AreEqual("id", deserialized.Id);
            Assert.AreEqual(time, deserialized.Time);
        }
Пример #2
0
        public void CloudEventParseThrowsOnNullInput()
        {
            Assert.That(() => CloudEvent.ParseMany(null),
                        Throws.InstanceOf <ArgumentNullException>());

            Assert.That(() => CloudEvent.Parse(null),
                        Throws.InstanceOf <ArgumentNullException>());
        }
Пример #3
0
        public void CanRoundTripNumber()
        {
            var time       = DateTimeOffset.Now;
            var cloudEvent = new CloudEvent("source", "type", 5)
            {
                Subject    = "subject",
                DataSchema = "schema",
                Id         = "id",
                Time       = time,
            };

            Assert.AreEqual(5, cloudEvent.Data.ToObjectFromJson <int>());
            var        serializer = new JsonObjectSerializer();
            BinaryData serialized = serializer.Serialize(cloudEvent);

            CloudEvent deserialized = CloudEvent.ParseMany(serialized)[0];

            AssertCloudEvent();

            deserialized = (CloudEvent)serializer.Deserialize(serialized.ToStream(), typeof(CloudEvent), CancellationToken.None);
            AssertCloudEvent();

            deserialized = CloudEvent.Parse(serialized);
            AssertCloudEvent();

            cloudEvent = new CloudEvent("source", "type", new BinaryData(5), "application/json", CloudEventDataFormat.Json)
            {
                Subject    = "subject",
                DataSchema = "schema",
                Id         = "id",
                Time       = time,
            };
            Assert.AreEqual(5, cloudEvent.Data.ToObjectFromJson <int>());
            serialized = serializer.Serialize(cloudEvent);

            deserialized = CloudEvent.ParseMany(serialized)[0];
            AssertCloudEvent();

            deserialized = (CloudEvent)serializer.Deserialize(serialized.ToStream(), typeof(CloudEvent), CancellationToken.None);
            AssertCloudEvent();

            deserialized = CloudEvent.Parse(serialized);
            AssertCloudEvent();

            void AssertCloudEvent()
            {
                Assert.AreEqual(5, cloudEvent.Data.ToObjectFromJson <int>());
                Assert.AreEqual("source", deserialized.Source);
                Assert.AreEqual("type", deserialized.Type);
                Assert.AreEqual("subject", deserialized.Subject);
                Assert.AreEqual("schema", deserialized.DataSchema);
                Assert.AreEqual("id", deserialized.Id);
                Assert.AreEqual(time, deserialized.Time);
            }
        }
Пример #4
0
        public void CanRoundTripModelWithCustomSerializer()
        {
            var time = DateTimeOffset.Now;
            var data = new TestModel
            {
                A = 10,
                B = true
            };
            var dataSerializer = new JsonObjectSerializer(new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            });
            var cloudEvent = new CloudEvent("source", "type", dataSerializer.Serialize(data), "application/json", CloudEventDataFormat.Json)
            {
                Subject    = "subject",
                DataSchema = "schema",
                Id         = "id",
                Time       = time,
            };
            var        serializer   = new JsonObjectSerializer();
            BinaryData serialized   = serializer.Serialize(cloudEvent);
            CloudEvent deserialized = CloudEvent.ParseMany(serialized)[0];

            Assert.AreEqual("source", deserialized.Source);
            Assert.AreEqual("type", deserialized.Type);
            Assert.AreEqual(10, deserialized.Data.ToObject <TestModel>(dataSerializer).A);
            Assert.AreEqual(true, deserialized.Data.ToObject <TestModel>(dataSerializer).B);
            Assert.AreEqual("subject", deserialized.Subject);
            Assert.AreEqual("schema", deserialized.DataSchema);
            Assert.AreEqual("id", deserialized.Id);
            Assert.AreEqual(time, deserialized.Time);

            deserialized = (CloudEvent)serializer.Deserialize(serialized.ToStream(), typeof(CloudEvent), CancellationToken.None);
            Assert.AreEqual("source", deserialized.Source);
            Assert.AreEqual("type", deserialized.Type);
            Assert.AreEqual(10, deserialized.Data.ToObject <TestModel>(dataSerializer).A);
            Assert.AreEqual(true, deserialized.Data.ToObject <TestModel>(dataSerializer).B);
            Assert.AreEqual("subject", deserialized.Subject);
            Assert.AreEqual("schema", deserialized.DataSchema);
            Assert.AreEqual("id", deserialized.Id);
            Assert.AreEqual(time, deserialized.Time);

            deserialized = CloudEvent.Parse(serialized);
            Assert.AreEqual("source", deserialized.Source);
            Assert.AreEqual("type", deserialized.Type);
            Assert.AreEqual(10, deserialized.Data.ToObject <TestModel>(dataSerializer).A);
            Assert.AreEqual(true, deserialized.Data.ToObject <TestModel>(dataSerializer).B);
            Assert.AreEqual("subject", deserialized.Subject);
            Assert.AreEqual("schema", deserialized.DataSchema);
            Assert.AreEqual("id", deserialized.Id);
            Assert.AreEqual(time, deserialized.Time);
        }
        public void Initialize(ExtensionConfigContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            _logger = _loggerFactory.CreateLogger <EventGridExtensionConfigProvider>();

#pragma warning disable 618
            Uri url = context.GetWebhookHandler();
#pragma warning restore 618
            _logger.LogInformation($"registered EventGrid Endpoint = {url?.GetLeftPart(UriPartial.Path)}");

            // Register our extension binding providers
            // use converterManager as a hashTable
            // also take benefit of identity converter
            context
            .AddBindingRule <EventGridTriggerAttribute>()    // following converters are for EventGridTriggerAttribute only
            .AddConverter <JToken, string>(jtoken => jtoken.ToString(Formatting.Indented))
            .AddConverter <JToken, string[]>(jarray => jarray.Select(ar => ar.ToString(Formatting.Indented)).ToArray())
            .AddConverter <JToken, DirectInvokeString>(jtoken => new DirectInvokeString(null))
            .AddConverter <JToken, EventGridEvent>(jobject => EventGridEvent.Parse(new BinaryData(jobject.ToString())))    // surface the type to function runtime
            .AddConverter <JToken, EventGridEvent[]>(jobject => EventGridEvent.ParseMany(new BinaryData(jobject.ToString())))
            .AddConverter <JToken, CloudEvent>(jobject => CloudEvent.Parse(new BinaryData(jobject.ToString())))
            .AddConverter <JToken, CloudEvent[]>(jobject => CloudEvent.ParseMany(new BinaryData(jobject.ToString())))
            .AddConverter <JToken, BinaryData>(jobject => new BinaryData(jobject.ToString()))
            .AddConverter <JToken, BinaryData[]>(jobject => jobject.Select(obj => new BinaryData(obj.ToString())).ToArray())
            .AddOpenConverter <JToken, OpenType.Poco>(typeof(JTokenToPocoConverter <>))
            .AddOpenConverter <JToken, OpenType.Poco[]>(typeof(JTokenToPocoConverter <>))
            .BindToTrigger <JToken>(new EventGridTriggerAttributeBindingProvider(this));

            // Register the output binding
            var rule = context.AddBindingRule <EventGridAttribute>();
            rule.BindToCollector(_converter);
            rule.AddValidator((a, t) =>
            {
                // if app setting is missing, it will be caught by runtime
                // this logic tries to validate the practicality of attribute properties
                if (string.IsNullOrWhiteSpace(a.TopicKeySetting))
                {
                    throw new InvalidOperationException($"The '{nameof(EventGridAttribute.TopicKeySetting)}' property must be the name of an application setting containing the Topic Key");
                }

                if (!Uri.IsWellFormedUriString(a.TopicEndpointUri, UriKind.Absolute))
                {
                    throw new InvalidOperationException($"The '{nameof(EventGridAttribute.TopicEndpointUri)}' property must be a valid absolute Uri");
                }
            });
        }
Пример #6
0
        public void CanRoundTrip()
        {
            var time = DateTimeOffset.Now;
            var data = new TestModel
            {
                A = 10,
                B = true
            };
            var cloudEvent = new CloudEvent("source", "type", data)
            {
                Subject    = "subject",
                DataSchema = "schema",
                Id         = "id",
                Time       = time,
            };
            var        serializer   = new JsonObjectSerializer();
            BinaryData serialized   = serializer.Serialize(cloudEvent);
            CloudEvent deserialized = CloudEvent.ParseMany(serialized)[0];

            Assert.AreEqual("source", deserialized.Source);
            Assert.AreEqual("type", deserialized.Type);
            Assert.AreEqual(10, deserialized.Data.ToObjectFromJson <TestModel>().A);
            Assert.AreEqual(true, deserialized.Data.ToObjectFromJson <TestModel>().B);
            Assert.AreEqual("subject", deserialized.Subject);
            Assert.AreEqual("schema", deserialized.DataSchema);
            Assert.AreEqual("id", deserialized.Id);
            Assert.AreEqual(time, deserialized.Time);

            deserialized = (CloudEvent)serializer.Deserialize(serialized.ToStream(), typeof(CloudEvent), CancellationToken.None);
            Assert.AreEqual("source", deserialized.Source);
            Assert.AreEqual("type", deserialized.Type);
            Assert.AreEqual(10, deserialized.Data.ToObjectFromJson <TestModel>().A);
            Assert.AreEqual(true, deserialized.Data.ToObjectFromJson <TestModel>().B);
            Assert.AreEqual("subject", deserialized.Subject);
            Assert.AreEqual("schema", deserialized.DataSchema);
            Assert.AreEqual("id", deserialized.Id);
            Assert.AreEqual(time, deserialized.Time);

            deserialized = CloudEvent.Parse(serialized);
            Assert.AreEqual("source", deserialized.Source);
            Assert.AreEqual("type", deserialized.Type);
            Assert.AreEqual(10, deserialized.Data.ToObjectFromJson <TestModel>().A);
            Assert.AreEqual(true, deserialized.Data.ToObjectFromJson <TestModel>().B);
            Assert.AreEqual("subject", deserialized.Subject);
            Assert.AreEqual("schema", deserialized.DataSchema);
            Assert.AreEqual("id", deserialized.Id);
            Assert.AreEqual(time, deserialized.Time);
        }
        public async Task GenericReceiveAndDeserializeEventGridEvents()
        {
            // Example of a custom ObjectSerializer used to deserialize the event payload
            JsonObjectSerializer myCustomSerializer = new JsonObjectSerializer(
                new JsonSerializerOptions()
            {
                PropertyNameCaseInsensitive = true
            });

            var httpContent = new StreamContent(new BinaryData(jsonPayloadSampleTwo).ToStream());

            #region Snippet:CloudEventParseJson
            var bytes = await httpContent.ReadAsByteArrayAsync();

            // Parse the JSON payload into a list of events
            CloudEvent[] cloudEvents = CloudEvent.ParseMany(new BinaryData(bytes));
            #endregion

            // Iterate over each event to access event properties and data
            #region Snippet:DeserializePayloadUsingGenericGetData
            foreach (CloudEvent cloudEvent in cloudEvents)
            {
                switch (cloudEvent.Type)
                {
                case "Contoso.Items.ItemReceived":
                    // By default, ToObjectFromJson<T> uses System.Text.Json to deserialize the payload
                    ContosoItemReceivedEventData itemReceived = cloudEvent.Data.ToObjectFromJson <ContosoItemReceivedEventData>();
                    Console.WriteLine(itemReceived.ItemSku);
                    break;

                case "MyApp.Models.CustomEventType":
                    // One can also specify a custom ObjectSerializer as needed to deserialize the payload correctly
                    TestPayload testPayload = cloudEvent.Data.ToObject <TestPayload>(myCustomSerializer);
                    Console.WriteLine(testPayload.Name);
                    break;

                case SystemEventNames.StorageBlobDeleted:
                    // Example for deserializing system events using ToObjectFromJson<T>
                    StorageBlobDeletedEventData blobDeleted = cloudEvent.Data.ToObjectFromJson <StorageBlobDeletedEventData>();
                    Console.WriteLine(blobDeleted.BlobType);
                    break;
                }
            }
            #endregion
        }
Пример #8
0
        public void CanParseNullAttributeValue(bool skipValidation)
        {
            // null extension attribute values can still be deserialized.
            var json = new BinaryData("{\"subject\": \"Subject-0\", \"source\":\"source\", \"specversion\":\"1.0\", \"id\": \"id\", \"type\": \"type\", \"key\":null }");

            if (!skipValidation)
            {
                Assert.That(
                    () => CloudEvent.ParseMany(json),
                    Throws.InstanceOf <ArgumentException>());
            }
            else
            {
                var evt = CloudEvent.ParseMany(json, true)[0];
                Assert.AreEqual("Subject-0", evt.Subject);
                Assert.AreEqual("type", evt.Type);
                Assert.IsNull(evt.ExtensionAttributes["key"]);
            }
        }
Пример #9
0
        public void CanParseInvalidAttributes(bool skipValidation)
        {
            // improperly cased extension can still be deserialized.
            var json = new BinaryData("{\"subject\": \"Subject-0\", \"source\":\"source\", \"specversion\":\"1.0\", \"id\": \"id\", \"type\": \"type\", \"KEY\":\"value\", \"dict\": { \"key1\":true, \"key2\": 5 } }");

            if (!skipValidation)
            {
                Assert.That(
                    () => CloudEvent.ParseMany(json),
                    Throws.InstanceOf <ArgumentException>());
            }
            else
            {
                var evt = CloudEvent.ParseMany(json, true)[0];
                Assert.AreEqual("Subject-0", evt.Subject);
                Assert.AreEqual("type", evt.Type);
                Assert.AreEqual("value", evt.ExtensionAttributes["KEY"]);
                Assert.AreEqual(true, ((IDictionary <string, object>)evt.ExtensionAttributes["dict"])["key1"]);
                Assert.AreEqual(5, ((IDictionary <string, object>)evt.ExtensionAttributes["dict"])["key2"]);
            }
        }
Пример #10
0
        public void CanRoundTripWithDefaultDataSerializer()
        {
            var data = new TestModel
            {
                A = 10,
                B = true
            };
            var cloudEvent = new CloudEvent("source", "type", data);
            var serializer = new JsonObjectSerializer(new JsonSerializerOptions
            {
                Converters = { new CloudEventConverter() }
            });

            BinaryData serialized   = serializer.Serialize(cloudEvent);
            CloudEvent deserialized = CloudEvent.ParseMany(serialized)[0];

            Assert.AreEqual("source", deserialized.Source);
            Assert.AreEqual("type", deserialized.Type);
            Assert.AreEqual(10, deserialized.Data.ToObjectFromJson <TestModel>().A);
            Assert.AreEqual(true, deserialized.Data.ToObjectFromJson <TestModel>().B);
        }
Пример #11
0
        public void CanRoundTripWithCustomDataSerializer()
        {
            var data = new TestModel
            {
                A = 10,
                B = true
            };
            var dataSerializer = new JsonObjectSerializer(new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            });
            var cloudEvent = new CloudEvent("source", "type", dataSerializer.Serialize(data), "custom", CloudEventDataFormat.Json);
            var serializer = new JsonObjectSerializer();

            BinaryData serialized   = serializer.Serialize(cloudEvent);
            CloudEvent deserialized = CloudEvent.ParseMany(serialized)[0];

            Assert.AreEqual("source", deserialized.Source);
            Assert.AreEqual("type", deserialized.Type);
            Assert.AreEqual(10, deserialized.Data.ToObject <TestModel>(dataSerializer).A);
            Assert.AreEqual(true, deserialized.Data.ToObject <TestModel>(dataSerializer).B);
        }
Пример #12
0
        public void CanParseMultipleMissingRequired(bool skipValidation)
        {
            // missing Id, Source, SpecVersion
            BinaryData requestContent = new BinaryData("[{ \"subject\": \"Subject-0\", \"data\": {    \"itemSku\": \"512d38b6-c7b8-40c8-89fe-f46f9e9622b6\",    \"itemUri\": \"https://rp-eastus2.eventgrid.azure.net:553/eventsubscriptions/estest/validate?id=B2E34264-7D71-453A-B5FB-B62D0FDC85EE&t=2018-04-26T20:30:54.4538837Z&apiVersion=2018-05-01-preview&token=1BNqCxBBSSE9OnNSfZM4%2b5H9zDegKMY6uJ%2fO2DFRkwQ%3d\"  }}, { \"subject\": \"Subject-0\", \"data\": {    \"itemSku\": \"512d38b6-c7b8-40c8-89fe-f46f9e9622b6\",    \"itemUri\": \"https://rp-eastus2.eventgrid.azure.net:553/eventsubscriptions/estest/validate?id=B2E34264-7D71-453A-B5FB-B62D0FDC85EE&t=2018-04-26T20:30:54.4538837Z&apiVersion=2018-05-01-preview&token=1BNqCxBBSSE9OnNSfZM4%2b5H9zDegKMY6uJ%2fO2DFRkwQ%3d\"  }}]");

            if (!skipValidation)
            {
                Assert.That(
                    () => CloudEvent.ParseMany(requestContent, skipValidation),
                    Throws.InstanceOf <ArgumentException>());
            }
            else
            {
                CloudEvent[] events = CloudEvent.ParseMany(requestContent, skipValidation);
                foreach (CloudEvent cloudEvent in events)
                {
                    Assert.IsNull(cloudEvent.Id);
                    Assert.IsNull(cloudEvent.Source);
                    Assert.IsNull(cloudEvent.Type);
                    Assert.AreEqual("Subject-0", cloudEvent.Subject);
                }
            }
        }