Example #1
0
        public async Task Controller_WithValidCloudEvent_DeserializesUsingPipeline(string contentType)
        {
            // Arrange
            var expectedExtensionKey   = "comexampleextension1";
            var expectedExtensionValue = Guid.NewGuid().ToString();
            var cloudEvent             = new CloudEvent("test-type-æøå", new Uri("urn:integration-tests"))
            {
                Id = Guid.NewGuid().ToString(),
            };
            var attrs = cloudEvent.GetAttributes();

            attrs[expectedExtensionKey] = expectedExtensionValue;

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

            content.Headers.ContentType = new MediaTypeHeaderValue(contentType);

            // Act
            var result = await _factory.CreateClient().PostAsync("/api/events/receive", content);

            // Assert
            Assert.Equal(HttpStatusCode.OK, result.StatusCode);
            Assert.Contains(cloudEvent.Id, await result.Content.ReadAsStringAsync());
            Assert.Contains(cloudEvent.Type, await result.Content.ReadAsStringAsync());
            Assert.Contains($"\"{expectedExtensionKey}\":\"{expectedExtensionValue}\"", await result.Content.ReadAsStringAsync());
        }
Example #2
0
        /// <summary>
        /// Creates a new handler for handling the messages of the specified subscription
        /// </summary>
        /// <param name="subscriptionId">The id of the subscription to handle the messages for</param>
        /// <returns>A new handler for handling the messages of the specified subscription</returns>
        protected virtual EventHandler <StanMsgHandlerArgs> CreateEventHandlerFor(string subscriptionId)
        {
            return(async(sender, e) =>
            {
                this.Logger.LogInformation("An event with subject '{subject}' has been received from the underlying NATS Streaming sink.", e.Message.Subject);
                this.Logger.LogInformation("Dispatching the resulting cloud event with subject '{subject}' to the gateway...", e.Message.Subject);
                CloudEvent cloudEvent = CloudEventBuilder.FromEvent(this.EventFormatter.DecodeJObject(JsonConvert.DeserializeObject <JObject>(Encoding.UTF8.GetString(e.Message.Data))))
                                        .WithSubscriptionId(subscriptionId)
                                        .WithSequence(e.Message.Sequence)
                                        .HasBeenRedelivered(e.Message.Redelivered)
                                        .Build();
                CloudEventContent cloudEventContent = new CloudEventContent(cloudEvent, ContentMode.Structured, new JsonEventFormatter());
                using (HttpResponseMessage response = await this.HttpClient.PostAsync("pub", cloudEventContent))
                {
                    string content = await response.Content?.ReadAsStringAsync();

                    if (!response.IsSuccessStatusCode)
                    {
                        this.Logger.LogError($"An error occured while dispatching a cloud event of type '{{eventType}}' to the eventing controller: the remote server response with a '{{statusCode}}' status code.{Environment.NewLine}Details: {{responseContent}}", cloudEvent.Type, response.StatusCode, content);
                        response.EnsureSuccessStatusCode();
                    }
                }
                this.Logger.LogInformation("The cloud event with subject '{subject}' has been successfully dispatched to the gateway.", e.Message.Subject);
                e.Message.Ack();
            });
        }
Example #3
0
        /// <inheritdoc/>
        public virtual async Task DispatchAsync(CloudEvent cloudEvent, CancellationToken cancellationToken = default)
        {
            this.Logger.LogInformation("Publishing a cloud event to all related subscriptions...");
            List <ISubscription> subscriptions = new List <ISubscription>();

            subscriptions.AddRange(this.SubscriptionManager.GetSubscriptionsBySubject(cloudEvent.Subject));
            subscriptions.AddRange(this.SubscriptionManager.GetSubscriptionsByEventType(cloudEvent.Type));
            subscriptions.AddRange(this.SubscriptionManager.GetSubscriptionsByEventSource(cloudEvent.Source));
            this.Logger.LogInformation("{subscriptionCount} matching subscriptions found.", subscriptions.Count);
            CloudEventContent cloudEventContent = new CloudEventContent(cloudEvent, ContentMode.Structured, new JsonEventFormatter());

            foreach (ISubscription subscription in subscriptions.Distinct())
            {
                this.Logger.LogInformation("{subscriberCount} subscribers found for subscription with id '{subscriptionId}'", subscription.Subscribers.Count, subscription.Id);
                foreach (Uri subscriberAddress in subscription.Subscribers)
                {
                    using (HttpResponseMessage response = await this.HttpClient.PostAsync(subscriberAddress, cloudEventContent, cancellationToken))
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            this.Logger.LogInformation("The cloud event has been successfully dispatched to subscriber '{subscriberAddress}'", subscriberAddress);
                        }
                        else
                        {
                            this.Logger.LogError($"Failed to dispatch the cloud event to '{{subscriberAddress}}': the server responded with a non-success status code '{{statusCode}}'.{Environment.NewLine}Details: {{responseContent}}", subscriberAddress, response.StatusCode, await response.Content?.ReadAsStringAsync());
                        }
                    }
                }
            }
            this.Logger.LogInformation("The cloud event has been published to all related subscriptions.");
        }
