/// <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(); }
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)); }
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)); }
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); }
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}'"); }); }); }
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); }
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); }
public void CreateFormatter_NoAttribute() => Assert.Null(CloudEventFormatterAttribute.CreateFormatter(typeof(NoAttribute)));
public void CreateFormatter_Valid() => Assert.IsType <SampleCloudEventFormatter>(CloudEventFormatterAttribute.CreateFormatter(typeof(ValidAttribute)));
public void CreateFormatter_Invalid(Type targetType) => Assert.Throws <ArgumentException>(() => CloudEventFormatterAttribute.CreateFormatter(targetType));