/// <summary>
        /// Executes the function with the specified CloudEvent, which is converted
        /// to an HTTP POST request using structured encoding and the specified event formatter,
        /// or a default formatter if <paramref name="formatter"/> is null.
        /// This method asserts that the request completed successfully.
        /// </summary>
        public async Task ExecuteCloudEventRequestAsync(CloudEvent cloudEvent, CloudEventFormatter?formatter = null)
        {
            var dataFormatter = cloudEvent.Data is null ? null : CloudEventFormatterAttribute.CreateFormatter(cloudEvent.Data.GetType());

            formatter = formatter ?? dataFormatter ?? s_defaultEventFormatter;
            var bytes = formatter.EncodeStructuredModeMessage(cloudEvent, out var contentType);

            contentType ??= s_applicationJsonContentType;
            var mediaContentType = new MediaTypeHeaderValue(contentType.MediaType)
            {
                CharSet = contentType.CharSet
            };
            var request = new HttpRequestMessage
            {
                // Any URI
                RequestUri = new Uri("uri", UriKind.Relative),
                // CloudEvent headers
                Content = new ReadOnlyMemoryContent(bytes)
                {
                    Headers = { ContentType = mediaContentType }
                },
                Method = HttpMethod.Post
            };

            using var client   = Server.CreateClient();
            using var response = await client.SendAsync(request);

            response.EnsureSuccessStatusCode();
        }
Exemplo n.º 2
0
        private static CloudEventFormatter CreateFormatter <T>()
        {
            var formatter = CloudEventFormatterAttribute.CreateFormatter(typeof(T));

            Assert.NotNull(formatter);
            return(formatter !);
        }
        public void EncodeBinaryModeEventData_NoData()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();
            var formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(AttributedModel));

            Assert.Empty(formatter.EncodeBinaryModeEventData(cloudEvent));
        }
Exemplo n.º 4
0
        private static async Task <T> ConvertAndDeserialize <T>(string resourceName) where T : class
        {
            var context   = GcfEventResources.CreateHttpContext(resourceName);
            var formatter = CloudEventFormatterAttribute.CreateFormatter(typeof(T))
                            ?? throw new InvalidOperationException("No formatter available");
            var cloudEvent = await GcfConverters.ConvertGcfEventToCloudEvent(context.Request, formatter);

            return((T)cloudEvent.Data);
        }
        public void DecodeBinaryEventModeData_NoData()
        {
            var formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(AttributedModel));
            var cloudEvent = new CloudEvent {
                Data = "original"
            };

            formatter.DecodeBinaryModeEventData(new byte[0], cloudEvent);
            Assert.Null(cloudEvent.Data);
        }
        public void EncodeStructuredMode_NoData()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();

            var formatter = CloudEventFormatterAttribute.CreateFormatter(typeof(AttributedModel));
            var body      = formatter.EncodeStructuredModeMessage(cloudEvent, out _);
            var jobject   = JsonEventFormatterTest.ParseJson(body);

            Assert.False(jobject.ContainsKey("data"));
            Assert.False(jobject.ContainsKey("data_base64"));
        }
        public void EncodeBinaryModeEventData_WrongType()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();

            cloudEvent.Data = new OtherModelClass {
                Text = "Wrong type"
            };
            var formatter = CloudEventFormatterAttribute.CreateFormatter(typeof(AttributedModel));

            Assert.Throws <InvalidCastException>(() => formatter.EncodeBinaryModeEventData(cloudEvent));
        }
        public void DecodeStructuredMode_NoData()
        {
            var obj = JsonEventFormatterTest.CreateMinimalValidJObject();

            byte[] bytes = Encoding.UTF8.GetBytes(obj.ToString());

            var formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(AttributedModel));
            var cloudEvent = formatter.DecodeStructuredModeMessage(bytes, null, null);

            Assert.Null(cloudEvent.Data);
        }
        public void DecodeStructuredMode_Base64Data()
        {
            var obj = JsonEventFormatterTest.CreateMinimalValidJObject();

            obj["data_base64"] = Convert.ToBase64String(Encoding.UTF8.GetBytes("{}"));
            byte[] bytes = Encoding.UTF8.GetBytes(obj.ToString());

            var formatter = CloudEventFormatterAttribute.CreateFormatter(typeof(AttributedModel));

            Assert.Throws <ArgumentException>(() => formatter.DecodeStructuredModeMessage(bytes, null, null));
        }
