public async Task PublishSingleCloudEvent_WithBuilder_ValidParameters_Succeeds()
        {
            // Arrange
            const string eventSubject = "integration-test";
            const string licensePlate = "1-TOM-337";
            var          eventId      = Guid.NewGuid().ToString();
            var          @event       = new CloudEvent(CloudEventsSpecVersion.V1_0, "NewCarRegistered", new Uri("http://test-host"), eventSubject, eventId)
            {
                Data            = new CarEventData(licensePlate),
                DataContentType = new ContentType("application/json")
            };

            IEventGridPublisher publisher = EventPublisherFactory.CreateCloudEventPublisher(_config);

            // Act
            await publisher.PublishAsync(@event);

            TracePublishedEvent(eventId, @event);

            // Assert
            string receivedEvent = _endpoint.ServiceBusEventConsumerHost.GetReceivedEvent(eventId);

            ArcusAssert.ReceivedNewCarRegisteredEvent(eventId, @event.Type, eventSubject, licensePlate, receivedEvent);
        }
            public async void Post_RepositoryThrowsException_ReturnsInternalServerError()
            {
                // Arrange
                string                requestUri    = $"{BasePath}/app";
                CloudEvent            cloudEvent    = GetCloudEvent();
                Mock <IEventsService> eventsService = new Mock <IEventsService>();

                eventsService.Setup(er => er.StoreCloudEvent(It.IsAny <CloudEvent>())).Throws(new Exception());
                HttpClient client = GetTestClient(eventsService.Object);

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", PrincipalUtil.GetToken(1));
                HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, requestUri)
                {
                    Content = new StringContent(cloudEvent.Serialize(), Encoding.UTF8, "application/json")
                };

                httpRequestMessage.Headers.Add("PlatformAccessToken", PrincipalUtil.GetAccessToken("ttd", "unittest"));

                // Act
                HttpResponseMessage response = await client.SendAsync(httpRequestMessage);

                // Assert
                Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
            }
示例#3
0
        public void EncodeStructuredModeMessage_Minimal()
        {
            var cloudEvent = new CloudEvent(CloudEventsSpecVersion.V1_0)
            {
                Id     = "event-id",
                Source = new Uri("https://event-source"),
                Type   = "event-type",
            };

            var encoded = new ProtobufEventFormatter().EncodeStructuredModeMessage(cloudEvent, out var contentType);

            Assert.Equal("application/cloudevents+protobuf; charset=utf-8", contentType.ToString());
            var actualProto = V1.CloudEvent.Parser.ParseFrom(encoded.ToArray());

            var expectedProto = new V1.CloudEvent
            {
                SpecVersion = "1.0",
                Id          = "event-id",
                Source      = "https://event-source",
                Type        = "event-type"
            };

            Assert.Equal(expectedProto, actualProto);
        }
示例#4
0
        async Task OnExecuteAsync()
        {
            var cloudEvent = new CloudEvent(this.Type, new Uri(this.Source))
            {
                DataContentType = new ContentType(MediaTypeNames.Application.Json),
                Data            = JsonConvert.SerializeObject("hey there!")
            };

            var content = new CloudEventContent(cloudEvent, ContentMode.Structured, new JsonEventFormatter());

            /* test with websocket - couldn't connect to Azure Application GW
             * var buffer = new byte[1024 * 4];
             * buffer = Encoding.UTF8.GetBytes(cloudEvent.Data.ToString());
             * var webSocket = new ClientWebSocket();
             * webSocket.Options.SetRequestHeader("Ocp-Apim-Subscription-Key", "ca1fcd5b134341eb9179a4dffbe4d492");
             * Uri wsUrl = new Uri("ws://51.116.139.102");
             * await webSocket.ConnectAsync(wsUrl, CancellationToken.None);
             * WebSocketReceiveResult wsresult = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
             * while (!wsresult.CloseStatus.HasValue)
             * {
             *  await webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, endOfMessage: true, CancellationToken.None);
             *  wsresult = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
             * }
             * await webSocket.CloseAsync(wsresult.CloseStatus.Value, wsresult.CloseStatusDescription, CancellationToken.None);
             */

            var httpClient = new HttpClient();

            httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "ca1fcd5b134341eb9179a4dffbe4d492");
            // your application remains in charge of adding any further headers or
            // other information required to authenticate/authorize or otherwise
            // dispatch the call at the server.
            var result = (await httpClient.PostAsync(this.Url, content));

            Console.WriteLine(result.StatusCode);
        }
