Bumping ASP.Net package to 3.0, implementing async decoding of CloudEvents

Signed-off-by: Tobias Lønnerød Madsen <m@dsen.tv>
This commit is contained in:
Tobias Lønnerød Madsen 2019-11-06 12:12:29 +01:00
parent 9d5c20e00b
commit aa78505be6
No known key found for this signature in database
GPG Key ID: E51953EA8372F2AC
7 changed files with 41 additions and 25 deletions

View File

@ -1,15 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\CloudNative.CloudEvents.AspNetCore\CloudNative.CloudEvents.AspNetCore.csproj" /> <ProjectReference Include="..\..\src\CloudNative.CloudEvents.AspNetCore\CloudNative.CloudEvents.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\CloudNative.CloudEvents\CloudNative.CloudEvents.csproj" /> <ProjectReference Include="..\..\src\CloudNative.CloudEvents\CloudNative.CloudEvents.csproj" />

View File

@ -9,6 +9,7 @@ namespace CloudNative.CloudEvents.AspNetCoreSample
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
public class Startup public class Startup
{ {
@ -22,21 +23,26 @@ namespace CloudNative.CloudEvents.AspNetCoreSample
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.AddMvc(opts => services.AddControllers(opts =>
{ {
opts.InputFormatters.Insert(0, new CloudEventInputFormatter()); opts.InputFormatters.Insert(0, new CloudEventInputFormatter());
}); });
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env) public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{ {
if (env.IsDevelopment()) if (env.IsDevelopment())
{ {
app.UseDeveloperExceptionPage(); app.UseDeveloperExceptionPage();
} }
app.UseMvc(); app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
} }
} }
} }

View File

@ -21,7 +21,7 @@ namespace CloudNative.CloudEvents
SupportedEncodings.Add(Encoding.Unicode); SupportedEncodings.Add(Encoding.Unicode);
} }
public override Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding) public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
{ {
if (context == null) if (context == null)
{ {
@ -37,12 +37,12 @@ namespace CloudNative.CloudEvents
try try
{ {
var cloudEvent = request.ToCloudEvent(); var cloudEvent = await request.ReadCloudEventAsync();
return InputFormatterResult.SuccessAsync(cloudEvent); return await InputFormatterResult.SuccessAsync(cloudEvent);
} }
catch (Exception) catch (Exception)
{ {
return InputFormatterResult.FailureAsync(); return await InputFormatterResult.FailureAsync();
} }
} }

View File

@ -9,6 +9,7 @@ namespace CloudNative.CloudEvents
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Net.Mime; using System.Net.Mime;
using System.Threading.Tasks;
public static class HttpRequestExtension public static class HttpRequestExtension
{ {
@ -26,10 +27,10 @@ namespace CloudNative.CloudEvents
/// <param name="httpRequest">HTTP request</param> /// <param name="httpRequest">HTTP request</param>
/// <param name="extensions">List of extension instances</param> /// <param name="extensions">List of extension instances</param>
/// <returns>A CloudEvent instance or 'null' if the request message doesn't hold a CloudEvent</returns> /// <returns>A CloudEvent instance or 'null' if the request message doesn't hold a CloudEvent</returns>
public static CloudEvent ToCloudEvent(this HttpRequest httpRequest, public static ValueTask<CloudEvent> ReadCloudEventAsync(this HttpRequest httpRequest,
params ICloudEventExtension[] extensions) params ICloudEventExtension[] extensions)
{ {
return ToCloudEvent(httpRequest, null, extensions); return ReadCloudEventAsync(httpRequest, null, extensions);
} }
/// <summary> /// <summary>
@ -40,7 +41,7 @@ namespace CloudNative.CloudEvents
/// <param name="formatter"></param> /// <param name="formatter"></param>
/// <param name="extensions">List of extension instances</param> /// <param name="extensions">List of extension instances</param>
/// <returns>A CloudEvent instance or 'null' if the request message doesn't hold a CloudEvent</returns> /// <returns>A CloudEvent instance or 'null' if the request message doesn't hold a CloudEvent</returns>
public static CloudEvent ToCloudEvent(this HttpRequest httpRequest, public static async ValueTask<CloudEvent> ReadCloudEventAsync(this HttpRequest httpRequest,
ICloudEventFormatter formatter = null, ICloudEventFormatter formatter = null,
params ICloudEventExtension[] extensions) params ICloudEventExtension[] extensions)
{ {
@ -63,7 +64,7 @@ namespace CloudNative.CloudEvents
} }
} }
return formatter.DecodeStructuredEvent(httpRequest.Body, extensions); return await formatter.DecodeStructuredEventAsync(httpRequest.Body, extensions);
} }
else else
{ {
@ -103,7 +104,9 @@ namespace CloudNative.CloudEvents
if (httpRequestHeader.StartsWith(HttpHeaderPrefix, StringComparison.InvariantCultureIgnoreCase)) if (httpRequestHeader.StartsWith(HttpHeaderPrefix, StringComparison.InvariantCultureIgnoreCase))
{ {
string headerValue = httpRequest.Headers[httpRequestHeader]; string headerValue = httpRequest.Headers[httpRequestHeader];
if (headerValue.StartsWith("{") && headerValue.EndsWith("}") || // maps in headers have been abolished in 1.0
if (version != CloudEventsSpecVersion.V1_0 &&
headerValue.StartsWith("{") && headerValue.EndsWith("}") ||
headerValue.StartsWith("[") && headerValue.EndsWith("]")) headerValue.StartsWith("[") && headerValue.EndsWith("]"))
{ {
attributes[httpRequestHeader.Substring(3)] = attributes[httpRequestHeader.Substring(3)] =
@ -112,7 +115,6 @@ namespace CloudNative.CloudEvents
else else
{ {
attributes[httpRequestHeader.Substring(3)] = headerValue; attributes[httpRequestHeader.Substring(3)] = headerValue;
attributes[httpRequestHeader.Substring(3)] = headerValue;
} }
} }
} }
@ -124,6 +126,5 @@ namespace CloudNative.CloudEvents
return cloudEvent; return cloudEvent;
} }
} }
} }
} }