Exemplo n.º 10
0
        public void EncodeStructuredMode_NoData()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();

            var formatter = CloudEventFormatterAttribute.CreateFormatter(typeof(AttributedModel));
            var body      = formatter.EncodeStructuredModeMessage(cloudEvent, out _);
            var element   = JsonEventFormatterTest.ParseJson(body);

            Assert.False(element.TryGetProperty("data", out _));
            Assert.False(element.TryGetProperty("data_base64", out _));
        }
        /// <summary>
        /// Convenience method to test CloudEvents by supplying only the most important aspects.
        /// This method simply constructs a CloudEvent from the parameters and delegates to
        /// <see cref="ExecuteCloudEventRequestAsync(CloudEvent, CloudEventFormatter)"/>.
        /// </summary>
        /// <param name="eventType">The CloudEvent type.</param>
        /// <param name="data">The data to populate the CloudEvent with. If the type of the event data
        /// has <see cref="CloudEventFormatterAttribute"/> applied to it, the corresponding formatter will be used.
        /// </param>
        /// <param name="source">The source URI for the CloudEvent, or null to use a default of "//test-source".</param>
        /// <param name="subject">The subject of the CloudEvent, or null if no subject is required.</param>
        /// <typeparam name="T">The type of the event data. This is used to find the appropriate event formatter.</typeparam>
        public Task ExecuteCloudEventRequestAsync <T>(string eventType, T?data, Uri?source = null, string?subject = null)
            where T : class
        {
            var formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(T));
            var cloudEvent = new CloudEvent
            {
                Type    = eventType,
                Source  = source ?? new Uri("//test-source", UriKind.RelativeOrAbsolute),
                Id      = Guid.NewGuid().ToString(),
                Subject = subject,
                Data    = data
            };

            return(ExecuteCloudEventRequestAsync(cloudEvent, formatter));
        }
        public void EncodeBinaryModeEventData()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();

            cloudEvent.Data = new AttributedModel {
                AttributedProperty = "test"
            };
            var formatter = CloudEventFormatterAttribute.CreateFormatter(typeof(AttributedModel));
            var body      = formatter.EncodeBinaryModeEventData(cloudEvent);
            var jobject   = JsonEventFormatterTest.ParseJson(body);

            new JTokenAsserter
            {
                { AttributedModel.JsonPropertyName, JTokenType.String, "test" }
            }.AssertProperties(jobject, assertCount: true);
        }
        public void DecodeStructuredMode_ContentTypeIgnored()
        {
            var obj = JsonEventFormatterTest.CreateMinimalValidJObject();

            obj["data"] = new JObject {
                [AttributedModel.JsonPropertyName] = "test"
            };
            byte[] bytes = Encoding.UTF8.GetBytes(obj.ToString());

            var formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(AttributedModel));
            var cloudEvent = formatter.DecodeStructuredModeMessage(bytes, new ContentType("text/plain"), null);

            var model = (AttributedModel)cloudEvent.Data;

            Assert.Equal("test", model.AttributedProperty);
        }
        public void DecodeBinaryEventModeData()
        {
            var obj = new JObject {
                [AttributedModel.JsonPropertyName] = "test"
            };

            byte[] bytes = Encoding.UTF8.GetBytes(obj.ToString());

            var formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(AttributedModel));
            var cloudEvent = new CloudEvent();

            formatter.DecodeBinaryModeEventData(bytes, cloudEvent);

            var model = (AttributedModel)cloudEvent.Data;

            Assert.Equal("test", model.AttributedProperty);
        }