示例#5
0
        /// <inheritdoc/>
        public async Task <string> Create(CloudEvent cloudEvent)
        {
            try
            {
                using NpgsqlConnection conn = new NpgsqlConnection(_connectionString);
                await conn.OpenAsync();

                NpgsqlCommand pgcom = new NpgsqlCommand(insertEventSql, conn);
                pgcom.Parameters.AddWithValue("id", cloudEvent.Id);
                pgcom.Parameters.AddWithValue("source", cloudEvent.Source.OriginalString);
                pgcom.Parameters.AddWithValue("subject", cloudEvent.Subject);
                pgcom.Parameters.AddWithValue("type", cloudEvent.Type);
                pgcom.Parameters.AddWithValue("cloudevent", cloudEvent.Serialize());

                await pgcom.ExecuteNonQueryAsync();

                return(cloudEvent.Id);
            }
            catch (Exception e)
            {
                _logger.LogError(e, "PostgresRepository // Create // Exception");
                throw;
            }
        }
示例#6
0
        public void Constructor2HappyPath()
        {
            var source = new CloudEvent
            {
                Id              = "MyId",
                Time            = new DateTime(2020, 7, 9, 22, 21, 37, DateTimeKind.Local),
                Source          = "http://mysource/",
                Type            = "MyType",
                DataContentType = "application/json; charset=utf-8",
                DataSchema      = "http://mydataschema/",
                Subject         = "MySubject"
            };

            var cloudEvent = new CloudEvent(source);

            cloudEvent.Source.Should().BeSameAs(source.Source);
            cloudEvent.Type.Should().BeSameAs(source.Type);
            cloudEvent.DataContentType.Should().BeSameAs(source.DataContentType);
            cloudEvent.DataSchema.Should().BeSameAs(source.DataSchema);
            cloudEvent.Subject.Should().BeSameAs(source.Subject);

            cloudEvent.Id.Should().NotBe(source.Id);
            cloudEvent.Time.Should().NotBe(source.Time);
        }
        public void Constructor3HappyPath5()
        {
            // Alternate property types provided

            using var receiverMessage = new FakeReceiverMessage("Hello, world!");

            var source          = new Uri("http://MySource").ToString();
            var dataContentType = new ContentType("application/mycontenttype").ToString();
            var dataSchema      = new Uri("http://MySource").ToString();
            var time            = DateTime.UtcNow.ToString("O");

            receiverMessage.Headers.Add(CloudEvent.SourceAttribute, source);
            receiverMessage.Headers.Add(CloudEvent.DataContentTypeAttribute, dataContentType);
            receiverMessage.Headers.Add(CloudEvent.DataSchemaAttribute, dataSchema);
            receiverMessage.Headers.Add(CloudEvent.TimeAttribute, time);

            var cloudEvent = new CloudEvent(receiverMessage);

            cloudEvent.Should().NotBeNull();
            cloudEvent.Source !.ToString().Should().Be(source);
            cloudEvent.DataContentType !.ToString().Should().Be(dataContentType);
            cloudEvent.DataSchema !.ToString().Should().Be(dataSchema);
            cloudEvent.Time.ToString("O").Should().Be(time);
        }
        private void WriteCloudEventForBatchOrStructuredMode(Utf8JsonWriter writer, CloudEvent cloudEvent)
        {
            Validation.CheckCloudEventArgument(cloudEvent, nameof(cloudEvent));

            writer.WriteStartObject();
            writer.WritePropertyName(CloudEventsSpecVersion.SpecVersionAttribute.Name);
            writer.WriteStringValue(cloudEvent.SpecVersion.VersionId);
            var attributes = cloudEvent.GetPopulatedAttributes();

            foreach (var keyValuePair in attributes)
            {
                var attribute = keyValuePair.Key;
                var value     = keyValuePair.Value;
                writer.WritePropertyName(attribute.Name);
                switch (CloudEventAttributeTypes.GetOrdinal(attribute.Type))
                {
                case CloudEventAttributeTypeOrdinal.Integer:
                    writer.WriteNumberValue((int)value);
                    break;

                case CloudEventAttributeTypeOrdinal.Boolean:
                    writer.WriteBooleanValue((bool)value);
                    break;

                default:
                    writer.WriteStringValue(attribute.Type.Format(value));
                    break;
                }
            }

            if (cloudEvent.Data is object)
            {
                EncodeStructuredModeData(cloudEvent, writer);
            }
            writer.WriteEndObject();
        }
