Skip to content

Commit

Permalink
Add function layer to process HTTP request
Browse files Browse the repository at this point in the history
  • Loading branch information
justinyoo committed Oct 26, 2017
1 parent e56b0e4 commit 85e3308
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 13 deletions.
25 changes: 24 additions & 1 deletion src/AglCodingTest.Functions/AglCodingTest.Functions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
<PackageReference Include="Legacy2CPSWorkaround" Version="1.0.0">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNet.WebApi.Core">
<Version>5.2.3</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>9.0.1</Version>
</PackageReference>
Expand All @@ -49,8 +52,28 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<Compile Include="AglCodingTestHttpTriggerFunction.cs" />
<Compile Include="IAglCodingTestHttpTriggerFunction.cs" />
<Compile Include="IFunction.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AglCodingTest.Extensions\AglCodingTest.Extensions.csproj">
<Project>{b6bb1c52-6b75-4316-b50b-9a6a160b2252}</Project>
<Name>AglCodingTest.Extensions</Name>
</ProjectReference>
<ProjectReference Include="..\AglCodingTest.Models\AglCodingTest.Models.csproj">
<Project>{c7d5bbb5-482d-49f6-9e0e-9f33f95a64cd}</Project>
<Name>AglCodingTest.Models</Name>
</ProjectReference>
<ProjectReference Include="..\AglCodingTest.Services\AglCodingTest.Services.csproj">
<Project>{2d1b8fd2-f4f5-4354-80fb-569d3491d78b}</Project>
<Name>AglCodingTest.Services</Name>
</ProjectReference>
<ProjectReference Include="..\AglCodingTest.Settings\AglCodingTest.Settings.csproj">
<Project>{074176de-e0ed-455c-814b-c96c5c3e85df}</Project>
<Name>AglCodingTest.Settings</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
80 changes: 80 additions & 0 deletions src/AglCodingTest.Functions/AglCodingTestHttpTriggerFunction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

using AglCodingTest.Extensions;
using AglCodingTest.Models;
using AglCodingTest.Services;
using AglCodingTest.Services.ServiceOptions;
using AglCodingTest.Settings;

namespace AglCodingTest.Functions
{
/// <summary>
/// This represents the function entity to process for AGL coding test.
/// </summary>
public class AglCodingTestHttpTriggerFunction : IAglCodingTestHttpTriggerFunction
{
private readonly AppSettings _appSettings;
private readonly IAglPayloadLoadingService _service;

private bool _disposed;

/// <summary>
/// Initializes a new instance of the <see cref="AglCodingTestHttpTriggerFunction"/> class.
/// </summary>
/// <param name="appSettings"><see cref="AppSettings"/> instance.</param>
/// <param name="service"><see cref="IAglPayloadLoadingService"/> instance.</param>
public AglCodingTestHttpTriggerFunction(AppSettings appSettings, IAglPayloadLoadingService service)
{
this._appSettings = appSettings.ThrowIfNullOrDefault();
this._service = service.ThrowIfNullOrDefault();
}

/// <inheritdoc />
public async Task<object> InvokeAsync<TIn, TOptions>(TIn input, TOptions options)
where TOptions : ServiceOptionsBase
{
var req = input as HttpRequestMessage;
req.ThrowIfNullOrDefault();

options.ThrowIfNullOrDefault();

var serviceOptions = options as AglPayloadLoadingServiceOptions;
serviceOptions.ThrowIfNullOrDefault();

await this._service.InvokeAsync(serviceOptions).ConfigureAwait(false);

var catOwners = serviceOptions.People
.Where(p => p.Pets.Any(q => q.PetType == PetType.Cat))
.OrderBy(p => p.GenderType)
.Select(p => new { Gender = p.GenderType, Names = p.Pets.Where(q => q.PetType == PetType.Cat).OrderBy(q => q.Name).Select(q => q.Name) })
.Select(p => $"<h1>{p.Gender}</h1><ul>{string.Join(string.Empty, p.Names.Select(q => $"<li>{q}</li>"))}</ul>")
.ToList();

var html = new StringBuilder();
html.AppendLine("<html><body>");
html.AppendLine(string.Join(string.Empty, catOwners));
html.AppendLine("</body></html>");

var res = req.CreateResponse(HttpStatusCode.OK, html.ToString(), "text/html");

return res;
}

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (this._disposed)
{
return;
}

this._disposed = true;
}
}
}
12 changes: 0 additions & 12 deletions src/AglCodingTest.Functions/Class1.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace AglCodingTest.Functions
{
/// <summary>
/// This provides interfaces to the <see cref="AglCodingTestHttpTriggerFunction"/> class.
/// </summary>
public interface IAglCodingTestHttpTriggerFunction : IFunction
{
}
}
24 changes: 24 additions & 0 deletions src/AglCodingTest.Functions/IFunction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Threading.Tasks;

using AglCodingTest.Services.ServiceOptions;

namespace AglCodingTest.Functions
{
/// <summary>
/// This provides interfaces to all classes in the function layer.
/// </summary>
public interface IFunction : IDisposable
{
/// <summary>
/// Invokes the function.
/// </summary>
/// <typeparam name="TIn">Type of input instance.</typeparam>
/// <typeparam name="TOptions">Type of service options instance.</typeparam>
/// <param name="input"><see cref="TIn"/> instance.</param>
/// <param name="options"><see cref="TOptions"/> instance.</param>
/// <returns>Returns <see cref="TOut"/> instance.</returns>
Task<object> InvokeAsync<TIn, TOptions>(TIn input, TOptions options)
where TOptions : ServiceOptionsBase;
}
}

0 comments on commit 85e3308

Please sign in to comment.