Skip to content

Commit

Permalink
add cloud event property filters
Browse files Browse the repository at this point in the history
Signed-off-by: Ilias Politsopoulos <[email protected]>
  • Loading branch information
IliasP91 committed Oct 13, 2023
1 parent 767dbf2 commit 567d148
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 4 deletions.
28 changes: 26 additions & 2 deletions src/Dapr.AspNetCore/CloudEventsMiddlewareOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,39 @@ public class CloudEventsMiddlewareOptions
/// </summary>
/// <remarks>
/// <para>
/// Setting this property to <c>true</c> will forward the CloudEvent properties as Request Headers in the following format.
/// Setting this property to <c>true</c> will forward all the CloudEvent properties as Request Headers.
/// For more fine grained control of which properties are forwarded you can use either <see cref="IncludedCloudEventPropertiesAsHeaders"/> or <see cref="ExcludedCloudEventPropertiesFromHeaders"/>.
/// </para>
/// <para>
/// Property names will always be prefixed with 'Cloudevent.' and lower case.
/// Property names will always be prefixed with 'Cloudevent.' and be lower case in the following format:<c>"Cloudevent.type"</c>
/// </para>
/// <para>
/// ie. A CloudEvent property <c>"type": "Example.Type"</c> will be added as <c>"Cloudevent.type": "Example.Type"</c> request header.
/// </para>
/// </remarks>
public bool ForwardCloudEventPropertiesAsHeaders { get; set; }

/// <summary>
/// Gets or sets an array of CloudEvent property names that will be forwarded as Request Headers if <see cref="ForwardCloudEventPropertiesAsHeaders"/> is set to <c>true</c>.
/// </summary>
/// <remarks>
/// <para>
/// Note: Setting this will only forwarded the listed property names.
/// </para>
/// <para>
/// ie: <c>["type", "subject"]</c>
/// </para>
/// </remarks>
public string[] IncludedCloudEventPropertiesAsHeaders { get; set; }

/// <summary>
/// Gets or sets an array of CloudEvent property names that will not be forwarded as Request Headers if <see cref="ForwardCloudEventPropertiesAsHeaders"/> is set to <c>true</c>.
/// </summary>
/// <remarks>
/// <para>
/// ie: <c>["type", "subject"]</c>
/// </para>
/// </remarks>
public string[] ExcludedCloudEventPropertiesFromHeaders { get; set; }
}
}
81 changes: 79 additions & 2 deletions test/Dapr.AspNetCore.Test/CloudEventsMiddlewareTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ public async Task InvokeAsync_ForwardsJsonPropertiesAsHeaders(string dataContent
ReadBody(httpContext.Request.Body).Should().Be("{\"name\":\"jimmy\"}");
httpContext.Request.Headers.Should().ContainKey("Cloudevent.type").WhichValue.Should().BeEquivalentTo("Test.Type");
httpContext.Request.Headers.Should().ContainKey("Cloudevent.subject").WhichValue.Should().BeEquivalentTo("Test.Subject");
return Task.CompletedTask;
});

Expand All @@ -146,8 +147,84 @@ public async Task InvokeAsync_ForwardsJsonPropertiesAsHeaders(string dataContent
var context = new DefaultHttpContext();
context.Request.ContentType = charSet == null ? "application/cloudevents+json" : $"application/cloudevents+json;charset={charSet}";
context.Request.Body = dataContentType == null ?
MakeBody("{ \"type\": \"Test.Type\", \"data\": { \"name\":\"jimmy\" } }", encoding) :
MakeBody($"{{ \"datacontenttype\": \"{dataContentType}\", \"type\":\"Test.Type\", \"data\": {{ \"name\":\"jimmy\" }} }}", encoding);
MakeBody("{ \"type\": \"Test.Type\", \"subject\": \"Test.Subject\", \"data\": { \"name\":\"jimmy\" } }", encoding) :
MakeBody($"{{ \"datacontenttype\": \"{dataContentType}\", \"type\":\"Test.Type\", \"subject\": \"Test.Subject\", \"data\": {{ \"name\":\"jimmy\" }} }}", encoding);

await pipeline.Invoke(context);
}