Exemplo n.º 15
0
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger <Startup> logger)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            logger.LogInformation("Service is starting...");

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapPost("/", async context =>
                {
                    var formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(LogEntryData));
                    var cloudEvent = await context.Request.ToCloudEventAsync(formatter);
                    logger.LogInformation("Event type: {type}", cloudEvent.Type);

                    var data = (LogEntryData)cloudEvent.Data;
                    if (!data.Operation.Last)
                    {
                        logger.LogInformation("Operation is not last, skipping event");
                        return;
                    }

                    // projects/events-atamel/zones/us-central1-a/instances/instance-1
                    var resourceName = data.ProtoPayload.ResourceName;
                    logger.LogInformation($"Resource: {resourceName}");

                    var tokens   = resourceName.Split("/");
                    var project  = tokens[1];
                    var zone     = tokens[3];
                    var instance = tokens[5];
                    var username = data.ProtoPayload.AuthenticationInfo.PrincipalEmail.Split("@")[0];

                    logger.LogInformation($"Setting label 'username:{username}' to instance '{instance}'");

                    await SetLabelsAsync(project, zone, instance, username);

                    logger.LogInformation($"Set label 'user:{username}' to instance '{instance}'");
                });
            });
        }
Exemplo n.º 16
0
        public void EncodeStructuredMode()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();

            cloudEvent.Data = new AttributedModel {
                AttributedProperty = "test"
            };
            var formatter = CloudEventFormatterAttribute.CreateFormatter(typeof(AttributedModel));
            var body      = formatter.EncodeStructuredModeMessage(cloudEvent, out _);
            var element   = JsonEventFormatterTest.ParseJson(body);

            Assert.False(element.TryGetProperty("data_base64", out _));
            var data = element.GetProperty("data");

            new JsonElementAsserter
            {
                { AttributedModel.JsonPropertyName, JsonValueKind.String, "test" }
            }.AssertProperties(data, assertCount: true);
        }
        public void EncodeStructuredMode()
        {
            var cloudEvent = new CloudEvent().PopulateRequiredAttributes();

            cloudEvent.Data = new AttributedModel {
                AttributedProperty = "test"
            };
            var formatter = CloudEventFormatterAttribute.CreateFormatter(typeof(AttributedModel));
            var body      = formatter.EncodeStructuredModeMessage(cloudEvent, out _);
            var jobject   = JsonEventFormatterTest.ParseJson(body);

            Assert.False(jobject.ContainsKey("data_base64"));
            var data = (JObject)jobject["data"];

            new JTokenAsserter
            {
                { AttributedModel.JsonPropertyName, JTokenType.String, "test" }
            }.AssertProperties(data, assertCount: true);
        }
        public async Task <string> ReadCloudSchedulerData(HttpContext context)
        {
            _logger.LogInformation("Reading cloud scheduler data");

            string              country = null;
            CloudEvent          cloudEvent;
            CloudEventFormatter formatter;
            var ceType = context.Request.Headers["ce-type"];

            switch (ceType)
            {
            case MessagePublishedData.MessagePublishedCloudEventType:
                formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(MessagePublishedData));
                cloudEvent = await context.Request.ToCloudEventAsync(formatter);

                _logger.LogInformation($"Received CloudEvent\n{cloudEvent.GetLog()}");

                var messagePublishedData = (MessagePublishedData)cloudEvent.Data;
                var pubSubMessage        = messagePublishedData.Message;
                _logger.LogInformation($"Type: {ceType} data: {pubSubMessage.Data.ToBase64()}");

                country = pubSubMessage.Data.ToStringUtf8();
                break;

            case SchedulerJobData.ExecutedCloudEventType:
                // Data: {"custom_data":"Q3lwcnVz"}
                formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(SchedulerJobData));
                cloudEvent = await context.Request.ToCloudEventAsync(formatter);

                _logger.LogInformation($"Received CloudEvent\n{cloudEvent.GetLog()}");

                var schedulerJobData = (SchedulerJobData)cloudEvent.Data;
                _logger.LogInformation($"Type: {ceType} data: {schedulerJobData.CustomData.ToBase64()}");

                country = schedulerJobData.CustomData.ToStringUtf8();
                break;
            }

            _logger.LogInformation($"Extracted country: {country}");
            return(country);
        }