View File

@ -7,6 +7,7 @@ namespace CloudNative.CloudEvents
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Net.Mime; using System.Net.Mime;
using System.Threading.Tasks;
/// <summary> /// <summary>
@ -22,6 +23,13 @@ namespace CloudNative.CloudEvents
/// <returns></returns> /// <returns></returns>
CloudEvent DecodeStructuredEvent(Stream data, IEnumerable<ICloudEventExtension> extensions); CloudEvent DecodeStructuredEvent(Stream data, IEnumerable<ICloudEventExtension> extensions);
/// <summary> /// <summary>
/// Decode a structured event from a stream asynchonously
/// </summary>
/// <param name="data"></param>
/// <param name="extensions"></param>
/// <returns></returns>
Task<CloudEvent> DecodeStructuredEventAsync(Stream data, IEnumerable<ICloudEventExtension> extensions);
/// <summary>
/// Decode a structured event from a byte array /// Decode a structured event from a byte array
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>

View File

@ -5,12 +5,12 @@
namespace CloudNative.CloudEvents namespace CloudNative.CloudEvents
{ {
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Mime; using System.Net.Mime;
using System.Text; using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -27,6 +27,13 @@ namespace CloudNative.CloudEvents
return DecodeStructuredEvent(data, (IEnumerable<ICloudEventExtension>)extensions); return DecodeStructuredEvent(data, (IEnumerable<ICloudEventExtension>)extensions);
} }
public async Task<CloudEvent> DecodeStructuredEventAsync(Stream data, IEnumerable<ICloudEventExtension> extensions)
{
var jsonReader = new JsonTextReader(new StreamReader(data, Encoding.UTF8, true, 8192, true));
var jObject = await JObject.LoadAsync(jsonReader);
return DecodeJObject(jObject, extensions);
}
public CloudEvent DecodeStructuredEvent(Stream data, IEnumerable<ICloudEventExtension> extensions = null) public CloudEvent DecodeStructuredEvent(Stream data, IEnumerable<ICloudEventExtension> extensions = null)
{ {
var jsonReader = new JsonTextReader(new StreamReader(data, Encoding.UTF8, true, 8192, true)); var jsonReader = new JsonTextReader(new StreamReader(data, Encoding.UTF8, true, 8192, true));

View File

@ -1,14 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp3.0</TargetFramework>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" /> <PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="xunit" Version="2.4.0" /> <PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup> </ItemGroup>