Example #4
0
        public async Task PublishAsync <T>(T message)
            where T : class
        {
            //var json = JsonConvert.SerializeObject(message);

            var topic = message.GetType().FullName;

            var cloudEvent = new CloudEvent(topic, this.Source)
            {
                DataContentType = new ContentType(MediaTypeNames.Application.Json),
                Data            = message
            };

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

            var json = await content.ReadAsStringAsync();

            _logger.LogInformation("Busk - Publishing event {Topic}: {Body}", cloudEvent.Type, json);
            var url      = Url.Combine(this.Endpoint, Magic.VirtualPath.Publish);
            var response = await _httpClient.PostAsync(url, content);
        }
        protected override string Execute(TaskContext context, string input)
        {
            try
            {
                Result++;

                var cloudEvent = new CloudEvent("com.hello.cron-event", new Uri("urn:hello-com:cron-source"))
                {
                    DataContentType = new ContentType(MediaTypeNames.Application.Json),
                    Data            = JsonConvert.SerializeObject(new
                    {
                        Id    = context.OrchestrationInstance.InstanceId,
                        JobId = input,
                        Result
                    })
                };

                var content = new CloudEventContent(cloudEvent, ContentMode.Structured, new JsonEventFormatter());
                Console.WriteLine($"Going to post data: {JsonConvert.SerializeObject(cloudEvent.Data)} to Url: {Environment.GetEnvironmentVariable("SINK")}");
                var result = _httpClient.PostAsync(Environment.GetEnvironmentVariable("SINK"), content).Result;
                return
                    ($"Cron Job '{input}' Completed... @{DateTime.UtcNow} Response: {result} Event: {JsonConvert.SerializeObject(cloudEvent.Data)}");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
Example #6
0
        public async Task PublishAsync(CloudEvent cloudEvent)
        {
            _logger.LogInformation(
                "Publishing event {Type} with id {Id} from {Source} with data: {Data}",
                cloudEvent.Type,
                cloudEvent.Id,
                cloudEvent.Source,
                JsonConvert.SerializeObject(cloudEvent.Data)
                );

            var httpClientHandler = new HttpClientHandler()
            {
                ClientCertificateOptions = ClientCertificateOption.Manual,
                ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => true
            };
            var httpClient = new HttpClient(httpClientHandler);

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


            var json = await content.ReadAsStringAsync();

            _logger.LogWarning("Publishing event {CloudEventContent}", json);

            foreach (var endpoint in await _storageProvider.GetSubscriptionsAsync(cloudEvent.Type))
            {
                var response = await httpClient.PostAsync(endpoint, content);
            }
        }
Example #7
0
        /// <summary>
        /// Dispatches the <see cref="ResolvedEvent"/> to the <see cref="CloudEvent"/> gateway
        /// </summary>
        /// <param name="subscriptionId">The id of the subscription the <see cref="CloudEvent"/> originates from</param>
        /// <param name="e">The <see cref="ResolvedEvent"/> to dispatch</param>
        /// <returns>A new awaitable <see cref="Task"/></returns>
        protected virtual async Task DispatchEventAsync(string subscriptionId, ResolvedEvent e)
        {
            try
            {
                this.Logger.LogInformation("An event has been received from the underlying EventStore sink.");
                this.Logger.LogInformation("Dispatching the resulting cloud event to the gateway...");
                CloudEvent cloudEvent = CloudEventBuilder.FromEvent(this.EventFormatter.DecodeJObject(JsonConvert.DeserializeObject <JObject>(Encoding.UTF8.GetString(e.Event.Data))))
                                        .WithSubscriptionId(subscriptionId)
                                        .WithSequence((ulong)e.Event.EventNumber)
                                        .Build();
                CloudEventContent cloudEventContent = new CloudEventContent(cloudEvent, ContentMode.Structured, new JsonEventFormatter());
                using (HttpResponseMessage response = await this.HttpClient.PostAsync("pub", cloudEventContent))
                {
                    string content = await response.Content?.ReadAsStringAsync();

                    if (!response.IsSuccessStatusCode)
                    {
                        this.Logger.LogError($"An error occured while dispatching a cloud event of type '{{eventType}}' to the eventing controller: the remote server response with a '{{statusCode}}' status code.{Environment.NewLine}Details: {{responseContent}}", cloudEvent.Type, response.StatusCode, content);
                        response.EnsureSuccessStatusCode();
                    }
                }
                this.Logger.LogInformation("The cloud event has been successfully dispatched to the gateway.");
            }
            catch (HttpRequestException)
            {
                throw;
            }
            catch (Exception ex)
            {
                this.Logger.LogError($"An error occured while dispatching a cloud event to the gateway.{Environment.NewLine}Details: {{ex}}", ex.Message);
                throw;
            }
        }
Example #8
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";

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

            content.Headers.Add(testContextHeader, ctx);

            pendingRequests.TryAdd(ctx, async context =>
            {
                try
                {
                    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"]);
                    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();
            });

            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());
            }
        }
        /// <summary>
        ///     Publish an event grid message as CloudEvent.
        /// </summary>
        /// <param name="cloudEvent">The event to publish.</param>
        public async Task PublishAsync(CloudEvent cloudEvent)
        {
            Guard.NotNull(cloudEvent, nameof(cloudEvent));

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

            await PublishContentToTopicAsync(content);
        }