Exemplo n.º 19
0
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger <Startup> logger)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        logger.LogInformation("Service is starting...");

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapPost("/", async context =>
            {
                var formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(MessagePublishedData));
                var cloudEvent = await context.Request.ToCloudEventAsync(formatter);
                logger.LogInformation("Received CloudEvent\n" + GetEventLog(cloudEvent));

                var messagePublishedData = (MessagePublishedData)cloudEvent.Data;
                var pubSubMessage        = messagePublishedData.Message;
                if (pubSubMessage == null)
                {
                    context.Response.StatusCode = 400;
                    await context.Response.WriteAsync("Bad request: Invalid Pub/Sub message format");
                    return;
                }

                var data = pubSubMessage.Data;
                logger.LogInformation($"Data: {data.ToBase64()}");

                var name = data.ToStringUtf8();
                logger.LogInformation($"Extracted name: {name}");

                var id = context.Request.Headers["ce-id"];
                await context.Response.WriteAsync($"Hello {name}! ID: {id}");
            });
        });
    }
        public async Task <(string, string)> ReadCloudStorageData(HttpContext context)
        {
            _logger.LogInformation("Reading cloud storage data");

            string              bucket = null, name = null;
            CloudEvent          cloudEvent;
            CloudEventFormatter formatter;
            var ceType = context.Request.Headers["ce-type"];

            switch (ceType)
            {
            case LogEntryData.WrittenCloudEventType:
                //"protoPayload" : {"resourceName":"projects/_/buckets/events-atamel-images-input/objects/atamel.jpg}";
                formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(LogEntryData));
                cloudEvent = await context.Request.ToCloudEventAsync(formatter);

                _logger.LogInformation($"Received CloudEvent\n{cloudEvent.GetLog()}");

                var logEntryData = (LogEntryData)cloudEvent.Data;
                var tokens       = logEntryData.ProtoPayload.ResourceName.Split('/');
                bucket = tokens[3];
                name   = tokens[5];
                break;

            case StorageObjectData.FinalizedCloudEventType:
                formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(StorageObjectData));
                cloudEvent = await context.Request.ToCloudEventAsync(formatter);

                _logger.LogInformation($"Received CloudEvent\n{cloudEvent.GetLog()}");

                var storageObjectData = (StorageObjectData)cloudEvent.Data;
                bucket = storageObjectData.Bucket;
                name   = storageObjectData.Name;
                break;

            case MessagePublishedData.MessagePublishedCloudEventType:
                // {"message": {
                //     "data": "eyJidWNrZXQiOiJldmVudHMtYXRhbWVsLWltYWdlcy1pbnB1dCIsIm5hbWUiOiJiZWFjaC5qcGcifQ==",
                // },"subscription": "projects/events-atamel/subscriptions/cre-europe-west1-trigger-resizer-sub-000"}
                formatter  = CloudEventFormatterAttribute.CreateFormatter(typeof(MessagePublishedData));
                cloudEvent = await context.Request.ToCloudEventAsync(formatter);

                _logger.LogInformation($"Received CloudEvent\n{cloudEvent.GetLog()}");

                var messagePublishedData = (MessagePublishedData)cloudEvent.Data;
                var pubSubMessage        = messagePublishedData.Message;
                _logger.LogInformation($"Type: {ceType} data: {pubSubMessage.Data.ToBase64()}");

                var decoded = pubSubMessage.Data.ToStringUtf8();
                _logger.LogInformation($"decoded: {decoded}");

                var parsed = JValue.Parse(decoded);
                bucket = (string)parsed["bucket"];
                name   = (string)parsed["name"];
                break;

            default:
                // Data:
                // {"bucket":"knative-atamel-images-input","name":"beach.jpg"}
                formatter  = new JsonEventFormatter();
                cloudEvent = await context.Request.ToCloudEventAsync(formatter);

                _logger.LogInformation($"Received CloudEvent\n{cloudEvent.GetLog()}");

                dynamic data = cloudEvent.Data;
                bucket = data.bucket;
                name   = data.name;
                break;
            }
            _logger.LogInformation($"Extracted bucket: {bucket} and name: {name}");
            return(bucket, name);
        }
Exemplo n.º 21
0
 public void CreateFormatter_NoAttribute() =>
 Assert.Null(CloudEventFormatterAttribute.CreateFormatter(typeof(NoAttribute)));
Exemplo n.º 22
0
 public void CreateFormatter_Valid() =>
 Assert.IsType <SampleCloudEventFormatter>(CloudEventFormatterAttribute.CreateFormatter(typeof(ValidAttribute)));
Exemplo n.º 23
0
 public void CreateFormatter_Invalid(Type targetType) =>
 Assert.Throws <ArgumentException>(() => CloudEventFormatterAttribute.CreateFormatter(targetType));