示例#9
0
            internal CloudEvent ConvertToCloudEvent(Request request)
            {
                MaybeReshapeData(request);

                var context      = request.Context;
                var resource     = context.Resource;
                var service      = ValidateNotNullOrEmpty(resource.Service ?? _defaultService, "service");
                var resourceName = ValidateNotNullOrEmpty(resource.Name, "resource name");

                var(source, subject) = ConvertResourceToSourceAndSubject(service, resourceName);
                var evt = new CloudEvent(_cloudEventType, source, context.Id, context.Timestamp?.UtcDateTime)
                {
                    Data            = JsonSerializer.Serialize(request.Data),
                    DataContentType = JsonContentType
                };

                // CloudEvent.Subject is null by default, but doesn't allow null to be set.
                // See https://github.com/cloudevents/sdk-csharp/issues/58
                if (subject is string)
                {
                    evt.Subject = subject;
                }
                return(evt);
            }
        private async Task PublishEventToEventGridAsync(Order orderMessage, string operationId, MessageCorrelationInfo correlationInfo)
        {
            var eventData = new OrderCreatedEventData(
                orderMessage.Id,
                orderMessage.Amount,
                orderMessage.ArticleNumber,
                $"{orderMessage.Customer.FirstName} {orderMessage.Customer.LastName}",
                correlationInfo);

            var orderCreatedEvent = new CloudEvent(
                CloudEventsSpecVersion.V1_0,
                "OrderCreatedEvent",
                new Uri("http://test-host"),
                operationId,
                DateTime.UtcNow)
            {
                Data            = eventData,
                DataContentType = new ContentType("application/json")
            };

            await _eventGridPublisher.PublishAsync(orderCreatedEvent);

            Logger.LogInformation("Event {EventId} was published with subject {EventSubject}", orderCreatedEvent.Id, orderCreatedEvent.Subject);
        }
示例#11
0
        private static CloudEvent BinaryToCloudEvent(Message message, ICloudEventExtension[] extensions)
        {
            var specVersion      = GetCloudEventsSpecVersion(message);
            var cloudEventType   = GetAttribute(message, CloudEventAttributes.TypeAttributeName(specVersion));
            var cloudEventSource = new Uri(GetAttribute(message, CloudEventAttributes.SourceAttributeName(specVersion)));
            var cloudEvent       = new CloudEvent(specVersion, cloudEventType, cloudEventSource, id: message.MessageId, extensions: extensions);
            var attributes       = cloudEvent.GetAttributes();

            foreach (var property in message.UserProperties)
            {
                if (property.Key.StartsWith(Constants.PropertyKeyPrefix, StringComparison.InvariantCultureIgnoreCase))
                {
#pragma warning disable CA1308 // Normalize strings to uppercase
                    var key = property.Key.Substring(Constants.PropertyKeyPrefix.Length).ToLowerInvariant();
#pragma warning restore CA1308 // Normalize strings to uppercase

                    attributes[key] = property.Value;
                }
            }

            cloudEvent.DataContentType = message.ContentType == null ? null : new ContentType(message.ContentType);
            cloudEvent.Data            = message.Body;
            return(cloudEvent);
        }