Example #10
0
        void ContentType_FromCloudEvent_BinaryMode()
        {
            var cloudEvent = CreateEmptyCloudEvent();

            cloudEvent.DataContentType = new ContentType("text/plain");
            var content             = new CloudEventContent(cloudEvent, ContentMode.Binary, new JsonEventFormatter());
            var expectedContentType = new MediaTypeHeaderValue("text/plain");

            Assert.Equal(expectedContentType, content.Headers.ContentType);
        }
Example #11
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());

            var httpClient = new HttpClient();
            var result     = (await httpClient.PostAsync(this.Url, content));

            Console.WriteLine(result.StatusCode);
        }
Example #12
0
        public Opportunity Request(AdvertisementRequest request)
        {
            var cloudEvent = new CloudEvent("com.example.myevent", new Uri("urn:example-com:mysource"))
            {
                DataContentType = new ContentType(MediaTypeNames.Application.Json),
                Data            = JsonConvert.SerializeObject("hey there!")
            };

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

            var httpClient = new HttpClient();
            var result     = httpClient.PostAsync("", content);

            return(null);
        }
        private static CloudEventContent GetResponseForEvent(CloudEvent receivedEvent)
        {
            var input   = JsonSerializer.Deserialize <SampleInput>(receivedEvent.Data.ToString());
            var content = new CloudEventContent
                          (
                new CloudEvent(CloudEventResponseType, new Uri(CloudEventResponseUri))
            {
                DataContentType = new ContentType(MediaTypeNames.Application.Json),
                Data            = new SampleOutput {
                    Message = $"Hello, {input.Name}"
                },
            },
                ContentMode.Structured,
                new JsonEventFormatter()
                          );

            return(content);
        }
