Swagger UI: a working version
Main changes: - Added Azure Functions with Swagger UI and OpenAPI spec; - Nuget packages conflicting with Swagger and the build process were removed; - Some small changes in tests to make the build work after duplicate packages were removed and library classes got loaded with other versions and changed API methods. Minor changes: - duplicate/useless Nuget packages were also cleaned up in the process; - NUnit was removed to avoid using two testing frameworks.
This commit is contained in:
Родитель
f7238ba6fe
Коммит
fd960cd00e
|
@ -5,13 +5,8 @@
|
|||
<UserSecretsId>e2c7f1fa-5d0c-47e5-8441-1f52ec2a4998</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.15.0" />
|
||||
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.CosmosDB" Version="3.0.7" />
|
||||
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="4.0.2" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="5.2.8" />
|
||||
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.11" />
|
||||
<PackageReference Include="Moq" Version="4.14.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="host.json">
|
||||
|
|
|
@ -8,11 +8,6 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||
<PackageReference Include="Moq" Version="4.14.1" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace MultiCdnApi
|
|||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Swagger;
|
||||
|
||||
public class CacheFunctions
|
||||
{
|
||||
|
@ -33,6 +34,15 @@ namespace MultiCdnApi
|
|||
this.userRequestTable = userRequestTable;
|
||||
}
|
||||
|
||||
[PostContent("cachePurgeRequest", "Cache Purge Request: a JSON describing what urls to purge",
|
||||
@"{" + "\n"
|
||||
+ @" ""Description"": ""Operation Description""," + "\n"
|
||||
+ @" ""Hostname"": ""Purge Hostname""," + "\n"
|
||||
+ @" ""Urls"": [" + "\n"
|
||||
+ @" ""url1""," + "\n"
|
||||
+ @" ""url2""" + "\n"
|
||||
+ @" ]" + "\n"
|
||||
+ @"}")]
|
||||
[FunctionName("CreateCachePurgeRequestByHostname")]
|
||||
public async Task<IActionResult> CreateCachePurgeRequestByHostname(
|
||||
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "{partnerId:guid}/CachePurgeByHostname")]
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
* Licensed under the MIT License.
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
using AzureFunctions.Extensions.Swashbuckle;
|
||||
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Reflection;
|
||||
using MultiCdnApi;
|
||||
using MultiCdnApi.Swagger;
|
||||
using CachePurgeLibrary;
|
||||
using CdnLibrary;
|
||||
|
||||
|
@ -16,9 +19,14 @@ namespace MultiCdnApi
|
|||
{
|
||||
public override void Configure(IFunctionsHostBuilder builder)
|
||||
{
|
||||
builder.Services.AddSingleton<IRequestTable<Partner>>((s) => { return new PartnerTable(); });
|
||||
builder.Services.AddSingleton<IRequestTable<UserRequest>>((s) => { return new UserRequestTable(); });
|
||||
builder.Services.AddSingleton<IPartnerRequestTableManager<CDN>>((s) => { return new PartnerRequestTableManager(); });
|
||||
builder.Services.AddSingleton<IRequestTable<Partner>>(s => new PartnerTable());
|
||||
builder.Services.AddSingleton<IRequestTable<UserRequest>>(s => new UserRequestTable());
|
||||
builder.Services.AddSingleton<IPartnerRequestTableManager<CDN>>(s => new PartnerRequestTableManager());
|
||||
|
||||
builder.AddSwashBuckle(Assembly.GetExecutingAssembly(),
|
||||
options => {
|
||||
options.ConfigureSwaggerGen = genOptions => genOptions.OperationFilter<PostContentFilter>();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
namespace MultiCdnApi
|
||||
{
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using AzureFunctions.Extensions.Swashbuckle;
|
||||
using AzureFunctions.Extensions.Swashbuckle.Attribute;
|
||||
using Microsoft.Azure.WebJobs;
|
||||
using Microsoft.Azure.WebJobs.Extensions.Http;
|
||||
|
||||
public static class SwaggerFunctions
|
||||
{
|
||||
[SwaggerIgnore]
|
||||
[FunctionName("SwaggerJson")]
|
||||
public static Task<HttpResponseMessage> SwaggerJson(
|
||||
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger/json")]
|
||||
HttpRequestMessage req,
|
||||
[SwashBuckleClient] ISwashBuckleClient swashBuckleClient)
|
||||
{
|
||||
return Task.FromResult(swashBuckleClient.CreateSwaggerDocumentResponse(req));
|
||||
}
|
||||
|
||||
[SwaggerIgnore]
|
||||
[FunctionName("SwaggerUi")]
|
||||
public static Task<HttpResponseMessage> SwaggerUi(
|
||||
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "swagger/ui")]
|
||||
HttpRequestMessage req,
|
||||
[SwashBuckleClient] ISwashBuckleClient swashBuckleClient)
|
||||
{
|
||||
return Task.FromResult(swashBuckleClient.CreateSwaggerUIResponse(req, "swagger/json"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,10 +4,9 @@
|
|||
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Azure.Identity" Version="1.3.0" />
|
||||
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.15.0" />
|
||||
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.11" />
|
||||
<PackageReference Include="AzureExtensions.Swashbuckle" Version="3.2.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="host.json">
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
namespace MultiCdnApi.Swagger
|
||||
{
|
||||
using System;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class PostContentAttribute : Attribute
|
||||
{
|
||||
public PostContentAttribute(string name, string description, string example = "")
|
||||
{
|
||||
this.Name = name;
|
||||
this.Description = description;
|
||||
this.Example = example;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
public string Example { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
namespace MultiCdnApi.Swagger
|
||||
{
|
||||
using System.Linq;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
public class PostContentFilter : IOperationFilter
|
||||
{
|
||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||
{
|
||||
var postContentAttribute = (PostContentAttribute) context.MethodInfo.GetCustomAttributes(true)
|
||||
.SingleOrDefault(attribute => attribute is PostContentAttribute);
|
||||
if (postContentAttribute != null)
|
||||
{
|
||||
operation.RequestBody = new OpenApiRequestBody();
|
||||
operation.RequestBody.Content.Add(postContentAttribute.Name,
|
||||
new OpenApiMediaType {
|
||||
Schema = new OpenApiSchema {
|
||||
Type = "multipart/form-data",
|
||||
Description = postContentAttribute.Description,
|
||||
Example = new OpenApiString(postContentAttribute.Example)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,6 @@ namespace MultiCdnApi
|
|||
using CdnLibrary;
|
||||
using CdnLibrary_Test;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Internal;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
@ -76,12 +75,10 @@ namespace MultiCdnApi
|
|||
[TestMethod]
|
||||
public async Task CreateCachePurgeRequestByHostname_Fail()
|
||||
{
|
||||
var defaultHttpRequest = new DefaultHttpRequest(new DefaultHttpContext())
|
||||
{
|
||||
Body = new MemoryStream(Encoding.UTF8.GetBytes(TestHostname))
|
||||
};
|
||||
var malformedCachePurgeRequest = new DefaultHttpContext().Request;
|
||||
malformedCachePurgeRequest.Body = new MemoryStream(Encoding.UTF8.GetBytes(TestHostname));
|
||||
var result = await cacheFunctions.CreateCachePurgeRequestByHostname(
|
||||
defaultHttpRequest,
|
||||
malformedCachePurgeRequest,
|
||||
null,
|
||||
Mock.Of<ILogger>());
|
||||
Assert.IsTrue(result is JsonResult);
|
||||
|
@ -123,17 +120,15 @@ namespace MultiCdnApi
|
|||
|
||||
private async Task<string> CallPurgeFunctionWithDefaultParameters()
|
||||
{
|
||||
var defaultHttpRequest = new DefaultHttpRequest(new DefaultHttpContext())
|
||||
{
|
||||
Body = new MemoryStream(Encoding.UTF8.GetBytes("{" +
|
||||
$@"""Description"": ""{TestDescription}""," +
|
||||
$@"""TicketId"": ""{TestTicketId}""," +
|
||||
$@"""Hostname"": ""{TestHostname}""," +
|
||||
$@"""Urls"": [""{TestHostname}""]" +
|
||||
"}"))
|
||||
};
|
||||
var cachePurgeRequest = new DefaultHttpContext().Request;
|
||||
cachePurgeRequest.Body = new MemoryStream(Encoding.UTF8.GetBytes("{" +
|
||||
$@"""Description"": ""{TestDescription}""," +
|
||||
$@"""TicketId"": ""{TestTicketId}""," +
|
||||
$@"""Hostname"": ""{TestHostname}""," +
|
||||
$@"""Urls"": [""{TestHostname}""]" +
|
||||
"}"));
|
||||
var result = await cacheFunctions.CreateCachePurgeRequestByHostname(
|
||||
defaultHttpRequest,
|
||||
cachePurgeRequest,
|
||||
testPartnerId,
|
||||
Mock.Of<ILogger>());
|
||||
Assert.AreEqual(typeof(StringResult), result.GetType());
|
||||
|
@ -143,9 +138,9 @@ namespace MultiCdnApi
|
|||
|
||||
private async Task<UserRequestStatusResult> CallPurgeStatus(string userRequestId)
|
||||
{
|
||||
var defaultHttpRequest = new DefaultHttpRequest(new DefaultHttpContext());
|
||||
var emptyRequest = new DefaultHttpContext().Request;
|
||||
var statusResponse = await cacheFunctions.CachePurgeRequestByHostnameStatus(
|
||||
defaultHttpRequest,
|
||||
emptyRequest,
|
||||
testPartnerId,
|
||||
userRequestId,
|
||||
Mock.Of<ILogger>());
|
||||
|
|
|
@ -13,7 +13,6 @@ namespace MultiCdnApi
|
|||
using CdnLibrary;
|
||||
using CdnLibrary_Test;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Internal;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
@ -57,13 +56,9 @@ namespace MultiCdnApi
|
|||
[TestMethod]
|
||||
public void TestCreatePartner_Fail()
|
||||
{
|
||||
var createPartnerResponse = partnerFunctions.CreatePartner(new DefaultHttpRequest(new DefaultHttpContext())
|
||||
{
|
||||
Query = new QueryCollection(new Dictionary<string, StringValues>
|
||||
{
|
||||
["Test"] = "Bad"
|
||||
}
|
||||
)}, null).Result;
|
||||
var malformedCreatePartnerRequest = new DefaultHttpContext().Request;
|
||||
malformedCreatePartnerRequest.Query = new QueryCollection(new Dictionary<string, StringValues> {["Test"] = "Bad"});
|
||||
var createPartnerResponse = partnerFunctions.CreatePartner(malformedCreatePartnerRequest, null).Result;
|
||||
|
||||
Assert.AreEqual(typeof(ExceptionResult), createPartnerResponse.GetType());
|
||||
}
|
||||
|
@ -109,13 +104,10 @@ namespace MultiCdnApi
|
|||
Assert.AreEqual(typeof(StringResult), testPartnerResponse.GetType());
|
||||
var partnerId = ((StringResult) testPartnerResponse).Value.ToString();
|
||||
|
||||
var partnerResult = partnerFunctions.GetPartner(new DefaultHttpRequest(new DefaultHttpContext())
|
||||
{
|
||||
Query = new QueryCollection(new Dictionary<string, StringValues>
|
||||
{
|
||||
["partnerId"] = partnerId
|
||||
})
|
||||
}, null).Result;
|
||||
var getPartnerRequest = new DefaultHttpContext().Request;
|
||||
getPartnerRequest.Query = new QueryCollection(new Dictionary<string, StringValues> {["partnerId"] = partnerId});
|
||||
|
||||
var partnerResult = partnerFunctions.GetPartner(getPartnerRequest, null).Result;
|
||||
|
||||
Assert.AreEqual(typeof(PartnerResult), partnerResult.GetType());
|
||||
|
||||
|
@ -126,10 +118,7 @@ namespace MultiCdnApi
|
|||
[TestMethod]
|
||||
public void TestGetPartner_Fail()
|
||||
{
|
||||
var partnerResult = partnerFunctions.GetPartner(new DefaultHttpRequest(new DefaultHttpContext())
|
||||
{
|
||||
Query = new QueryCollection()
|
||||
}, null).Result;
|
||||
var partnerResult = partnerFunctions.GetPartner(new DefaultHttpContext().Request, null).Result;
|
||||
|
||||
Assert.AreEqual(typeof(StringResult), partnerResult.GetType());
|
||||
}
|
||||
|
@ -140,7 +129,7 @@ namespace MultiCdnApi
|
|||
this.partners.Clear();
|
||||
CreateTestPartner();
|
||||
var partnersResponse =
|
||||
partnerFunctions.ListPartners(new DefaultHttpRequest(new DefaultHttpContext()), null).Result;
|
||||
partnerFunctions.ListPartners(new DefaultHttpContext().Request, null).Result;
|
||||
Assert.AreEqual(typeof(EnumerableResult<PartnerResult>), partnersResponse.GetType());
|
||||
var partnersValue = ((EnumerableResult<PartnerResult>) partnersResponse).Value;
|
||||
|
||||
|
@ -154,16 +143,16 @@ namespace MultiCdnApi
|
|||
|
||||
private IActionResult CreateTestPartner()
|
||||
{
|
||||
var createPartnerResponse = partnerFunctions.CreatePartner(new DefaultHttpRequest(new DefaultHttpContext())
|
||||
{
|
||||
Body = new MemoryStream(Encoding.UTF8.GetBytes("{" +
|
||||
$@"""Tenant"": ""{TenantId}""," +
|
||||
$@"""Name"": ""{Name}""," +
|
||||
$@"""ContactEmail"": ""{DriContact}""," +
|
||||
$@"""NotifyContactEmail"": ""{NotifyContact}""," +
|
||||
$@"""CdnConfiguration"": {{""Hostname"": ""{TestHostname}"", ""CdnWithCredentials"": {{""AFD"":"""", ""Akamai"":""""}}}}" +
|
||||
"}"))
|
||||
}, Mock.Of<ILogger>());
|
||||
var createPartnerRequest = new DefaultHttpContext().Request;
|
||||
createPartnerRequest.Body = new MemoryStream(Encoding.UTF8.GetBytes("{" +
|
||||
$@"""Tenant"": ""{TenantId}""," +
|
||||
$@"""Name"": ""{Name}""," +
|
||||
$@"""ContactEmail"": ""{DriContact}""," +
|
||||
$@"""NotifyContactEmail"": ""{NotifyContact}""," +
|
||||
$@"""CdnConfiguration"": {{""Hostname"": ""{TestHostname}"", ""CdnWithCredentials"": {{""AFD"":"""", ""Akamai"":""""}}}}" +
|
||||
"}"));
|
||||
|
||||
var createPartnerResponse = partnerFunctions.CreatePartner(createPartnerRequest, Mock.Of<ILogger>());
|
||||
return createPartnerResponse.Result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,14 @@ namespace MultiCdnApi
|
|||
using CachePurgeLibrary;
|
||||
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
|
||||
public class FunctionsStartup_Test
|
||||
{
|
||||
private IFunctionsHostBuilder functionsHostBuilder;
|
||||
|
||||
[SetUp]
|
||||
[TestInitialize]
|
||||
public void Setup()
|
||||
{
|
||||
var multiCdnFunctionsStartup = new Startup();
|
||||
|
@ -25,14 +25,14 @@ namespace MultiCdnApi
|
|||
multiCdnFunctionsStartup.Configure(functionsHostBuilder);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestMethod]
|
||||
public void TestSetupPartnerTable()
|
||||
{
|
||||
var partnerTableService = FindServiceByType(functionsHostBuilder, typeof(IRequestTable<Partner>));
|
||||
Assert.IsNotNull(partnerTableService);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestMethod]
|
||||
public void TestSetupUserRequestTable()
|
||||
{
|
||||
var userRequestTable = FindServiceByType(functionsHostBuilder, typeof(IRequestTable<UserRequest>));
|
||||
|
|
|
@ -8,11 +8,6 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
||||
<PackageReference Include="Moq" Version="4.14.1" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
Загрузка…
Ссылка в новой задаче