示例#12
0
        public byte[] EncodeStructuredEvent(CloudEvent cloudEvent, out ContentType contentType)
        {
            contentType = new ContentType("application/cloudevents+json")
            {
                CharSet = Encoding.UTF8.WebName
            };

            JObject jObject    = new JObject();
            var     attributes = cloudEvent.GetPopulatedAttributes();

            foreach (var keyValuePair in attributes)
            {
                jObject[keyValuePair.Key.Name] = JToken.FromObject(keyValuePair.Value);
            }

            // FIXME: This is all a bit arbitrary.
            if (cloudEvent.Data is object)
            {
                // FIXME: This assumes there's nothing beyond the media type...
                if (cloudEvent.DataContentType == "application/json")
                {
                    jObject[Data] = JToken.FromObject(cloudEvent.Data);
                }
                else if (cloudEvent.Data is string text && cloudEvent.DataContentType?.StartsWith("text/") == true)
                {
                    jObject[Data] = text;
                }
                else if (cloudEvent.Data is byte[] binary)
                {
                    jObject[DataBase64] = Convert.ToBase64String(binary);
                }
                else
                {
                    throw new ArgumentException($"{nameof(JsonEventFormatter)} cannot serialize data of type {cloudEvent.Data.GetType()} with content type {cloudEvent.DataContentType}");
                }
            }
示例#13
0
        public void Data_String_Basic_Success()
        {
            var json = @"
{
  'id': 'C234-1234-1234',
  'type': 'com.example.someevent',
  'specversion': '1.0',
  'source': '/mycontext',
  'data': 'This is some text...'
}";

            Tuple <bool, System.Collections.Generic.IReadOnlyList <string> > validationResults = CloudEvent.ValidateJsonDetailed(json);

            validationResults.Item1.Should().BeTrue();
        }
示例#14
0
        public void ContentType_Invalid_Fail(string contentType)
        {
            var json = $@"
{{
  'id': 'C234-1234-1234',
  'type': 'com.example.someevent',
  'specversion': '1.0',
  'source': '/mycontext',
  'datacontenttype': '{contentType}'
}}";

            Tuple <bool, System.Collections.Generic.IReadOnlyList <string> > validationResults = CloudEvent.ValidateJsonDetailed(json);

            validationResults.Item1.Should().BeFalse();
        }
示例#15
0
        public void Id_Guid_Success()
        {
            var json = @"
{
  'id': '00717CE8-D29E-4C2E-84D4-A9E026575778',
  'type': 'com.example.someevent',
  'specversion': '1.0',
  'source': '/mycontext'
}
";
            Tuple <bool, System.Collections.Generic.IReadOnlyList <string> > validationResults = CloudEvent.ValidateJsonDetailed(json);

            validationResults.Item1.Should().BeTrue();
        }
示例#16
0
        public void DataSchema_Invalid_Fail()
        {
            var json = @"
{
  'id': 'C234-1234-1234',
  'type': 'com.example.someevent',
  'specversion': '1.0',
  'source': '/mycontext',
  'dataschema': '`~!@#$%^&*()-_=+[{]};:'"",<.>/?'
}";

            Tuple <bool, System.Collections.Generic.IReadOnlyList <string> > validationResults = CloudEvent.ValidateJsonDetailed(json);

            validationResults.Item1.Should().BeFalse();
        }
示例#17
0
        public void DataSchema_FullUri_Success()
        {
            var json = @"
{
  'id': 'C234-1234-1234',
  'type': 'com.example.someevent',
  'specversion': '1.0',
  'source': '/mycontext',
  'dataschema': 'https://example.com/foo'
}";

            Tuple <bool, System.Collections.Generic.IReadOnlyList <string> > validationResults = CloudEvent.ValidateJsonDetailed(json);

            validationResults.Item1.Should().BeTrue();
        }
示例#18
0
        public void Time_NoTimeZone_Fail()
        {
            var json = @"
{
  'id': 'C234-1234-1234',
  'type': 'com.example.someevent',
  'specversion': '1.0',
  'source': '/mycontext',
  'time': '2019-04-13T15:07:00.2031033'
}";

            Tuple <bool, System.Collections.Generic.IReadOnlyList <string> > validationResults = CloudEvent.ValidateJsonDetailed(json);

            validationResults.Item1.Should().BeFalse();
        }
            static object Transformer(CloudEvent cloudEvent, Type type)
            {
                var b = ((JsonElement)cloudEvent.Data).GetRawText();

                return(JsonSerializer.Deserialize(b, type));
            }
示例#20
0
        async Task HttpBinaryClientReceiveTest()
        {
            string ctx = Guid.NewGuid().ToString();

            pendingRequests.TryAdd(ctx, async context =>
            {
                try
                {
                    var cloudEvent = new CloudEvent("com.github.pull.create",
                                                    new Uri("https://github.com/cloudevents/spec/pull/123"))
                    {
                        Id              = "A234-1234-1234",
                        Time            = new DateTime(2018, 4, 5, 17, 31, 0, DateTimeKind.Utc),
                        DataContentType = new ContentType(MediaTypeNames.Text.Xml),
                        Data            = "<much wow=\"xml\"/>"
                    };

                    var attrs = cloudEvent.GetAttributes();
                    attrs["comexampleextension1"] = "value";
                    attrs["utf8examplevalue"]     = "æøå";

                    await context.Response.CopyFromAsync(cloudEvent, ContentMode.Binary, new JsonEventFormatter());
                    context.Response.StatusCode = (int)HttpStatusCode.OK;
                }
                catch (Exception e)
                {
                    using (var sw = new StreamWriter(context.Response.OutputStream))
                    {
                        sw.Write(e.ToString());
                        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    }
                }

                context.Response.Close();
            });

            var httpClient = new HttpClient();

            httpClient.DefaultRequestHeaders.Add(testContextHeader, ctx);
            var result = await httpClient.GetAsync(new Uri(listenerAddress + "ep"));

            Assert.Equal(HttpStatusCode.OK, result.StatusCode);

            // The non-ASCII attribute value should have been URL-encoded using UTF-8 for the header.
            Assert.True(result.Headers.TryGetValues("ce-utf8examplevalue", out var utf8ExampleValues));
            Assert.Equal("%C3%A6%C3%B8%C3%A5", utf8ExampleValues.Single());

            var receivedCloudEvent = result.ToCloudEvent();

            Assert.Equal(CloudEventsSpecVersion.V1_0, receivedCloudEvent.SpecVersion);
            Assert.Equal("com.github.pull.create", receivedCloudEvent.Type);
            Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source);
            Assert.Equal("A234-1234-1234", receivedCloudEvent.Id);
            Assert.Equal(DateTime.Parse("2018-04-05T17:31:00Z").ToUniversalTime(),
                         receivedCloudEvent.Time.Value.ToUniversalTime());
            Assert.Equal(new ContentType(MediaTypeNames.Text.Xml), receivedCloudEvent.DataContentType);
            using (var sr = new StreamReader((Stream)receivedCloudEvent.Data))
            {
                Assert.Equal("<much wow=\"xml\"/>", sr.ReadToEnd());
            }

            var attr = receivedCloudEvent.GetAttributes();

            Assert.Equal("value", (string)attr["comexampleextension1"]);
            Assert.Equal("æøå", (string)attr["utf8examplevalue"]);
        }