Example #14
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());

            var httpClient = new HttpClient();
            // 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);
        }
        public async Task <ActionResult> SendCloudEvent()
        {
            var source     = "urn:example-com:mysource:abc";
            var type       = "com.example.myevent";
            var cloudEvent = new CloudEvent(type, new Uri(source))
            {
                DataContentType = new ContentType(MediaTypeNames.Application.Json),
                Data            = JsonConvert.SerializeObject("hey there!")
            };

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

            var httpClient = new HttpClient();
            var url        = new Uri("http://localhost:5000/api/events/receive");
            var result     = await httpClient.PostAsync(url, content);

            return(Ok(result));
        }
        /// <summary>
        /// Allows you to send an instance of T to the <see cref="ISpigotStream"/>
        /// </summary>
        /// <param name="eventData">The data to be sent over</param>
        public void Send(T eventData)
        {
            var wrapper = new CloudEvent(CloudEventsSpecVersion.Default, new ICloudEventExtension[]
            {
                new SamplingExtension(),
                new DistributedTracingExtension(),
                new IntegerSequenceExtension()
            })
            {
                Data            = _spigot.Serializer.Serialize(eventData),
                DataContentType = _spigot.Serializer.ContentType,
                Type            = typeof(T).Name,
                Subject         = typeof(T).FullName,
                Source          = new Uri
                                  (
                    $"urn:spigot-{Environment.CurrentManagedThreadId}:{_spigot.ApplicationName}:{_spigot.InstanceIdentifier}"
                                  )
            };

            _spigot.BeforeSend?.Invoke(wrapper);
            _logger.LogTrace("Sending [{0}] with id {1}", wrapper.Type, wrapper.Id);

            //Send it to all listeners in the same process space
            if (_spigot.Knobs.ContainsKey(typeof(T).Name))
            {
                _spigot.Knobs[typeof(T).Name]?.Invoke(wrapper);
            }

            var contents = new CloudEventContent(wrapper, ContentMode.Structured, new JsonEventFormatter());
            var bytes    = contents.ReadAsByteArrayAsync().GetAwaiter().GetResult();

            foreach (var stream in _spigot.Streams)
            {
                _spigot.Resilience.Sending.Execute(() =>
                {
                    _logger.LogTrace("Sending using resilience.");
                    var result = stream?.TrySend(bytes);
                    if (!result.GetValueOrDefault())
                    {
                        throw new Exception("Sending exception");
                    }
                });
            }
        }
        /// <summary>
        ///     Publish Cloud Event to a given topic
        /// </summary>
        /// <param name="cloudEvent">Event to publish</param>
        public async Task Publish(CloudEvent cloudEvent)
        {
            var content = new CloudEventContent(cloudEvent, ContentMode.Structured, new JsonEventFormatter());

            var httpRequest = new HttpRequestMessage(HttpMethod.Post, TopicEndpointUri)
            {
                Content = content
            };

            var response = await _httpClient.SendAsync(httpRequest);

            if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Accepted)
            {
                _logger.LogInformation($"Event '{cloudEvent.Id}' was forwarded to event topic uri '{TopicEndpointUri}'");
            }
            else
            {
                _logger.LogError($"Failed to forward event '{cloudEvent.Id}' to event topic uri '{TopicEndpointUri}'");
            }
        }
Example #18
0
        public async Task publishEvent(string url, string name)
        {
            var cloudEvent = new CloudEvent("webapp.image.uploaded",
                                            new Uri("urn:webapp.dev:webapp"))
            {
                ContentType = new ContentType(MediaTypeNames.Application.Json),
                SpecVersion = CloudEventsSpecVersion.V0_2,
                Data        = JsonConvert.SerializeObject(new
                {
                    url   = url,
                    title = name
                })
            };

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

            var httpClient = new HttpClient();
            await httpClient.PostAsync(BrokerUrl, content);
        }
        private async void SendCloudEventForCertificate(string name)
        {
            _logger.LogInformation("Sending cloud event for secret {Name}", name);
            var cloudEvent = new CloudEvent("Microsoft.KeyVault.SecretExpired",
                                            new Uri("https://labrats.shawnross.dev/async-function/keyvault-credential-rotator"))
            {
                DataContentType = new ContentType(MediaTypeNames.Application.Json),
                Data            = new CertificateExpiryEvent
                {
                    ObjectType = "Secret",
                    ObjectName = name
                }
            };

            _logger.LogInformation("Creating content type");
            var content = new CloudEventContent(cloudEvent, ContentMode.Structured, new JsonEventFormatter());

            var httpClient = new HttpClient();

            _logger.LogInformation("Sending request");
            var result =
                await httpClient.PostAsync("https://labrats.shawnross.dev/async-function/keyvault-secret-rotate",
                                           // I know this is kind of scuffed, but this is the best I can do currently with the limited timespan.
                                           new StringContent("[" + await content.ReadAsStringAsync() + "]", Encoding.UTF8, "application/json"));

            _logger.LogInformation("Request {Request}", await result.RequestMessage.Content.ReadAsStringAsync());

            if (result.IsSuccessStatusCode)
            {
                _logger.LogInformation("Successfully rotated secret");
            }
            else
            {
                var resultString = await result.Content.ReadAsStringAsync();

                _logger.LogError("Result unsuccessful: \n{Result}", resultString);
            }
        }
Example #20
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);
        }
Example #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());
            }
        }
Example #22
0
        async Task HttpBinaryClientSendTest()
        {
            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.Binary, new JsonEventFormatter());

            content.Headers.Add(testContextHeader, ctx);

            pendingRequests.TryAdd(ctx, context =>
            {
                try
                {
                    Assert.True(context.Request.IsCloudEvent());

                    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);

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

                    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"]);
                    // The non-ASCII attribute value should have been correctly URL-decoded.
                    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());
            }
        }
 public CloudEventActionResult(HttpStatusCode statusCode, CloudEventContent content)
 {
     this.statusCode = statusCode;
     this.content    = content;
 }