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); }
public void CloudEventParseThrowsOnNullInput() { Assert.That(() => CloudEvent.ParseMany(null), Throws.InstanceOf <ArgumentNullException>()); Assert.That(() => CloudEvent.Parse(null), Throws.InstanceOf <ArgumentNullException>()); }
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); } }
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"); } }); }
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 }
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"]); } }
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"]); } }
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); }
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); }
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); } } }