示例#21
0
        async Task HttpStructuredClientSendTest()
        {
            var cloudEvent = new CloudEvent("com.github.pull.create",
                                            new Uri("https://github.com/cloudevents/spec/pull/123"))
            {
                Id              = "A234-1234-1234",
                Time            = new DateTime(2018, 4, 5, 17, 31, 0, DateTimeKind.Utc),
                DataContentType = new ContentType(MediaTypeNames.Text.Xml),
                Data            = "<much wow=\"xml\"/>"
            };

            var attrs = cloudEvent.GetAttributes();

            attrs["comexampleextension1"] = "value";
            attrs["utf8examplevalue"]     = "æøå";

            string ctx     = Guid.NewGuid().ToString();
            var    content = new CloudEventContent(cloudEvent, ContentMode.Structured, new JsonEventFormatter());

            content.Headers.Add(testContextHeader, ctx);

            pendingRequests.TryAdd(ctx, context =>
            {
                try
                {
                    // Structured events contain a copy of the CloudEvent attributes as HTTP headers.
                    var headers = context.Request.Headers;
                    Assert.Equal("1.0", headers["ce-specversion"]);
                    Assert.Equal("com.github.pull.create", headers["ce-type"]);
                    Assert.Equal("https://github.com/cloudevents/spec/pull/123", headers["ce-source"]);
                    Assert.Equal("A234-1234-1234", headers["ce-id"]);
                    Assert.Equal("2018-04-05T17:31:00Z", headers["ce-time"]);
                    // Note that datacontenttype is mapped in this case, but would not be included in binary mode.
                    Assert.Equal("text/xml", headers["ce-datacontenttype"]);
                    Assert.Equal("application/cloudevents+json", context.Request.ContentType);
                    Assert.Equal("value", headers["ce-comexampleextension1"]);
                    // The non-ASCII attribute value should have been URL-encoded using UTF-8 for the header.
                    Assert.Equal("%C3%A6%C3%B8%C3%A5", headers["ce-utf8examplevalue"]);

                    var receivedCloudEvent = context.Request.ToCloudEvent(new JsonEventFormatter());

                    Assert.Equal(CloudEventsSpecVersion.V1_0, receivedCloudEvent.SpecVersion);
                    Assert.Equal("com.github.pull.create", receivedCloudEvent.Type);
                    Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source);
                    Assert.Equal("A234-1234-1234", receivedCloudEvent.Id);
                    Assert.Equal(DateTime.Parse("2018-04-05T17:31:00Z").ToUniversalTime(),
                                 receivedCloudEvent.Time.Value.ToUniversalTime());
                    Assert.Equal(new ContentType(MediaTypeNames.Text.Xml), receivedCloudEvent.DataContentType);
                    Assert.Equal("<much wow=\"xml\"/>", receivedCloudEvent.Data);

                    var attr = receivedCloudEvent.GetAttributes();
                    Assert.Equal("value", (string)attr["comexampleextension1"]);
                    Assert.Equal("æøå", (string)attr["utf8examplevalue"]);
                    context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                }
                catch (Exception e)
                {
                    using (var sw = new StreamWriter(context.Response.OutputStream))
                    {
                        sw.Write(e.ToString());
                        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    }
                }

                context.Response.Close();
                return(Task.CompletedTask);
            });

            var httpClient = new HttpClient();
            var result     = (await httpClient.PostAsync(new Uri(listenerAddress + "ep"), content));

            if (result.StatusCode != HttpStatusCode.NoContent)
            {
                throw new InvalidOperationException(result.Content.ReadAsStringAsync().GetAwaiter().GetResult());
            }
        }