[Theory]
[InlineData(null, null)] // assumes application/json + utf8
[InlineData("application/json", null)] // assumes utf8
[InlineData("application/json", "utf-8")]
[InlineData("application/json", "UTF-8")]
[InlineData("application/person+json", "UTF-16")] // arbitrary content type and charset
public async Task InvokeAsync_ForwardsIncludedJsonPropertiesAsHeaders(string dataContentType, string charSet)
{
var encoding = charSet == null ? null : Encoding.GetEncoding(charSet);
var app = new ApplicationBuilder(null);
app.UseCloudEvents(new CloudEventsMiddlewareOptions
{
ForwardCloudEventPropertiesAsHeaders = true,
IncludedCloudEventPropertiesAsHeaders = new []{"type"}
});

// Do verification in the scope of the middleware
app.Run(httpContext =>
{
httpContext.Request.ContentType.Should().Be(dataContentType ?? "application/json");
ReadBody(httpContext.Request.Body).Should().Be("{\"name\":\"jimmy\"}");
httpContext.Request.Headers.Should().ContainKey("Cloudevent.type").WhichValue.Should().BeEquivalentTo("Test.Type");
httpContext.Request.Headers.Should().NotContainKey("Cloudevent.subject");
return Task.CompletedTask;
});

var pipeline = app.Build();

var context = new DefaultHttpContext();
context.Request.ContentType = charSet == null ? "application/cloudevents+json" : $"application/cloudevents+json;charset={charSet}";
context.Request.Body = dataContentType == null ?
MakeBody("{ \"type\": \"Test.Type\", \"subject\": \"Test.Subject\", \"data\": { \"name\":\"jimmy\" } }", encoding) :
MakeBody($"{{ \"datacontenttype\": \"{dataContentType}\", \"type\":\"Test.Type\", \"subject\": \"Test.Subject\", \"data\": {{ \"name\":\"jimmy\" }} }}", encoding);

await pipeline.Invoke(context);
}

[Theory]
[InlineData(null, null)] // assumes application/json + utf8
[InlineData("application/json", null)] // assumes utf8
[InlineData("application/json", "utf-8")]
[InlineData("application/json", "UTF-8")]
[InlineData("application/person+json", "UTF-16")] // arbitrary content type and charset
public async Task InvokeAsync_DoesNotForwardExcludedJsonPropertiesAsHeaders(string dataContentType, string charSet)
{
var encoding = charSet == null ? null : Encoding.GetEncoding(charSet);
var app = new ApplicationBuilder(null);
app.UseCloudEvents(new CloudEventsMiddlewareOptions
{
ForwardCloudEventPropertiesAsHeaders = true,
ExcludedCloudEventPropertiesFromHeaders = new []{"type"}
});

// Do verification in the scope of the middleware
app.Run(httpContext =>
{
httpContext.Request.ContentType.Should().Be(dataContentType ?? "application/json");
ReadBody(httpContext.Request.Body).Should().Be("{\"name\":\"jimmy\"}");
httpContext.Request.Headers.Should().NotContainKey("Cloudevent.type");
httpContext.Request.Headers.Should().ContainKey("Cloudevent.subject").WhichValue.Should().BeEquivalentTo("Test.Subject");
return Task.CompletedTask;
});

var pipeline = app.Build();

var context = new DefaultHttpContext();
context.Request.ContentType = charSet == null ? "application/cloudevents+json" : $"application/cloudevents+json;charset={charSet}";
context.Request.Body = dataContentType == null ?
MakeBody("{ \"type\": \"Test.Type\", \"subject\": \"Test.Subject\", \"data\": { \"name\":\"jimmy\" } }", encoding) :
MakeBody($"{{ \"datacontenttype\": \"{dataContentType}\", \"type\":\"Test.Type\", \"subject\": \"Test.Subject\", \"data\": {{ \"name\":\"jimmy\" }} }}", encoding);

await pipeline.Invoke(context);
}
Expand Down

0 comments on commit 567d148

Please sign in to comment.