示例#22
0
        public void Id_None_Fail()
        {
            var json = @"
{
  'type': 'com.example.someevent',
  'specversion': '1.0',
  'source': '/mycontext'
}
";
            Tuple <bool, System.Collections.Generic.IReadOnlyList <string> > validationResults = CloudEvent.ValidateJsonDetailed(json);

            validationResults.Item1.Should().BeFalse();
        }
示例#23
0
        public void Type_Empty_Fail()
        {
            var json = @"
{
  'id': 'C234-1234-1234',
  'type': '',
  'specversion': '1.0',
  'source': '/mycontext'
}";

            Tuple <bool, System.Collections.Generic.IReadOnlyList <string> > validationResults = CloudEvent.ValidateJsonDetailed(json);

            validationResults.Item1.Should().BeFalse();
        }
示例#24
0
 public static string GetTraceState(this CloudEvent cloudEvent) =>
     (string)cloudEvent[TraceStateAttribute];
示例#25
0
        async Task HttpStructuredWebRequestSendTest()
        {
            var cloudEvent = new CloudEvent("com.github.pull.create",
                                            new Uri("https://github.com/cloudevents/spec/pull/123"))
            {
                Id              = "A234-1234-1234",
                Time            = new DateTime(2018, 4, 5, 17, 31, 0, DateTimeKind.Utc),
                DataContentType = new ContentType(MediaTypeNames.Text.Xml),
                Data            = "<much wow=\"xml\"/>"
            };

            var attrs = cloudEvent.GetAttributes();

            attrs["comexampleextension1"] = "value";
            attrs["utf8examplevalue"]     = "æøå";

            string         ctx            = Guid.NewGuid().ToString();
            HttpWebRequest httpWebRequest = WebRequest.CreateHttp(listenerAddress + "ep");

            httpWebRequest.Method = "POST";
            await httpWebRequest.CopyFromAsync(cloudEvent, ContentMode.Structured, new JsonEventFormatter());

            httpWebRequest.Headers.Add(testContextHeader, ctx);

            pendingRequests.TryAdd(ctx, context =>
            {
                try
                {
                    // Structured events do not contain any CloudEvent HTTP headers.
                    Assert.Empty(context.Request.Headers.AllKeys.Where(key => key.StartsWith("ce-")));

                    var receivedCloudEvent = context.Request.ToCloudEvent(new JsonEventFormatter());

                    Assert.Equal(CloudEventsSpecVersion.V1_0, receivedCloudEvent.SpecVersion);
                    Assert.Equal("com.github.pull.create", receivedCloudEvent.Type);
                    Assert.Equal(new Uri("https://github.com/cloudevents/spec/pull/123"), receivedCloudEvent.Source);
                    Assert.Equal("A234-1234-1234", receivedCloudEvent.Id);
                    Assert.Equal(DateTime.Parse("2018-04-05T17:31:00Z").ToUniversalTime(),
                                 receivedCloudEvent.Time.Value.ToUniversalTime());
                    Assert.Equal(new ContentType(MediaTypeNames.Text.Xml), receivedCloudEvent.DataContentType);
                    Assert.Equal("<much wow=\"xml\"/>", receivedCloudEvent.Data);

                    var attr = receivedCloudEvent.GetAttributes();
                    Assert.Equal("value", (string)attr["comexampleextension1"]);
                    Assert.Equal("æøå", (string)attr["utf8examplevalue"]);
                    context.Response.StatusCode = (int)HttpStatusCode.NoContent;
                }
                catch (Exception e)
                {
                    using (var sw = new StreamWriter(context.Response.OutputStream))
                    {
                        sw.Write(e.ToString());
                        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    }
                }

                context.Response.Close();
                return(Task.CompletedTask);
            });

            var result = (HttpWebResponse)await httpWebRequest.GetResponseAsync();

            if (result.StatusCode != HttpStatusCode.NoContent)
            {
                throw new InvalidOperationException(result.StatusCode.ToString());
            }
        }
示例#26
0
        public CloudEvent GetCloudEvent <T>(T pLoad, string pLoadId = null, string pLoadType       = null,
                                            string eventSubject     = null, string dataContentType = null)
        {
            CloudEvent cEvent = null;

            if (pLoad != null)
            {
                try
                {
                    // param defaults
                    if (String.IsNullOrWhiteSpace(pLoadId))
                    {
                        pLoadId = RetrievePayloadId <T>(pLoad) ?? Guid.NewGuid().ToString();
                    }
                    if (String.IsNullOrWhiteSpace(pLoadType))
                    {
                        pLoadType = typeof(T).Name; // use custom formatting for generic type definitions
                    }
                    if (String.IsNullOrWhiteSpace(dataContentType))
                    {
                        dataContentType = "application/json"; // by default serialize as json
                    }

                    var declarativeType = System.Uri.EscapeUriString($"urn:{_eventTypeUrnAuthority}:{_declarativeTypeMapper(pLoadType)}");

                    var pLoadFormatter = _pLoadFormatters.FirstOrDefault(pf => pf.SerializedContentType.Equals(dataContentType));
                    if (pLoadFormatter == null)
                    {
                        throw new ArgumentException($"No publisher formatter can serialize a payload with content type '{dataContentType}'", "targetContentType");
                    }

                    // create the CloudEvent instance
                    cEvent = new CloudEvent(type: declarativeType, source: _eventSource, id: pLoadId)
                    {
                        DataContentType = new ContentType(pLoadFormatter.SerializedContentType),
                        Data            = pLoadFormatter.Serialize <T>(pLoad)
                    };
                    if (!String.IsNullOrWhiteSpace(eventSubject))
                    {
                        cEvent.Subject = eventSubject;
                    }
                    ;

                    // info, with param list (reccomended for structured logging)
                    _logger.LogInformation(
                        "{MethodName}: created CloudEvents envelope specversion='{CloudEventsSpecVersion}' type='{CloudEventsDeclarativeType}' source='{CloudEventsSource}' id='{CloudEventsId}' subject='{CloudEventsSubject}' content-type='{CloudEventsDataContentType}'",
                        "GetCloudEvent<T>", cEvent.SpecVersion, cEvent.Type, cEvent.Source.ToString(), cEvent.Id, cEvent.Subject ?? "NA", cEvent.DataContentType.MediaType);
                }
                catch (ArgumentException agEx)
                {
                    // warn
                    _logger.LogWarning($"GetCloudEvent: cannot add the payload into a CloudEvent - '{agEx.Message}'");
                }
                catch (Exception ex)
                {
                    // err
                    _logger.LogError($"GetCloudEvent: failed with exception '{ex.Message}', of type '{ex.GetType().Name}'");
                    throw new CloudEventWriterException("GetCloudEvent", ex);
                }
            }
            else
            {
                // warn
                _logger.LogWarning("GetCloudEvent: specified payload of type '{typeof(T)}' is empty");
            }

            return(cEvent);
        }
示例#27
0
 public Task HandleAsync(CloudEvent cloudEvent, CancellationToken cancellationToken)
 {
     LastEvent = cloudEvent;
     return(Task.CompletedTask);
 }
示例#28
0
        public static async Task <HttpResponseMessage> Madlibs(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
            HttpRequestMessage req,
            ILogger log)
        {
            try
            {
                // opt into push if needed
                if (req.IsWebHookValidationRequest())
                {
                    return(await req.HandleAsWebHookValidationRequest(null, null));
                }

                if (!req.Headers.Contains("X-Callback-URL"))
                {
                    // thanks, but we can't respond without an address
                    log.LogInformation("Didn't find 'X-Callback-URL' header.");
                    return(new HttpResponseMessage(HttpStatusCode.BadRequest));
                }
                string callbackUrl = req.Headers.GetValues("X-Callback-URL").FirstOrDefault();

                CloudEvent receivedCloudEvent = req.ToCloudEvent();
                CloudEvent raisedCloudEvent   = null;

                log.LogInformation($"Processing {receivedCloudEvent.SpecVersion} with {receivedCloudEvent.Type}");
                log.LogInformation($"Callback to {callbackUrl}");

                switch (receivedCloudEvent.Type)
                {
                case "word.found.noun":
                    raisedCloudEvent = new CloudEvent("word.picked.noun",
                                                      new Uri(SourceIdentifier))
                    {
                        ContentType = Json,
                        Data        = new { word = Words.All.Nouns[rnd.Next(Words.All.Nouns.Length)] }
                    };
                    break;

                case "word.found.verb":
                    raisedCloudEvent = new CloudEvent("word.picked.verb",
                                                      new Uri(SourceIdentifier))
                    {
                        ContentType = Json,
                        Data        = new { word = Words.All.Verbs[rnd.Next(Words.All.Verbs.Length)] }
                    };
                    break;

                case "word.found.exclamation":
                    raisedCloudEvent = new CloudEvent("word.picked.exlamation",
                                                      new Uri(SourceIdentifier))
                    {
                        ContentType = Json,
                        Data        = new { word = Words.All.Exclamations[rnd.Next(Words.All.Exclamations.Length)] }
                    };
                    break;

                case "word.found.adverb":
                    raisedCloudEvent = new CloudEvent("word.picked.adverb",
                                                      new Uri(SourceIdentifier))
                    {
                        ContentType = Json,
                        Data        = new { word = Words.All.Adverbs[rnd.Next(Words.All.Adverbs.Length)] }
                    };
                    break;

                case "word.found.pluralnoun":
                    raisedCloudEvent = new CloudEvent("word.picked.pluralnoun",
                                                      new Uri(SourceIdentifier))
                    {
                        ContentType = Json,
                        Data        = new { word = Words.All.Pluralnouns[rnd.Next(Words.All.Pluralnouns.Length)] }
                    };
                    break;

                case "word.found.adjective":
                    raisedCloudEvent = new CloudEvent("word.picked.adjective",
                                                      new Uri(SourceIdentifier))
                    {
                        ContentType = Json,
                        Data        = new { word = Words.All.Adjectives[rnd.Next(Words.All.Adjectives.Length)] }
                    };
                    break;

                case "word.found.color":
                    raisedCloudEvent = new CloudEvent("word.picked.color",
                                                      new Uri(SourceIdentifier))
                    {
                        ContentType = Json,
                        Data        = new { word = Words.All.Colors[rnd.Next(Words.All.Colors.Length)] }
                    };
                    break;

                case "word.found.name":
                    raisedCloudEvent = new CloudEvent("word.picked.name",
                                                      new Uri(SourceIdentifier))
                    {
                        ContentType = Json,
                        Data        = new { word = Words.All.Names[rnd.Next(Words.All.Names.Length)] }
                    };
                    break;

                case "word.found.animal":
                    raisedCloudEvent = new CloudEvent("word.picked.animal",
                                                      new Uri(SourceIdentifier))
                    {
                        ContentType = Json,
                        Data        = new { word = Words.All.Animals[rnd.Next(Words.All.Animals.Length)] }
                    };
                    break;

                case "word.found.verbing":
                    raisedCloudEvent = new CloudEvent("word.picked.verbing",
                                                      new Uri(SourceIdentifier))
                    {
                        ContentType = Json,
                        Data        = new { word = Words.All.Verbings[rnd.Next(Words.All.Verbings.Length)] }
                    };
                    break;

                default:
                    return(new HttpResponseMessage(HttpStatusCode.NoContent));
                }

                raisedCloudEvent.GetAttributes().Add("relatedid", receivedCloudEvent.Id);

                HttpClient client = new HttpClient();
                var        result = await client.PostAsync(callbackUrl,
                                                           new CloudEventContent(raisedCloudEvent, rnd.Next(2) == 0 ? ContentMode.Binary : ContentMode.Structured,
                                                                                 new JsonEventFormatter()));

                log.LogInformation($"Callback result {result.StatusCode}");
                return(new HttpResponseMessage(result.StatusCode));
            }
            catch (Exception e)
            {
                log.LogInformation($"Exception while processing {e.ToString()}");
                throw;
            }
        }
示例#29
0
 /// <summary>
 /// Initialize a new <see cref="PublishCloudEventCommand"/>
 /// </summary>
 /// <param name="e">The <see cref="CloudEvent"/> to publish</param>
 public PublishCloudEventCommand(CloudEvent e)
 {
     this.Event = e;
 }
 public Task HandleAsync(CloudEvent cloudEvent, StorageObjectData data, CancellationToken cancellationToken)
 {
     _logger.LogInformation($"Name: {data.Name}");
     return(Task.CompletedTask);
 }