diff --git a/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md
new file mode 100644
index 00000000..9ed3ea0f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md
@@ -0,0 +1,31 @@
+---
+name: Bug report, feature request or other
+about: Create a report to help us improve
+title: Bug report, feature request or other request
+labels: ''
+assignees: ''
+---
+
+**Describe the issue**
+A clear and concise description of what the issue is about.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your issue.
+
+**Environment (please complete the following information, if applicable):**
+ - OS: [e.g. Windows/Mac/Linux]
+ - Browser [e.g. edge, chrome, firefox, safari]
+ - Version [e.g. 22]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 00000000..06d80aa3
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,18 @@
+---
+name: Pull request
+about: Create a pull request
+title: Pull request
+labels: ''
+assignees: ''
+---
+
+Related to #{issue_number}.
+
+**Changes proposed in this pull request**:
+
+* ...
+* ...
+* ...
+
+**Screenshots**
+If applicable, add screenshots to help explain your pull request.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..ef77b4a9
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,7 @@
+# Contributing #
+
+This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
+
+When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
+
+This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
diff --git a/README.md b/README.md
index 74e187fa..e33538c3 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,8 @@
## Getting Started ##
* [**Enable OpenAPI documents to your Azure Functions HTTP Trigger (Preview)**](docs/enable-open-api-endpoints.md): This document shows how to enable OpenAPI extension on your Azure Functions applications and render Swagger UI, and OpenAPI v2 and v3 documents on-the-fly. It's currently in preview.
- * [**Microsoft.Azure.WebJobs.Extensions.OpenApi**](docs/openapi.md)
+ * [**Microsoft.Azure.Functions.Worker.Extensions.OpenApi**](docs/openapi-out-of-proc.md)
+ * [**Microsoft.Azure.WebJobs.Extensions.OpenApi**](docs/openapi-in-proc.md)
* [**Microsoft.Azure.WebJobs.Extensions.OpenApi.Core**](docs/openapi-core.md)
* [**Azure Functions v1 Support**](docs/azure-functions-v1-support.md): This document shows how to support Azure Functions v1 runtime with this OpenAPI extension.
* [**Integrating OpenAPI-enabled Azure Functions to Azure API Management**](docs/integrate-with-apim.md): This document shows how to integrate the Azure Functions application with [Azure API Management](https://docs.microsoft.com/azure/api-management/api-management-key-concepts?WT.mc_id=dotnet_0000_juyoo), via this OpenAPI extension.
@@ -38,12 +39,10 @@ Here are the other sample apps directly using the NuGet packages (external repos
* [Function App .NET 6 with IoC Container (out-of-proc)](https://github.com/justinyoo/azfunc-openapi-dotnet/tree/main/Net60.FunctionApp.OutOfProc.IoC)
* [Function App .NET 6 with Static (out-of-proc)](https://github.com/justinyoo/azfunc-openapi-dotnet/tree/main/Net60.FunctionApp.OutOfProc.Static)
-> **NOTE**: .NET 6 support is currently very early preview.
-
## Azure Functions V1 Support ##
-This library supports Azure Functions V2 and onwards. If you still want to get your v1 app supported, find the [community contribution](https://github.com/aliencube/AzureFunctions.Extensions).
+This library supports Azure Functions V2 and onwards. If you still want to get your v1 app supported, find the [community contribution](https://github.com/aliencube/AzureFunctions.Extensions) or the [proxy feature](docs/azure-functions-v1-support.md).
## Issues? ##
diff --git a/docs/README.md b/docs/README.md
index da131870..86607ce2 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,13 +1,14 @@
-# AzureFunctions.Extensions #
+# Azure Functions OpenAPI Extension #
-This provides some useful extensions for Azure Functions.
+This extension adds the OpenAPI capability to your Azure Functions app.
## Getting Started  ##
| Package | Status | Version |
| --- | --- | --- |
+| [Microsoft.Azure.Functions.Worker.Extensions.OpenApi](openapi-out-of-proc.md) | [](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/) | [](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/) |
| [Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings](app-settings.md) | [](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings/) | [](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi.Configuration.AppSettings/) |
| [Microsoft.Azure.WebJobs.Extensions.OpenApi.Core](openapi-core.md) | [](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/) | [](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/) |
-| [Microsoft.Azure.WebJobs.Extensions.OpenApi](openapi.md) | [](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi/) | [](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi/) |
-| [Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI](openapi-cli.md) | [](https://github.com/Azure/azure-functions-openapi-extension/releases) | [](https://github.com/Azure/azure-functions-openapi-extension/releases) |
\ No newline at end of file
+| [Microsoft.Azure.WebJobs.Extensions.OpenApi](openapi-in-proc.md) | [](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi/) | [](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.OpenApi/) |
+| [Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI](openapi-cli.md) | [](https://github.com/Azure/azure-functions-openapi-extension/releases) | [](https://github.com/Azure/azure-functions-openapi-extension/releases) |
diff --git a/docs/enable-open-api-endpoints.md b/docs/enable-open-api-endpoints.md
index 56af81c8..d87eae6a 100644
--- a/docs/enable-open-api-endpoints.md
+++ b/docs/enable-open-api-endpoints.md
@@ -1 +1,4 @@
-# DOCUMENT MOVED
👉 [Enable OpenAPI Endpoints on Azure Functions (Preview) – In-Process Model](./enable-open-api-endpoints-in-proc.md) #
+# Enable OpenAPI Endpoints on Azure Functions (Preview) #
+
+* [Enable OpenAPI Endpoints on Azure Functions (Preview) – In-Process Model](./enable-open-api-endpoints-in-proc.md)
+* [Enable OpenAPI Endpoints on Azure Functions (Preview) – Out-of-Process Model](./enable-open-api-endpoints-out-of-proc.md)
diff --git a/docs/openapi.md b/docs/openapi.md
index b1971c72..3e4f5559 100644
--- a/docs/openapi.md
+++ b/docs/openapi.md
@@ -1 +1,4 @@
-# DOCUMENT MOVED
👉 [Microsoft.Azure.WebJobs.Extensions.OpenApi](./openapi-in-proc.md) #
+# Packages for In-Process / Out-of-Process Worker #
+
+* [Microsoft.Azure.WebJobs.Extensions.OpenApi – In-Process Model](./openapi-in-proc.md)
+* [Microsoft.Azure.Functions.Worker.Extensions.OpenApi – Out-of-Process Model](./openapi-out-of-proc.md)
diff --git a/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models/DummyListModel.cs b/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models/DummyListModel.cs
index 58d6c9d5..10d26ad3 100644
--- a/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models/DummyListModel.cs
+++ b/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models/DummyListModel.cs
@@ -1,4 +1,6 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using Microsoft.AspNetCore.Mvc;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models
{
@@ -9,5 +11,7 @@ public class DummyListModel
public HashSet ListValues2 { get; set; }
public ISet ListValues3 { get; set; }
+
+ public ValidationProblemDetails ValidationProblemDetails { get; set; }
}
}
diff --git a/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models/DummyResponseModel.cs b/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models/DummyResponseModel.cs
index a71d8fc0..09627db7 100644
--- a/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models/DummyResponseModel.cs
+++ b/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.Models/DummyResponseModel.cs
@@ -54,5 +54,9 @@ public class DummyResponseModel
public DummySubResponseModel SubResponse2 { get; set; }
public DummyGenericModel DummyGenericDummyModel { get; set; }
+
+ public List Children { get; set; }
+
+ public Dictionary Children2 { get; set; }
}
}
diff --git a/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static/Configurations/OpenApiHttpTriggerAuthorization.cs b/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static/Configurations/OpenApiHttpTriggerAuthorization.cs
new file mode 100644
index 00000000..17f5f00a
--- /dev/null
+++ b/samples/Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static/Configurations/OpenApiHttpTriggerAuthorization.cs
@@ -0,0 +1,58 @@
+// using System.Globalization;
+// using System.Linq;
+// using System.Net;
+// using System.Threading.Tasks;
+
+// using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+// using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
+// using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
+
+// namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.FunctionApp.V3Static.Configurations
+// {
+// public class OpenApiHttpTriggerAuthorization : DefaultOpenApiHttpTriggerAuthorization
+// {
+// public override async Task AuthorizeAsync(IHttpRequestDataObject req)
+// {
+// var result = default(OpenApiAuthorizationResult);
+// var authtoken = (string) req.Headers["Authorization"];
+// if (authtoken.IsNullOrWhiteSpace())
+// {
+// result = new OpenApiAuthorizationResult()
+// {
+// StatusCode = HttpStatusCode.Unauthorized,
+// ContentType = "text/plain",
+// Payload = "Unauthorized",
+// };
+
+// return await Task.FromResult(result).ConfigureAwait(false);
+// }
+
+// if (authtoken.StartsWith("Bearer", ignoreCase: true, CultureInfo.InvariantCulture) == false)
+// {
+// result = new OpenApiAuthorizationResult()
+// {
+// StatusCode = HttpStatusCode.Unauthorized,
+// ContentType = "text/plain",
+// Payload = "Invalid auth format",
+// };
+
+// return await Task.FromResult(result).ConfigureAwait(false);
+// }
+
+// var token = authtoken.Split(' ').Last();
+// if (token != "secret")
+// {
+// result = new OpenApiAuthorizationResult()
+// {
+// StatusCode = HttpStatusCode.Forbidden,
+// ContentType = "text/plain",
+// Payload = "Invalid auth token",
+// };
+
+// return await Task.FromResult(result).ConfigureAwait(false);
+// }
+
+// return await Task.FromResult(result).ConfigureAwait(false);
+// }
+// }
+// }
diff --git a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Document.cs b/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Document.cs
index 6fbb8001..ddf3f3d7 100644
--- a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Document.cs
+++ b/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Document.cs
@@ -14,6 +14,7 @@
using Newtonsoft.Json.Serialization;
using GenericExtensions = Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions.GenericExtensions;
+using HttpRequestDataObjectExtensions = Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions.HttpRequestDataObjectExtensions;
using OpenApiDocumentExtensions = Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions.OpenApiDocumentExtensions;
using StringExtensions = Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions.StringExtensions;
@@ -73,7 +74,7 @@ public IDocument AddServer(IHttpRequestDataObject req, string routePrefix, IOpen
this._req = req;
var prefix = string.IsNullOrWhiteSpace(routePrefix) ? string.Empty : $"/{routePrefix}";
- var baseUrl = $"{this._req.Scheme}://{this._req.Host}{prefix}";
+ var baseUrl = $"{HttpRequestDataObjectExtensions.GetScheme(this._req, options)}://{this._req.Host}{prefix}";
var server = new OpenApiServer { Url = baseUrl };
diff --git a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Extensions/OpenApiHostBuilderExtensions.cs b/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Extensions/OpenApiHostBuilderExtensions.cs
index 0b91e5d6..39a100fa 100644
--- a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Extensions/OpenApiHostBuilderExtensions.cs
+++ b/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Extensions/OpenApiHostBuilderExtensions.cs
@@ -1,4 +1,5 @@
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Functions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
diff --git a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Extensions/OpenApiHttpRequestDataExtensions.cs b/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Extensions/OpenApiHttpRequestDataExtensions.cs
index 47a8a99f..91bea663 100644
--- a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Extensions/OpenApiHttpRequestDataExtensions.cs
+++ b/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Extensions/OpenApiHttpRequestDataExtensions.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
@@ -15,10 +16,44 @@ namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Extensions
public static class OpenApiHttpRequestDataExtensions
{
///
- /// Gets the instance from the .
+ /// Gets the instance from the .
///
/// instance.
- /// Returns instance.
+ /// Returns instance.
+ public static IHeaderDictionary Headers(this HttpRequestData req)
+ {
+ req.ThrowIfNullOrDefault();
+
+ var headers = req.Headers.ToDictionary(p => p.Key, p => new StringValues(p.Value.ToArray()));
+ if (headers.IsNullOrDefault() || headers.Any() == false)
+ {
+ headers = new Dictionary();
+ }
+
+ return new HeaderDictionary(headers);
+ }
+
+ ///
+ /// Gets the object from the header of .
+ ///
+ /// instance.
+ /// Header key.
+ /// Returns object.
+ public static StringValues Header(this HttpRequestData req, string key)
+ {
+ req.ThrowIfNullOrDefault();
+
+ var headers = Headers(req);
+ var value = headers.ContainsKey(key) ? headers[key] : new StringValues(default(string));
+
+ return value;
+ }
+
+ ///
+ /// Gets the instance from the .
+ ///
+ /// instance.
+ /// Returns instance.
public static IQueryCollection Queries(this HttpRequestData req)
{
req.ThrowIfNullOrDefault();
@@ -33,7 +68,7 @@ public static IQueryCollection Queries(this HttpRequestData req)
}
///
- /// Gets the object from the .
+ /// Gets the object from the querystring of .
///
/// instance.
/// Querystring key.
diff --git a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Functions/OpenApiTriggerFunction.cs b/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Functions/OpenApiTriggerFunction.cs
index 8109e5ed..9844a442 100644
--- a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Functions/OpenApiTriggerFunction.cs
+++ b/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/Functions/OpenApiTriggerFunction.cs
@@ -4,6 +4,7 @@
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker.Http;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
using Microsoft.Extensions.Logging;
@@ -37,20 +38,34 @@ public async Task RenderSwaggerDocument(HttpRequestData req, s
log.LogInformation($"swagger.{extension} was requested.");
var fi = new FileInfo(ctx.FunctionDefinition.PathToAssembly);
+ var request = new HttpRequestObject(req);
var result = default(string);
var response = default(HttpResponseData);
try
{
- result = await (await this._context.SetApplicationAssemblyAsync(fi.Directory.FullName, appendBin: false))
- .Document
- .InitialiseDocument()
- .AddMetadata(this._context.OpenApiConfigurationOptions.Info)
- .AddServer(new HttpRequestObject(req), this._context.HttpSettings.RoutePrefix, this._context.OpenApiConfigurationOptions)
- .AddNamingStrategy(this._context.NamingStrategy)
- .AddVisitors(this._context.GetVisitorCollection())
- .Build(this._context.ApplicationAssembly, this._context.OpenApiConfigurationOptions.OpenApiVersion)
- .RenderAsync(this._context.GetOpenApiSpecVersion(this._context.OpenApiConfigurationOptions.OpenApiVersion), this._context.GetOpenApiFormat(extension))
- .ConfigureAwait(false);
+ var auth = await this._context
+ .SetApplicationAssemblyAsync(fi.Directory.FullName, appendBin: false)
+ .AuthorizeAsync(request)
+ .ConfigureAwait(false);
+ if (!auth.IsNullOrDefault())
+ {
+ response = req.CreateResponse(auth.StatusCode);
+ response.Headers.Add("Content-Type", auth.ContentType);
+ await response.WriteStringAsync(auth.Payload).ConfigureAwait(false);
+
+ return response;
+ }
+
+ result = await this._context
+ .Document
+ .InitialiseDocument()
+ .AddMetadata(this._context.OpenApiConfigurationOptions.Info)
+ .AddServer(request, this._context.HttpSettings.RoutePrefix, this._context.OpenApiConfigurationOptions)
+ .AddNamingStrategy(this._context.NamingStrategy)
+ .AddVisitors(this._context.GetVisitorCollection())
+ .Build(this._context.ApplicationAssembly, this._context.OpenApiConfigurationOptions.OpenApiVersion)
+ .RenderAsync(this._context.GetOpenApiSpecVersion(this._context.OpenApiConfigurationOptions.OpenApiVersion), this._context.GetOpenApiFormat(extension))
+ .ConfigureAwait(false);
response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", this._context.GetOpenApiFormat(extension).GetContentType());
@@ -82,20 +97,34 @@ public async Task RenderOpenApiDocument(HttpRequestData req, s
log.LogInformation($"{version}.{extension} was requested.");
var fi = new FileInfo(ctx.FunctionDefinition.PathToAssembly);
+ var request = new HttpRequestObject(req);
var result = default(string);
var response = default(HttpResponseData);
try
{
- result = await (await this._context.SetApplicationAssemblyAsync(fi.Directory.FullName, appendBin: false))
- .Document
- .InitialiseDocument()
- .AddMetadata(this._context.OpenApiConfigurationOptions.Info)
- .AddServer(new HttpRequestObject(req), this._context.HttpSettings.RoutePrefix, this._context.OpenApiConfigurationOptions)
- .AddNamingStrategy(this._context.NamingStrategy)
- .AddVisitors(this._context.GetVisitorCollection())
- .Build(this._context.ApplicationAssembly, this._context.GetOpenApiVersionType(version))
- .RenderAsync(this._context.GetOpenApiSpecVersion(version), this._context.GetOpenApiFormat(extension))
- .ConfigureAwait(false);
+ var auth = await this._context
+ .SetApplicationAssemblyAsync(fi.Directory.FullName, appendBin: false)
+ .AuthorizeAsync(request)
+ .ConfigureAwait(false);
+ if (!auth.IsNullOrDefault())
+ {
+ response = req.CreateResponse(auth.StatusCode);
+ response.Headers.Add("Content-Type", auth.ContentType);
+ await response.WriteStringAsync(auth.Payload).ConfigureAwait(false);
+
+ return response;
+ }
+
+ result = await this._context
+ .Document
+ .InitialiseDocument()
+ .AddMetadata(this._context.OpenApiConfigurationOptions.Info)
+ .AddServer(request, this._context.HttpSettings.RoutePrefix, this._context.OpenApiConfigurationOptions)
+ .AddNamingStrategy(this._context.NamingStrategy)
+ .AddVisitors(this._context.GetVisitorCollection())
+ .Build(this._context.ApplicationAssembly, this._context.GetOpenApiVersionType(version))
+ .RenderAsync(this._context.GetOpenApiSpecVersion(version), this._context.GetOpenApiFormat(extension))
+ .ConfigureAwait(false);
response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", this._context.GetOpenApiFormat(extension).GetContentType());
@@ -126,17 +155,31 @@ public async Task RenderSwaggerUI(HttpRequestData req, Functio
log.LogInformation("SwaggerUI page was requested.");
var fi = new FileInfo(ctx.FunctionDefinition.PathToAssembly);
+ var request = new HttpRequestObject(req);
var result = default(string);
var response = default(HttpResponseData);
try
{
- result = await (await this._context.SetApplicationAssemblyAsync(fi.Directory.FullName, appendBin: false))
- .SwaggerUI
- .AddMetadata(this._context.OpenApiConfigurationOptions.Info)
- .AddServer(new HttpRequestObject(req), this._context.HttpSettings.RoutePrefix, this._context.OpenApiConfigurationOptions)
- .BuildAsync(this._context.PackageAssembly, this._context.OpenApiCustomUIOptions)
- .RenderAsync("swagger.json", this._context.GetDocumentAuthLevel(), this._context.GetSwaggerAuthKey())
- .ConfigureAwait(false);
+ var auth = await this._context
+ .SetApplicationAssemblyAsync(fi.Directory.FullName, appendBin: false)
+ .AuthorizeAsync(request)
+ .ConfigureAwait(false);
+ if (!auth.IsNullOrDefault())
+ {
+ response = req.CreateResponse(auth.StatusCode);
+ response.Headers.Add("Content-Type", auth.ContentType);
+ await response.WriteStringAsync(auth.Payload).ConfigureAwait(false);
+
+ return response;
+ }
+
+ result = await this._context
+ .SwaggerUI
+ .AddMetadata(this._context.OpenApiConfigurationOptions.Info)
+ .AddServer(request, this._context.HttpSettings.RoutePrefix, this._context.OpenApiConfigurationOptions)
+ .BuildAsync(this._context.PackageAssembly, this._context.OpenApiCustomUIOptions)
+ .RenderAsync("swagger.json", this._context.GetDocumentAuthLevel(), this._context.GetSwaggerAuthKey())
+ .ConfigureAwait(false);
response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", ContentTypeHtml);
@@ -167,16 +210,21 @@ public async Task RenderOAuth2Redirect(HttpRequestData req, Fu
log.LogInformation("The oauth2-redirect.html page was requested.");
var fi = new FileInfo(ctx.FunctionDefinition.PathToAssembly);
+ var request = new HttpRequestObject(req);
var result = default(string);
var response = default(HttpResponseData);
try
{
- result = await (await this._context.SetApplicationAssemblyAsync(fi.Directory.FullName, appendBin: false))
- .SwaggerUI
- .AddServer(new HttpRequestObject(req), this._context.HttpSettings.RoutePrefix, this._context.OpenApiConfigurationOptions)
- .BuildOAuth2RedirectAsync(this._context.PackageAssembly)
- .RenderOAuth2RedirectAsync("oauth2-redirect.html", this._context.GetDocumentAuthLevel(), this._context.GetSwaggerAuthKey())
- .ConfigureAwait(false);
+ await this._context
+ .SetApplicationAssemblyAsync(fi.Directory.FullName, appendBin: false)
+ .ConfigureAwait(false);
+
+ result = await this._context
+ .SwaggerUI
+ .AddServer(request, this._context.HttpSettings.RoutePrefix, this._context.OpenApiConfigurationOptions)
+ .BuildOAuth2RedirectAsync(this._context.PackageAssembly)
+ .RenderOAuth2RedirectAsync("oauth2-redirect.html", this._context.GetDocumentAuthLevel(), this._context.GetSwaggerAuthKey())
+ .ConfigureAwait(false);
response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", ContentTypeHtml);
diff --git a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/HttpRequestObject.cs b/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/HttpRequestObject.cs
index 1a1b8f48..2909305f 100644
--- a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/HttpRequestObject.cs
+++ b/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/HttpRequestObject.cs
@@ -27,6 +27,7 @@ public HttpRequestObject(HttpRequestData req)
? new HostString(req.Url.Authority)
: new HostString(req.Url.Host, req.Url.Port);
+ this.Headers = req.Headers();
this.Query = req.Queries();
this.Body = req.Body;
}
@@ -37,6 +38,9 @@ public HttpRequestObject(HttpRequestData req)
///
public virtual HostString Host { get; }
+ ///
+ public virtual IHeaderDictionary Headers { get; }
+
///
public virtual IQueryCollection Query { get;}
diff --git a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/OpenApiHttpTriggerContext.cs b/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/OpenApiHttpTriggerContext.cs
index f1b38fb9..52137cea 100644
--- a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/OpenApiHttpTriggerContext.cs
+++ b/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/OpenApiHttpTriggerContext.cs
@@ -140,6 +140,24 @@ public virtual async Task SetApplicationAssemblyAsyn
return this;
}
+ ///
+ public virtual async Task AuthorizeAsync(IHttpRequestDataObject req)
+ {
+ var result = default(OpenApiAuthorizationResult);
+ var type = this.ApplicationAssembly
+ .GetLoadableTypes()
+ .SingleOrDefault(p => p.HasInterface());
+ if (type.IsNullOrDefault())
+ {
+ return result;
+ }
+
+ var auth = Activator.CreateInstance(type) as IOpenApiHttpTriggerAuthorization;
+ result = await auth.AuthorizeAsync(req).ConfigureAwait(false);
+
+ return result;
+ }
+
///
public virtual VisitorCollection GetVisitorCollection()
{
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.csproj b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.csproj
index e1b364eb..102edbc2 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.csproj
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.csproj
@@ -4,7 +4,7 @@
Exe
- netcoreapp2.1;netcoreapp3.1
+ netcoreapp3.1
azfuncopenapi
Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IHttpRequestDataObject.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IHttpRequestDataObject.cs
index e1da789c..3484020e 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IHttpRequestDataObject.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IHttpRequestDataObject.cs
@@ -19,10 +19,15 @@ public interface IHttpRequestDataObject
///
HostString Host { get; }
+ ///
+ /// Gets the header collection.
+ ///
+ IHeaderDictionary Headers { get; }
+
///
/// Gets the query collection.
///
- IQueryCollection Query { get;}
+ IQueryCollection Query { get; }
///
/// Gets the request payload stream.
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IOpenApiConfigurationOptions.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IOpenApiConfigurationOptions.cs
index a30df97a..df8e2e3b 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IOpenApiConfigurationOptions.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IOpenApiConfigurationOptions.cs
@@ -29,5 +29,15 @@ public interface IOpenApiConfigurationOptions
/// Gets or sets the value indicating whether to include the requesting hostname or not.
///
bool IncludeRequestingHostName { get; set; }
+
+ ///
+ /// Gets or sets the value indicating whether to force the HTTP protocol or not.
+ ///
+ bool ForceHttp { get; set; }
+
+ ///
+ /// Gets or sets the value indicating whether to force the HTTPS protocol or not.
+ ///
+ bool ForceHttps { get; set; }
}
}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IOpenApiHttpTriggerAuthorization.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IOpenApiHttpTriggerAuthorization.cs
new file mode 100644
index 00000000..5336fd1f
--- /dev/null
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IOpenApiHttpTriggerAuthorization.cs
@@ -0,0 +1,19 @@
+using System.Threading.Tasks;
+
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions
+{
+ ///
+ /// This provides interfaces to HTTP trigger authorisation for OpenAPI endpoints.
+ ///
+ public interface IOpenApiHttpTriggerAuthorization
+ {
+ ///
+ /// Authorizes the endpoint.
+ ///
+ /// instance.
+ /// Returns instance.
+ Task AuthorizeAsync(IHttpRequestDataObject req);
+ }
+}
diff --git a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/IOpenApiHttpTriggerContext.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IOpenApiHttpTriggerContext.cs
similarity index 90%
rename from src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/IOpenApiHttpTriggerContext.cs
rename to src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IOpenApiHttpTriggerContext.cs
index c52ca7fd..c299a4bc 100644
--- a/src/Microsoft.Azure.Functions.Worker.Extensions.OpenApi/IOpenApiHttpTriggerContext.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Abstractions/IOpenApiHttpTriggerContext.cs
@@ -2,7 +2,6 @@
using System.Reflection;
using System.Threading.Tasks;
-using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors;
@@ -10,10 +9,10 @@
using Newtonsoft.Json.Serialization;
-namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions
{
///
- /// This provides interfaces to .
+ /// This provides interfaces to OpenApiHttpTriggerContext
///
public interface IOpenApiHttpTriggerContext
{
@@ -74,8 +73,16 @@ public interface IOpenApiHttpTriggerContext
///
/// Function app directory.
/// Value indicating whether to append the "bin" directory or not.
+ /// Returns the instance.
Task SetApplicationAssemblyAsync(string functionAppDirectory, bool appendBin = true);
+ ///
+ /// Authorizes the endpoint.
+ ///
+ /// instance.
+ /// Returns instance.
+ Task AuthorizeAsync(IHttpRequestDataObject req);
+
///
/// Gets the instance.
///
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Attributes/OpenApiParameterAttribute.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Attributes/OpenApiParameterAttribute.cs
index 004d811e..3deb0019 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Attributes/OpenApiParameterAttribute.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Attributes/OpenApiParameterAttribute.cs
@@ -1,7 +1,7 @@
using System;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
-
using Microsoft.OpenApi.Models;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes
@@ -71,5 +71,10 @@ public OpenApiParameterAttribute(string name)
/// Gets or sets the value indicating whether the parameter is deprecated or not.
///
public virtual bool Deprecated { get; set; }
+
+ ///
+ /// Gets or sets the type of the example. It SHOULD be inheriting the class.
+ ///
+ public virtual Type Example { get; set; }
}
}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/DefaultOpenApiConfigurationOptions.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/DefaultOpenApiConfigurationOptions.cs
index a6b5f69c..adb886e1 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/DefaultOpenApiConfigurationOptions.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/DefaultOpenApiConfigurationOptions.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Reflection;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
@@ -20,6 +19,8 @@ public class DefaultOpenApiConfigurationOptions : IOpenApiConfigurationOptions
private const string OpenApiHostNamesKey = "OpenApi__HostNames";
private const string OpenApiVersionKey = "OpenApi__Version";
private const string FunctionsRuntimeEnvironmentKey = "AZURE_FUNCTIONS_ENVIRONMENT";
+ private const string ForceHttpKey = "OpenApi__ForceHttp";
+ private const string ForceHttpsKey = "OpenApi__ForceHttps";
///
public virtual OpenApiInfo Info { get; set; } = new OpenApiInfo()
@@ -37,6 +38,12 @@ public class DefaultOpenApiConfigurationOptions : IOpenApiConfigurationOptions
///
public virtual bool IncludeRequestingHostName { get; set; } = IsFunctionsRuntimeEnvironmentDevelopment();
+ ///
+ public bool ForceHttp { get; set; } = IsHttpForced();
+
+ ///
+ public bool ForceHttps { get; set; } = IsHttpsForced();
+
///
/// Gets the OpenAPI document version.
///
@@ -105,6 +112,28 @@ protected static bool IsFunctionsRuntimeEnvironmentDevelopment()
return development;
}
+ ///
+ /// Checks whether HTTP is forced or not.
+ ///
+ /// Returns True, if HTTP is forced; otherwise returns False.
+ protected static bool IsHttpForced()
+ {
+ var development = bool.TryParse(Environment.GetEnvironmentVariable(ForceHttpKey), out var result) ? result : false;;
+
+ return development;
+ }
+
+ ///
+ /// Checks whether HTTPS is forced or not.
+ ///
+ /// Returns True, if HTTPS is forced; otherwise returns False.
+ protected static bool IsHttpsForced()
+ {
+ var development = bool.TryParse(Environment.GetEnvironmentVariable(ForceHttpsKey), out var result) ? result : false;;
+
+ return development;
+ }
+
private static OpenApiVersionType DefaultOpenApiVersion()
{
return OpenApiVersionType.V2;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/DefaultOpenApiHttpTriggerAuthorization.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/DefaultOpenApiHttpTriggerAuthorization.cs
new file mode 100644
index 00000000..b999a261
--- /dev/null
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/DefaultOpenApiHttpTriggerAuthorization.cs
@@ -0,0 +1,20 @@
+using System.Threading.Tasks;
+
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations
+{
+ ///
+ /// This represents the entity for the default authorisation options for the HTTP trigger endpoints used for Swagger UI and OpenAPI document.
+ ///
+ public class DefaultOpenApiHttpTriggerAuthorization : IOpenApiHttpTriggerAuthorization
+ {
+ ///
+ public virtual async Task AuthorizeAsync(IHttpRequestDataObject req)
+ {
+ var result = default(OpenApiAuthorizationResult);
+
+ return await Task.FromResult(result).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/OpenApiAuthorizationResult.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/OpenApiAuthorizationResult.cs
new file mode 100644
index 00000000..6658e64e
--- /dev/null
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/OpenApiAuthorizationResult.cs
@@ -0,0 +1,25 @@
+using System.Net;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations
+{
+ ///
+ /// This represents the entity for the authorisation result.
+ ///
+ public class OpenApiAuthorizationResult
+ {
+ ///
+ /// Gets or sets the HTTP status code.
+ ///
+ public virtual HttpStatusCode StatusCode { get; set; }
+
+ ///
+ /// Gets or sets the content type.
+ ///
+ public virtual string ContentType { get; set; }
+
+ ///
+ /// Gets or sets the payload.
+ ///
+ public virtual string Payload { get; set; }
+ }
+}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/OpenApiSettings.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/OpenApiSettings.cs
index ec5d87af..6a8f2443 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/OpenApiSettings.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Configurations/OpenApiSettings.cs
@@ -28,5 +28,11 @@ public sealed class OpenApiSettings : IOpenApiConfigurationOptions
///
public bool IncludeRequestingHostName { get; set; }
+
+ ///
+ public bool ForceHttp { get; set; }
+
+ ///
+ public bool ForceHttps { get; set; }
}
}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/HttpRequestDataObjectExtensions.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/HttpRequestDataObjectExtensions.cs
new file mode 100644
index 00000000..ba3723f5
--- /dev/null
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/HttpRequestDataObjectExtensions.cs
@@ -0,0 +1,41 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions
+{
+ ///
+ /// This represents the extension entity for .
+ ///
+ public static class HttpRequestDataObjectExtensions
+ {
+ private const string HTTP = "http";
+ private const string HTTPS = "https";
+
+ ///
+ /// Gets the scheme whether to return either HTTP or HTTPS depending on the condition.
+ /// ///
+ /// instance.
+ /// instance.
+ /// Return either "HTTP" or "HTTPS", depending on the condition.
+ public static string GetScheme(this IHttpRequestDataObject req, IOpenApiConfigurationOptions options)
+ {
+ req.ThrowIfNullOrDefault();
+
+ if (options.IsNullOrDefault())
+ {
+ return req.Scheme;
+ }
+
+ if (options.ForceHttps)
+ {
+ return HTTPS;
+ }
+
+ if (options.ForceHttp)
+ {
+ return HTTP;
+ }
+
+ return req.Scheme;
+ }
+ }
+}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/OpenApiHttpTriggerContextExtensions.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/OpenApiHttpTriggerContextExtensions.cs
new file mode 100644
index 00000000..ced66ea7
--- /dev/null
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/OpenApiHttpTriggerContextExtensions.cs
@@ -0,0 +1,28 @@
+using System.Threading.Tasks;
+
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions
+{
+ ///
+ /// This represents the extension entity for .
+ ///
+ public static class OpenApiHttpTriggerContextExtensions
+ {
+ ///
+ /// Authorizes the endpoint.
+ ///
+ /// instance.
+ /// instance.
+ /// Returns instance.
+ public static async Task AuthorizeAsync(this Task context, IHttpRequestDataObject req)
+ {
+ req.ThrowIfNullOrDefault();
+
+ var instance = await context.ThrowIfNullOrDefault().ConfigureAwait(false);
+
+ return await instance.AuthorizeAsync(req).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/OpenApiParameterAttributeExtensions.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/OpenApiParameterAttributeExtensions.cs
index 3a57fbdf..1e07499e 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/OpenApiParameterAttributeExtensions.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/OpenApiParameterAttributeExtensions.cs
@@ -1,7 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors;
-
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
@@ -20,8 +23,9 @@ public static class OpenApiParameterAttributeExtensions
/// instance.
/// instance.
/// instance.
+ /// value.
/// instance.
- public static OpenApiParameter ToOpenApiParameter(this OpenApiParameterAttribute attribute, NamingStrategy namingStrategy = null, VisitorCollection collection = null)
+ public static OpenApiParameter ToOpenApiParameter(this OpenApiParameterAttribute attribute, NamingStrategy namingStrategy = null, VisitorCollection collection = null, OpenApiVersionType version = OpenApiVersionType.V2)
{
attribute.ThrowIfNullOrDefault();
@@ -84,6 +88,20 @@ public static OpenApiParameter ToOpenApiParameter(this OpenApiParameterAttribute
parameter.Extensions.Add("x-ms-visibility", visibility);
}
+ if (attribute.Example.IsNullOrDefault())
+ {
+ return parameter;
+ }
+
+ var example = (dynamic)Activator.CreateInstance(attribute.Example);
+ var examples = (IDictionary)example.Build(namingStrategy).Examples;
+
+ parameter.Examples = examples;
+ if (version == OpenApiVersionType.V2)
+ {
+ parameter.Example = examples.First().Value.Value;
+ }
+
return parameter;
}
}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs
index 55ad50d0..58aaa3fd 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/TypeExtensions.cs
@@ -35,26 +35,11 @@ public static bool IsSimpleType(this Type type)
case TypeCode.Boolean:
case TypeCode.DateTime:
case TypeCode.String:
+ case TypeCode.Object when type == typeof(Guid):
+ case TypeCode.Object when type == typeof(DateTime):
+ case TypeCode.Object when type == typeof(DateTimeOffset):
return true;
- case TypeCode.Object:
- if (type == typeof(Guid))
- {
- return true;
- }
- else if (type == typeof(DateTime))
- {
- return true;
- }
- else if (type == typeof(DateTimeOffset))
- {
- return true;
- }
- else
- {
- return false;
- }
-
case TypeCode.Empty:
case TypeCode.DBNull:
case TypeCode.Char:
@@ -68,37 +53,67 @@ public static bool IsSimpleType(this Type type)
}
}
+ private static HashSet jObjects = new HashSet
+ {
+ typeof(JObject),
+ typeof(JToken),
+ typeof(JArray),
+ };
+
+ ///
+ /// Checks whether the given type is Json.NET related , or not.
+ ///
+ /// instance.
+ /// Returns True, if the type is identified as either or ; otherwise returns False.
+ public static bool IsJObjectType(this Type type)
+ {
+ if (type.IsNullOrDefault())
+ {
+ return false;
+ }
+
+ if (jObjects.Any(p => p == type))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private static HashSet nonReferentials = new HashSet
+ {
+ typeof(Guid),
+ typeof(DateTime),
+ typeof(DateTimeOffset),
+ typeof(object),
+ };
///
/// Checks whether the type can be referenced or not.
///
/// Type to check.
/// Returns True, if the type can be referenced; otherwise returns False.
+
public static bool IsReferentialType(this Type type)
{
var @enum = Type.GetTypeCode(type);
var isReferential = @enum == TypeCode.Object;
- if (type == typeof(Guid))
- {
- isReferential = false;
- }
- if (type == typeof(DateTime))
- {
- isReferential = false;
- }
- if (type == typeof(DateTimeOffset))
+ if (nonReferentials.Contains(type))
{
isReferential = false;
}
+
if (type.IsOpenApiNullable())
{
isReferential = false;
}
+
if (type.IsUnflaggedEnumType())
{
isReferential = false;
}
+
if (type.IsJObjectType())
{
isReferential = false;
@@ -107,35 +122,10 @@ public static bool IsReferentialType(this Type type)
return isReferential;
}
- ///
- /// Checks whether the given type is Json.NET related , or not.
- ///
- /// instance.
- /// Returns True, if the type is identified as either or ; otherwise returns False.
- public static bool IsJObjectType(this Type type)
- {
- if (type.IsNullOrDefault())
- {
- return false;
- }
-
- if (type == typeof(JObject))
- {
- return true;
- }
-
- if (type == typeof(JToken))
- {
- return true;
- }
-
- return false;
- }
-
///
/// Checks whether the given type is enum without flags or not.
///
- /// instance.
+ /// /// instance.
/// Returns True, if the type is identified as enum without flags; otherwise returns False.
public static bool IsEnumType(this Type type)
{
@@ -374,10 +364,14 @@ public static string GetOpenApiReferenceId(this Type type, bool isDictionary, bo
namingStrategy = new DefaultNamingStrategy();
}
- if (isDictionary || isList)
+ if(isDictionary)
{
- var name = type.Name.Split('`').First() + "_" + type.GetOpenApiSubTypeName(namingStrategy);
-
+ var name = type.Name.EndsWith("[]") ? "Dictionary_" + type.GetOpenApiSubTypeName(namingStrategy) : type.Name.Split('`').First() + "_" + type.GetOpenApiSubTypeName(namingStrategy);
+ return namingStrategy.GetPropertyName(name, hasSpecifiedName: false);
+ }
+ if(isList)
+ {
+ var name = type.Name.EndsWith("[]") ? "List_" + type.GetOpenApiSubTypeName(namingStrategy): type.Name.Split('`').First() + "_" + type.GetOpenApiSubTypeName(namingStrategy);;
return namingStrategy.GetPropertyName(name, hasSpecifiedName: false);
}
@@ -657,82 +651,31 @@ public static bool HasInterface(this Type type, string interfaceName)
private static bool IsArrayType(this Type type)
{
- if (type.BaseType == typeof(Array))
- {
- return true;
- }
-
- if (type.IsGenericTypeOf(typeof(List<>)))
- {
- return true;
- }
-
- if (type.IsGenericTypeOf(typeof(IList<>)))
- {
- return true;
- }
-
- if (type.IsGenericTypeOf(typeof(ICollection<>)))
- {
- return true;
- }
-
- if (type.IsGenericTypeOf(typeof(IEnumerable<>)))
- {
- return true;
- }
-
- if (type.IsGenericTypeOf(typeof(IReadOnlyList<>)))
- {
- return true;
- }
-
- if (type.IsGenericTypeOf(typeof(IReadOnlyCollection<>)))
- {
- return true;
- }
-
- if (type.IsGenericTypeOf(typeof(HashSet<>)))
- {
- return true;
- }
-
- if (type.IsGenericTypeOf(typeof(ISet<>)))
- {
- return true;
- }
-
- return false;
+ var isArrayType = type.Name.Equals("String", StringComparison.InvariantCultureIgnoreCase) == false &&
+ type.GetInterfaces()
+ .Where(p => p.IsInterface)
+ .Where(p => p.Name.Equals("IEnumerable", StringComparison.InvariantCultureIgnoreCase) == true)
+ .Any() &&
+ type.IsJObjectType() == false &&
+ type.IsDictionaryType() == false;
+
+ return isArrayType;
}
- private static bool IsDictionaryType(this Type type)
+ private static HashSet dictionaries = new HashSet
{
- if (!type.IsGenericType)
- {
- return false;
- }
-
- if (type.Name.Equals("Dictionary`2", StringComparison.CurrentCultureIgnoreCase))
- {
- return true;
- }
-
- if (type.Name.Equals("IDictionary`2", StringComparison.CurrentCultureIgnoreCase))
- {
- return true;
- }
+ "Dictionary`2",
+ "IDictionary`2",
+ "IReadOnlyDictionary`2",
+ "KeyValuePair`2",
+ };
- if (type.Name.Equals("IReadOnlyDictionary`2", StringComparison.CurrentCultureIgnoreCase))
- {
- return true;
- }
-
- if (type.Name.Equals("KeyValuePair`2", StringComparison.CurrentCultureIgnoreCase))
- {
- return true;
- }
+ private static bool IsDictionaryType(this Type type)
+ {
+ var isDictionaryType = type.IsGenericType &&
+ dictionaries.Any(p => type.Name.Equals(p, StringComparison.InvariantCultureIgnoreCase) == true);
- return false;
+ return isDictionaryType;
}
private static bool IsNullableType(this Type type, out Type underlyingType)
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/OpenApiExampleFactory.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/OpenApiExampleFactory.cs
new file mode 100644
index 00000000..19f9197f
--- /dev/null
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/OpenApiExampleFactory.cs
@@ -0,0 +1,80 @@
+using System;
+
+using Microsoft.OpenApi.Any;
+
+using Newtonsoft.Json;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core
+{
+ ///
+ /// This represents the factory entity to create a openApiExample instance based on the OpenAPI document format.
+ ///
+ public static class OpenApiExampleFactory
+ {
+ ///
+ /// Creates a new instance of based on the OpenAPI document format.
+ ///
+ /// instance.
+ /// settings.
+ /// instance.
+ public static IOpenApiAny CreateInstance(T instance, JsonSerializerSettings settings)
+ {
+ Type type = typeof(T);
+ var @enum = Type.GetTypeCode(type);
+ var openApiExampleValue = default(IOpenApiAny);
+
+ switch (@enum)
+ {
+ case TypeCode.Int16:
+ openApiExampleValue = new OpenApiInteger(Convert.ToInt16(instance));
+ break;
+ case TypeCode.Int32:
+ openApiExampleValue = new OpenApiInteger(Convert.ToInt32(instance));
+ break;
+ case TypeCode.Int64:
+ openApiExampleValue = new OpenApiLong(Convert.ToInt64(instance));
+ break;
+ case TypeCode.UInt16:
+ openApiExampleValue = new OpenApiDouble(Convert.ToUInt16(instance));
+ break;
+ case TypeCode.UInt32:
+ openApiExampleValue = new OpenApiDouble(Convert.ToUInt32(instance));
+ break;
+ case TypeCode.UInt64:
+ openApiExampleValue = new OpenApiDouble(Convert.ToUInt64(instance));
+ break;
+ case TypeCode.Single:
+ openApiExampleValue = new OpenApiFloat(Convert.ToSingle(instance));
+ break;
+ case TypeCode.Double:
+ openApiExampleValue = new OpenApiDouble(Convert.ToDouble(instance));
+ break;
+ case TypeCode.Boolean:
+ openApiExampleValue = new OpenApiBoolean(Convert.ToBoolean(instance));
+ break;
+ case TypeCode.String:
+ openApiExampleValue = new OpenApiString(Convert.ToString(instance));
+ break;
+ case TypeCode.DateTime:
+ openApiExampleValue = new OpenApiDateTime(Convert.ToDateTime(instance));
+ break;
+ case TypeCode.Object when type == typeof(DateTimeOffset):
+ openApiExampleValue = new OpenApiDateTime((DateTimeOffset)(Convert.ChangeType(instance, type)));
+ break;
+ case TypeCode.Object when type == typeof(Guid):
+ openApiExampleValue = new OpenApiString(Convert.ToString(instance));
+ break;
+ case TypeCode.Object when type == typeof(byte[]):
+ openApiExampleValue = new OpenApiString(Convert.ToBase64String((byte[])Convert.ChangeType(instance, type)));
+ break;
+ case TypeCode.Object:
+ openApiExampleValue = new OpenApiString(JsonConvert.SerializeObject(instance, settings));
+ break;
+ default:
+ throw new InvalidOperationException("Invalid OpenAPI data Format");
+ }
+
+ return openApiExampleValue;
+ }
+ }
+}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Resolvers/OpenApiExampleResolver.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Resolvers/OpenApiExampleResolver.cs
index fee9d0a2..04586f6f 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Resolvers/OpenApiExampleResolver.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Resolvers/OpenApiExampleResolver.cs
@@ -1,7 +1,7 @@
+using System;
using System.Collections.Generic;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
@@ -56,16 +56,19 @@ public static KeyValuePair Resolve(string name, strin
public static KeyValuePair Resolve(string name, string summary, string description, T instance, NamingStrategy namingStrategy = null)
{
name.ThrowIfNullOrWhiteSpace();
- instance.ThrowIfNullOrDefault();
-
+ if (instance == null)
+ {
+ throw new ArgumentNullException(nameof(instance));
+ }
var resolver = new DefaultContractResolver() { NamingStrategy = namingStrategy ?? new DefaultNamingStrategy() };
settings.ContractResolver = resolver;
+ var openApiExampleValue = OpenApiExampleFactory.CreateInstance(instance,settings);
var example = new OpenApiExample()
{
Summary = summary,
Description = description,
- Value = new OpenApiString(JsonConvert.SerializeObject(instance, settings)),
+ Value = openApiExampleValue,
};
var kvp = new KeyValuePair(name, example);
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/SwaggerUI.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/SwaggerUI.cs
index f675111d..c56666ee 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/SwaggerUI.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/SwaggerUI.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
@@ -59,12 +58,16 @@ public ISwaggerUI AddServer(IHttpRequestDataObject req, string routePrefix, IOpe
this._req = req;
var prefix = string.IsNullOrWhiteSpace(routePrefix) ? string.Empty : $"/{routePrefix}";
- var baseUrl = $"{this._req.Scheme}://{this._req.Host}{prefix}";
+ var baseUrl = $"{this._req.GetScheme(options)}://{this._req.Host}{prefix}";
+ var absolutePath = default(string);
if (options.IsNullOrDefault())
{
this._baseUrl = baseUrl;
+ absolutePath = new Uri(this._baseUrl).AbsolutePath.Trim('/');
+ this._swaggerUiApiPrefix = absolutePath;
+
return this;
}
@@ -85,7 +88,9 @@ public ISwaggerUI AddServer(IHttpRequestDataObject req, string routePrefix, IOpe
}
this._baseUrl = servers.First().Url;
- this._swaggerUiApiPrefix = prefix;
+
+ absolutePath = new Uri(this._baseUrl).AbsolutePath.Trim('/');
+ this._swaggerUiApiPrefix = absolutePath;
return this;
}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/BaseObjectTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/BaseObjectTypeVisitor.cs
new file mode 100644
index 00000000..e8dadd22
--- /dev/null
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/BaseObjectTypeVisitor.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.OpenApi.Models;
+
+using Newtonsoft.Json.Serialization;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors
+{
+ ///
+ /// This represents the type visitor for .
+ ///
+ public class BaseObjectTypeVisitor : TypeVisitor
+ {
+ ///
+ public BaseObjectTypeVisitor(VisitorCollection visitorCollection)
+ : base(visitorCollection)
+ {
+ }
+
+ ///
+ public override bool IsVisitable(Type type)
+ {
+ var isVisitable = this.IsVisitable(type, TypeCode.Object) && type == typeof(object);
+
+ return isVisitable;
+ }
+
+ ///
+ public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes)
+ {
+ var title = type.Value.IsGenericType
+ ? namingStrategy.GetPropertyName(type.Value.Name.Split('`').First(), hasSpecifiedName: false) + "_" +
+ string.Join("_",
+ type.Value.GenericTypeArguments.Select(a => namingStrategy.GetPropertyName(a.Name, false)))
+ : namingStrategy.GetPropertyName(type.Value.Name, hasSpecifiedName: false);
+ this.Visit(acceptor, name: type.Key, title: title, dataType: "object", dataFormat: null, attributes: attributes);
+ }
+
+ ///
+ public override bool IsPayloadVisitable(Type type)
+ {
+ var isVisitable = this.IsVisitable(type);
+
+ return isVisitable;
+ }
+
+ ///
+ public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrategy)
+ {
+ return this.PayloadVisit(dataType: "object", dataFormat: null);
+ }
+ }
+}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/BooleanTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/BooleanTypeVisitor.cs
index 58382e95..a1e966e1 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/BooleanTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/BooleanTypeVisitor.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DateTimeObjectTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DateTimeObjectTypeVisitor.cs
index 308d6732..6078df0e 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DateTimeObjectTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DateTimeObjectTypeVisitor.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DateTimeOffsetObjectTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DateTimeOffsetObjectTypeVisitor.cs
index cab85a4d..88653c52 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DateTimeOffsetObjectTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DateTimeOffsetObjectTypeVisitor.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DateTimeTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DateTimeTypeVisitor.cs
index 5bfe01d0..288aab5f 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DateTimeTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DateTimeTypeVisitor.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DecimalTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DecimalTypeVisitor.cs
index 9aa32b50..8394edf2 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DecimalTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DecimalTypeVisitor.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DictionaryObjectTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DictionaryObjectTypeVisitor.cs
index fa6cd54a..d5d46746 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DictionaryObjectTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DictionaryObjectTypeVisitor.cs
@@ -4,7 +4,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
@@ -16,6 +15,8 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors
///
public class DictionaryObjectTypeVisitor : TypeVisitor
{
+ private readonly Dictionary visitedTypes = new Dictionary();
+
///
public DictionaryObjectTypeVisitor(VisitorCollection visitorCollection)
: base(visitorCollection)
@@ -54,14 +55,20 @@ public override void Visit(IAcceptor acceptor, KeyValuePair type,
};
var schemas = new Dictionary();
- var subAcceptor = new OpenApiSchemaAcceptor()
+ OpenApiSchemaAcceptor subAcceptor;
+ if (!this.visitedTypes.ContainsKey(underlyingType))
{
- Types = types,
- RootSchemas = instance.RootSchemas,
- Schemas = schemas,
- };
-
- subAcceptor.Accept(this.VisitorCollection, namingStrategy);
+ subAcceptor = new OpenApiSchemaAcceptor()
+ {
+ Types = types, RootSchemas = instance.RootSchemas, Schemas = schemas,
+ };
+ this.visitedTypes.Add(underlyingType, subAcceptor);
+ subAcceptor.Accept(this.VisitorCollection, namingStrategy);
+ }
+ else
+ {
+ subAcceptor = this.visitedTypes[underlyingType];
+ }
var properties = subAcceptor.Schemas.First().Value;
@@ -71,7 +78,7 @@ public override void Visit(IAcceptor acceptor, KeyValuePair type,
var reference = new OpenApiReference()
{
Type = ReferenceType.Schema,
- Id = underlyingType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy)
+ Id = underlyingType.GetOpenApiReferenceId(underlyingType.IsOpenApiDictionary(), underlyingType.IsOpenApiArray(), namingStrategy)
};
properties.Reference = reference;
@@ -81,7 +88,6 @@ public override void Visit(IAcceptor acceptor, KeyValuePair type,
// Adds schemas to the root.
var schemasToBeAdded = subAcceptor.Schemas
- .Where(p => !instance.Schemas.Keys.Contains(p.Key))
.Where(p => p.Value.IsOpenApiSchemaObject()
|| p.Value.IsOpenApiSchemaArray()
|| p.Value.IsOpenApiSchemaDictionary()
@@ -133,7 +139,7 @@ public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrat
var reference = new OpenApiReference()
{
Type = ReferenceType.Schema,
- Id = underlyingType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy)
+ Id = underlyingType.GetOpenApiReferenceId(underlyingType.IsOpenApiDictionary(), underlyingType.IsOpenApiArray(), namingStrategy)
};
properties.Reference = reference;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DoubleTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DoubleTypeVisitor.cs
index ae99dcc9..82837755 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DoubleTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/DoubleTypeVisitor.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/GuidObjectTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/GuidObjectTypeVisitor.cs
index c02ea2e9..ae9e3e97 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/GuidObjectTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/GuidObjectTypeVisitor.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/IOpenApiSchemaAcceptor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/IOpenApiSchemaAcceptor.cs
index 5e8570bc..4fac05d8 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/IOpenApiSchemaAcceptor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/IOpenApiSchemaAcceptor.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
-
using Microsoft.OpenApi.Models;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int16EnumTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int16EnumTypeVisitor.cs
index a85f1ef6..c72acce8 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int16EnumTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int16EnumTypeVisitor.cs
@@ -5,7 +5,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int16TypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int16TypeVisitor.cs
index 6f0738eb..02f77e44 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int16TypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int16TypeVisitor.cs
@@ -3,7 +3,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int32EnumTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int32EnumTypeVisitor.cs
index bea7f545..c56df4cf 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int32EnumTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int32EnumTypeVisitor.cs
@@ -5,7 +5,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int32TypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int32TypeVisitor.cs
index a7d8e52d..acd64924 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int32TypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int32TypeVisitor.cs
@@ -3,7 +3,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int64EnumTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int64EnumTypeVisitor.cs
index 7d863f33..e7ca1e5d 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int64EnumTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int64EnumTypeVisitor.cs
@@ -5,7 +5,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int64TypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int64TypeVisitor.cs
index 07e4f7e5..19b3b1dd 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int64TypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/Int64TypeVisitor.cs
@@ -3,7 +3,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/JObjectTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/JObjectTypeVisitor.cs
index d7b50900..bc51f8e3 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/JObjectTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/JObjectTypeVisitor.cs
@@ -3,7 +3,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Linq;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ListObjectTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ListObjectTypeVisitor.cs
index 72c118e3..d314ceab 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ListObjectTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ListObjectTypeVisitor.cs
@@ -4,7 +4,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
@@ -16,6 +15,8 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors
///
public class ListObjectTypeVisitor : TypeVisitor
{
+ private readonly Dictionary visitedTypes = new Dictionary();
+
///
public ListObjectTypeVisitor(VisitorCollection visitorCollection)
: base(visitorCollection)
@@ -54,14 +55,21 @@ public override void Visit(IAcceptor acceptor, KeyValuePair type,
};
var schemas = new Dictionary();
- var subAcceptor = new OpenApiSchemaAcceptor()
+ OpenApiSchemaAcceptor subAcceptor;
+ if (!this.visitedTypes.ContainsKey(underlyingType))
{
- Types = types,
- RootSchemas = instance.RootSchemas,
- Schemas = schemas,
- };
+ subAcceptor = new OpenApiSchemaAcceptor()
+ {
+ Types = types, RootSchemas = instance.RootSchemas, Schemas = schemas,
+ };
+ this.visitedTypes.Add(underlyingType, subAcceptor);
+ subAcceptor.Accept(this.VisitorCollection, namingStrategy);
- subAcceptor.Accept(this.VisitorCollection, namingStrategy);
+ }
+ else
+ {
+ subAcceptor = this.visitedTypes[underlyingType];
+ }
var items = subAcceptor.Schemas.First().Value;
@@ -71,7 +79,7 @@ public override void Visit(IAcceptor acceptor, KeyValuePair type,
var reference = new OpenApiReference()
{
Type = ReferenceType.Schema,
- Id = underlyingType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy)
+ Id = underlyingType.GetOpenApiReferenceId(underlyingType.IsOpenApiDictionary(), underlyingType.IsOpenApiArray(), namingStrategy)
};
items.Reference = reference;
@@ -81,7 +89,6 @@ public override void Visit(IAcceptor acceptor, KeyValuePair type,
// Adds schemas to the root.
var schemasToBeAdded = subAcceptor.Schemas
- .Where(p => !instance.Schemas.Keys.Contains(p.Key))
.Where(p => p.Value.IsOpenApiSchemaObject()
|| p.Value.IsOpenApiSchemaArray()
|| p.Value.IsOpenApiSchemaDictionary()
@@ -148,7 +155,7 @@ public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrat
var reference = new OpenApiReference()
{
Type = ReferenceType.Schema,
- Id = underlyingType.GetOpenApiReferenceId(isDictionary: false, isList: false, namingStrategy)
+ Id = underlyingType.GetOpenApiReferenceId(underlyingType.IsOpenApiDictionary(), underlyingType.IsOpenApiArray(), namingStrategy)
};
items.Reference = reference;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/NullableObjectTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/NullableObjectTypeVisitor.cs
index 8c44a2a9..585f91d0 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/NullableObjectTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/NullableObjectTypeVisitor.cs
@@ -6,7 +6,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs
index 96b0c23c..762eaf40 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs
@@ -15,10 +15,28 @@
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors
{
///
- /// This represents the type visitor for .
+ /// This represents the type visitor for typed object, not .
///
public class ObjectTypeVisitor : TypeVisitor
{
+ private readonly HashSet _noVisitableTypes = new HashSet
+ {
+ typeof(Guid),
+ typeof(DateTime),
+ typeof(DateTimeOffset),
+ typeof(Uri),
+ typeof(Type),
+ typeof(object),
+ typeof(byte[])
+ };
+
+ private readonly HashSet _noAddedKeys = new HashSet
+ {
+ "OBJECT",
+ "JTOKEN",
+ "JOBJECT"
+ };
+
///
public ObjectTypeVisitor(VisitorCollection visitorCollection)
: base(visitorCollection)
@@ -30,27 +48,7 @@ public override bool IsVisitable(Type type)
{
var isVisitable = this.IsVisitable(type, TypeCode.Object);
- if (type == typeof(Guid))
- {
- isVisitable = false;
- }
- else if (type == typeof(DateTime))
- {
- isVisitable = false;
- }
- else if (type == typeof(DateTimeOffset))
- {
- isVisitable = false;
- }
- else if (type == typeof(Uri))
- {
- isVisitable = false;
- }
- else if (type == typeof(Type))
- {
- isVisitable = false;
- }
- else if(type == typeof(byte[]))
+ if (this._noVisitableTypes.Contains(type))
{
isVisitable = false;
}
@@ -207,13 +205,12 @@ private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaNam
// Adds schemas to the root.
var schemasToBeAdded = subAcceptor.Schemas
- .Where(p => !instance.Schemas.Keys.Contains(p.Key))
.Where(p => p.Value.IsOpenApiSchemaObject())
.GroupBy(p => p.Value.Title)
.Select(p => p.First())
.ToDictionary(p => p.Value.Title, p => p.Value);
- foreach (var schema in schemasToBeAdded.Where(p => p.Key != "jObject" && p.Key != "jToken"))
+ foreach (var schema in schemasToBeAdded.Where(p => !this._noAddedKeys.Contains(p.Key.ToUpperInvariant())))
{
if (instance.RootSchemas.ContainsKey(schema.Key))
{
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/RecursiveObjectTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/RecursiveObjectTypeVisitor.cs
index a22a019a..ed4d5eb8 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/RecursiveObjectTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/RecursiveObjectTypeVisitor.cs
@@ -5,7 +5,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
@@ -56,7 +55,7 @@ public override bool IsVisitable(Type type)
{
isVisitable = false;
}
-
+
return isVisitable;
}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/SingleTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/SingleTypeVisitor.cs
index 6c58773d..26beb97b 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/SingleTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/SingleTypeVisitor.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/StringEnumTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/StringEnumTypeVisitor.cs
index ab9d6c70..1d1c7bcb 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/StringEnumTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/StringEnumTypeVisitor.cs
@@ -5,7 +5,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/TypeTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/TypeTypeVisitor.cs
index 01afd499..6d955321 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/TypeTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/TypeTypeVisitor.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+
using Newtonsoft.Json.Serialization;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UInt16TypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UInt16TypeVisitor.cs
index 05beba29..a9723238 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UInt16TypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UInt16TypeVisitor.cs
@@ -3,7 +3,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UInt32TypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UInt32TypeVisitor.cs
index d9318785..12e63734 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UInt32TypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UInt32TypeVisitor.cs
@@ -3,7 +3,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UInt64TypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UInt64TypeVisitor.cs
index 802e6f77..9c17d752 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UInt64TypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UInt64TypeVisitor.cs
@@ -3,7 +3,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UriTypeVisitor.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UriTypeVisitor.cs
index f36a5c8b..32ae534d 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UriTypeVisitor.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/UriTypeVisitor.cs
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
+
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.OpenApi.Models;
+
using Newtonsoft.Json.Serialization;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/VisitorCollection.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/VisitorCollection.cs
index 95f2c4d3..30423b84 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/VisitorCollection.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/VisitorCollection.cs
@@ -4,7 +4,6 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
-
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/Document.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/Document.cs
index 4c279135..6ba7a792 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/Document.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/Document.cs
@@ -69,7 +69,7 @@ public IDocument AddServer(IHttpRequestDataObject req, string routePrefix, IOpen
this._req = req;
var prefix = string.IsNullOrWhiteSpace(routePrefix) ? string.Empty : $"/{routePrefix}";
- var baseUrl = $"{this._req.Scheme}://{this._req.Host}{prefix}";
+ var baseUrl = $"{this._req.GetScheme(options)}://{this._req.Host}{prefix}";
var server = new OpenApiServer { Url = baseUrl };
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/HttpRequestObject.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/HttpRequestObject.cs
index 97124a86..d82932b4 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/HttpRequestObject.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/HttpRequestObject.cs
@@ -21,6 +21,7 @@ public HttpRequestObject(HttpRequest req)
this.Scheme = req.Scheme;
this.Host = req.Host;
+ this.Headers = req.Headers;
this.Query = req.Query;
this.Body = req.Body;
}
@@ -31,6 +32,9 @@ public HttpRequestObject(HttpRequest req)
///
public virtual HostString Host { get; }
+ ///
+ public virtual IHeaderDictionary Headers { get; }
+
///
public virtual IQueryCollection Query { get;}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/IOpenApiHttpTriggerContext.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/IOpenApiHttpTriggerContext.cs
deleted file mode 100644
index e5601703..00000000
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/IOpenApiHttpTriggerContext.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-using System;
-using System.Reflection;
-using System.Threading.Tasks;
-
-using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
-using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
-using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
-using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors;
-using Microsoft.OpenApi;
-
-using Newtonsoft.Json.Serialization;
-
-namespace Microsoft.Azure.WebJobs.Extensions.OpenApi
-{
- ///
- /// This provides interfaces to .
- ///
- public interface IOpenApiHttpTriggerContext
- {
- ///
- /// Gets the instance representing the Azure Functions app.
- ///
- Assembly ApplicationAssembly { get; }
-
- ///
- /// Gets the instance representing the Azure Functions OpenAPI Extension package.
- ///
- Assembly PackageAssembly { get; }
-
- ///
- /// Gets the instance.
- ///
- IOpenApiConfigurationOptions OpenApiConfigurationOptions { get; }
-
- ///
- /// Gets the instance.
- ///
- IOpenApiCustomUIOptions OpenApiCustomUIOptions { get; }
-
- ///
- /// Gets the instance.
- ///
- HttpSettings HttpSettings { get; }
-
- ///
- /// Gets the instance.
- ///
- IDocument Document { get; }
-
- ///
- /// Gets the instance.
- ///
- ISwaggerUI SwaggerUI { get; }
-
- ///
- /// Gets the instance.
- ///
- NamingStrategy NamingStrategy { get; }
-
- ///
- /// Gets the value indicating whether it's in the development environment or not.
- ///
- bool IsDevelopment { get; }
-
- ///
- /// Gets the executing assembly.
- ///
- /// Returns the executing assembly.
- [Obsolete("This method is obsolete.", error: true)]
- Assembly GetExecutingAssembly();
-
- ///
- /// Sets the application assembly from the function app directory.
- ///
- /// Function app directory.
- /// Value indicating whether to append the "bin" directory or not.
- Task SetApplicationAssemblyAsync(string functionAppDirectory, bool appendBin = true);
-
- ///
- /// Gets the instance.
- ///
- /// Returns the instance.
- VisitorCollection GetVisitorCollection();
-
- ///
- /// Gets the value.
- ///
- /// OpenAPI spec version. It can be either v2 or v3.
- /// Returns the value.
- OpenApiVersionType GetOpenApiVersionType(string version = "v2");
-
- ///
- /// Gets the value.
- ///
- /// OpenAPI spec version. It can be either v2 or v3.
- /// Returns the value.
- OpenApiSpecVersion GetOpenApiSpecVersion(string version = "v2");
-
- ///
- /// Gets the value.
- ///
- /// value.
- /// Returns the value.
- OpenApiSpecVersion GetOpenApiSpecVersion(OpenApiVersionType version = OpenApiVersionType.V2);
-
- ///
- /// Gets the value.
- ///
- /// OpenAPI document format. It can be either json or yaml.
- /// Returns the value.
- OpenApiFormat GetOpenApiFormat(string format = "json");
-
- ///
- /// Gets the value.
- ///
- /// value.
- /// Returns the value.
- OpenApiFormat GetOpenApiFormat(OpenApiFormatType format = OpenApiFormatType.Json);
-
- ///
- /// Gets the auth level of the document rendering page endpoint.
- ///
- /// Environment variables key to look for.
- /// Returns the auth level of the document rendering page endpoint.
- OpenApiAuthLevelType GetDocumentAuthLevel(string key = "OpenApi__AuthLevel__Document");
-
- ///
- /// Gets the auth level of the UI rendering page endpoint.
- ///
- /// Environment variables key to look for.
- /// Returns the auth level of the UI rendering page endpoint.
- OpenApiAuthLevelType GetUIAuthLevel(string key = "OpenApi__AuthLevel__UI");
-
- ///
- /// Gets the API key for endpoints from environment variables.
- ///
- /// Environment variables key to look for.
- /// Returns the API key for endpoints.
- string GetSwaggerAuthKey(string key = "OpenApi__ApiKey");
- }
-}
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/OpenApiHttpTriggerContext.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/OpenApiHttpTriggerContext.cs
index 937a3b9d..cd32c832 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/OpenApiHttpTriggerContext.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/OpenApiHttpTriggerContext.cs
@@ -140,6 +140,24 @@ public virtual async Task SetApplicationAssemblyAsyn
return this;
}
+ ///
+ public virtual async Task AuthorizeAsync(IHttpRequestDataObject req)
+ {
+ var result = default(OpenApiAuthorizationResult);
+ var type = this.ApplicationAssembly
+ .GetLoadableTypes()
+ .SingleOrDefault(p => p.HasInterface());
+ if (type.IsNullOrDefault())
+ {
+ return result;
+ }
+
+ var auth = Activator.CreateInstance(type) as IOpenApiHttpTriggerAuthorization;
+ result = await auth.AuthorizeAsync(req).ConfigureAwait(false);
+
+ return result;
+ }
+
///
public virtual VisitorCollection GetVisitorCollection()
{
diff --git a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/OpenApiTriggerFunctions.cs b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/OpenApiTriggerFunctions.cs
index 5dd7a267..ed6261a3 100644
--- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/OpenApiTriggerFunctions.cs
+++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi/OpenApiTriggerFunctions.cs
@@ -4,6 +4,7 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
using Microsoft.Extensions.Logging;
@@ -35,15 +36,30 @@ public static async Task RenderSwaggerDocument(HttpRequest req, s
{
log.LogInformation($"swagger.{extension} was requested.");
+ var request = new HttpRequestObject(req);
var result = default(string);
var content = default(ContentResult);
try
{
- result = await (await context.SetApplicationAssemblyAsync(ctx.FunctionAppDirectory))
- .Document
+ var auth = await context.SetApplicationAssemblyAsync(ctx.FunctionAppDirectory)
+ .AuthorizeAsync(request)
+ .ConfigureAwait(false);
+ if (!auth.IsNullOrDefault())
+ {
+ content = new ContentResult()
+ {
+ Content = auth.Payload,
+ ContentType = auth.ContentType,
+ StatusCode = (int)auth.StatusCode,
+ };
+
+ return content;
+ }
+
+ result = await context.Document
.InitialiseDocument()
.AddMetadata(context.OpenApiConfigurationOptions.Info)
- .AddServer(new HttpRequestObject(req), context.HttpSettings.RoutePrefix, context.OpenApiConfigurationOptions)
+ .AddServer(request, context.HttpSettings.RoutePrefix, context.OpenApiConfigurationOptions)
.AddNamingStrategy(context.NamingStrategy)
.AddVisitors(context.GetVisitorCollection())
.Build(context.ApplicationAssembly, context.OpenApiConfigurationOptions.OpenApiVersion)
@@ -92,12 +108,27 @@ public static async Task RenderOpenApiDocument(HttpRequest req, s
{
log.LogInformation($"{version}.{extension} was requested.");
+ var request = new HttpRequestObject(req);
var result = default(string);
var content = default(ContentResult);
try
{
- result = await (await context.SetApplicationAssemblyAsync(ctx.FunctionAppDirectory))
- .Document
+ var auth = await context.SetApplicationAssemblyAsync(ctx.FunctionAppDirectory)
+ .AuthorizeAsync(request)
+ .ConfigureAwait(false);
+ if (!auth.IsNullOrDefault())
+ {
+ content = new ContentResult()
+ {
+ Content = auth.Payload,
+ ContentType = auth.ContentType,
+ StatusCode = (int)auth.StatusCode,
+ };
+
+ return content;
+ }
+
+ result = await context.Document
.InitialiseDocument()
.AddMetadata(context.OpenApiConfigurationOptions.Info)
.AddServer(new HttpRequestObject(req), context.HttpSettings.RoutePrefix, context.OpenApiConfigurationOptions)
@@ -147,12 +178,27 @@ public static async Task RenderSwaggerUI(HttpRequest req, Executi
{
log.LogInformation("SwaggerUI page was requested.");
+ var request = new HttpRequestObject(req);
var result = default(string);
var content = default(ContentResult);
try
{
- result = await (await context.SetApplicationAssemblyAsync(ctx.FunctionAppDirectory))
- .SwaggerUI
+ var auth = await context.SetApplicationAssemblyAsync(ctx.FunctionAppDirectory)
+ .AuthorizeAsync(request)
+ .ConfigureAwait(false);
+ if (!auth.IsNullOrDefault())
+ {
+ content = new ContentResult()
+ {
+ Content = auth.Payload,
+ ContentType = auth.ContentType,
+ StatusCode = (int)auth.StatusCode,
+ };
+
+ return content;
+ }
+
+ result = await context.SwaggerUI
.AddMetadata(context.OpenApiConfigurationOptions.Info)
.AddServer(new HttpRequestObject(req), context.HttpSettings.RoutePrefix, context.OpenApiConfigurationOptions)
.BuildAsync(context.PackageAssembly, context.OpenApiCustomUIOptions)
@@ -199,13 +245,16 @@ public static async Task RenderOAuth2Redirect(HttpRequest req, Ex
{
log.LogInformation("The oauth2-redirect.html page was requested.");
+ var request = new HttpRequestObject(req);
var result = default(string);
var content = default(ContentResult);
try
{
- result = await (await context.SetApplicationAssemblyAsync(ctx.FunctionAppDirectory))
- .SwaggerUI
- .AddServer(new HttpRequestObject(req), context.HttpSettings.RoutePrefix, context.OpenApiConfigurationOptions)
+ await context.SetApplicationAssemblyAsync(ctx.FunctionAppDirectory)
+ .ConfigureAwait(false);
+
+ result = await context.SwaggerUI
+ .AddServer(request, context.HttpSettings.RoutePrefix, context.OpenApiConfigurationOptions)
.BuildOAuth2RedirectAsync(context.PackageAssembly)
.RenderOAuth2RedirectAsync("oauth2-redirect.html", context.GetDocumentAuthLevel(), context.GetSwaggerAuthKey())
.ConfigureAwait(false);
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_ArrayObject_Tests.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_ArrayObject_Tests.cs
index 47200e95..718df49d 100644
--- a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_ArrayObject_Tests.cs
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_ArrayObject_Tests.cs
@@ -75,6 +75,7 @@ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchema(string @
[DataRow("arrayObjectModel", "object", "decimalValue", "array")]
[DataRow("arrayObjectModel", "object", "stringObjectValue", "array")]
[DataRow("arrayObjectModel", "object", "int32ObjectValue", "array")]
+ [DataRow("arrayObjectModel", "object", "stringObjectModel", "array")]
public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaProperty(string @ref, string refType, string propertyName, string propertyType)
{
var properties = this._doc["components"]["schemas"][@ref]["properties"];
@@ -105,6 +106,7 @@ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaPropertyI
[DataTestMethod]
[DataRow("arrayObjectModel", "object", "stringObjectValue", "array", "stringObjectModel")]
[DataRow("arrayObjectModel", "object", "int32ObjectValue", "array", "int32ObjectModel")]
+ [DataRow("arrayObjectModel", "object", "stringObjectModel", "array", "stringObjectModel")]
public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaPropertyItemReference(string @ref, string refType, string propertyName, string propertyType, string itemRef)
{
var items = this._doc["components"]["schemas"][@ref]["properties"][propertyName]["items"];
@@ -113,6 +115,8 @@ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaPropertyI
itemReference.Should().NotBeNull();
itemReference.Value().Should().Be($"#/components/schemas/{itemRef}");
+
+ this._doc["components"]["schemas"][itemRef].Should().NotBeNullOrEmpty();
}
}
}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_BaseObject_Tests.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_BaseObject_Tests.cs
new file mode 100644
index 00000000..e1fae5f0
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_BaseObject_Tests.cs
@@ -0,0 +1,74 @@
+using System.Net.Http;
+using System.Threading.Tasks;
+
+using FluentAssertions;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests
+{
+ [TestClass]
+ [TestCategory(Constants.TestCategory)]
+ public class Get_ApplicationJson_BaseObject_Tests
+ {
+ private static HttpClient http = new HttpClient();
+
+ private JObject _doc;
+
+ [TestInitialize]
+ public async Task Init()
+ {
+ var json = await http.GetStringAsync(Constants.OpenApiDocEndpoint).ConfigureAwait(false);
+ this._doc = JsonConvert.DeserializeObject(json);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-applicationjson-baseobject", "get", "200")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponse(string path, string operationType, string responseCode)
+ {
+ var responses = this._doc["paths"][path][operationType]["responses"];
+
+ responses[responseCode].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-applicationjson-baseobject", "get", "200", "application/json")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentType(string path, string operationType, string responseCode, string contentType)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ content[contentType].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-applicationjson-baseobject", "get", "200", "application/json", "stringObjectModel")]
+ public void Given_OpenApiDocument_Then_It_Should_Not_Return_ReferenceSchema(string path, string operationType, string responseCode, string contentType, string reference)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+ }
+
+ [DataTestMethod]
+ [DataRow("hasBaseObjectModel", "objectValue", true)]
+ [DataRow("hasBaseObjectModel", "nonObjectValue", false)]
+ [DataRow("hasBaseObjectModel", "subModel", false)]
+ [DataRow("hasBaseObjectSubModel", "subObjectValue", true)]
+ public void Given_OpenApiDocument_And_BaseObject_Then_It_Should_Return_Expected_Type(string @ref, string propName,bool isBaseObject)
+ {
+ var schemas = this._doc["components"]["schemas"];
+
+ var type = schemas?[@ref]?["properties"]?[propName]?["type"]?.Value() ;
+
+ if (isBaseObject)
+ {
+ type.Should().Be("object");
+ }
+ else
+ {
+ type.Should().NotBe("object");
+ }
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_DictionaryObject_Tests.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_DictionaryObject_Tests.cs
new file mode 100644
index 00000000..5e1c7e65
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_DictionaryObject_Tests.cs
@@ -0,0 +1,115 @@
+using System.Net.Http;
+using System.Threading.Tasks;
+
+using FluentAssertions;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests
+{
+ [TestClass]
+ [TestCategory(Constants.TestCategory)]
+ public class Get_ApplicationJson_DictionaryObject_Tests
+ {
+ private static HttpClient http = new HttpClient();
+
+ private JObject _doc;
+
+ [TestInitialize]
+ public async Task Init()
+ {
+ var json = await http.GetStringAsync(Constants.OpenApiDocEndpoint).ConfigureAwait(false);
+ this._doc = JsonConvert.DeserializeObject(json);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-applicationjson-dictionary", "get", "200")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponse(string path, string operationType, string responseCode)
+ {
+ var responses = this._doc["paths"][path][operationType]["responses"];
+
+ responses[responseCode].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-applicationjson-dictionary", "get", "200", "application/json")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentType(string path, string operationType, string responseCode, string contentType)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ content[contentType].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-applicationjson-dictionary", "get", "200", "application/json", "dictionaryObjectModel")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentTypeSchema(string path, string operationType, string responseCode, string contentType, string reference)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ var @ref = content[contentType]["schema"]["$ref"];
+
+ @ref.Value().Should().Be($"#/components/schemas/{reference}");
+ }
+
+ [DataTestMethod]
+ [DataRow("dictionaryObjectModel", "object", "boolValue", "object", "boolean")]
+ [DataRow("dictionaryObjectModel", "object", "stringValue", "object", "string")]
+ [DataRow("dictionaryObjectModel", "object", "floatValue", "object", "number")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchema(string @ref, string refType, string propertyName, string propertyType, string itemType)
+ {
+ var items = this._doc["components"]["schemas"][@ref]["properties"][propertyName];
+
+ var type = items["additionalProperties"]["type"];
+
+ type.Should().NotBeNull();
+ type.Value().Should().Be(itemType);
+ }
+
+ [DataTestMethod]
+ [DataRow("dictionaryObjectModel", "int32ObjectValue", "object", "int32ObjectModel")]
+ [DataRow("dictionaryObjectModel", "stringObjectModel", "object", "stringObjectModel")]
+ [DataRow("dictionaryObjectModel", "stringArrayValue", "object", "list_string")]
+ [DataRow("dictionaryObjectModel", "intArrayValue", "object", "list_int32")]
+
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaProperty(string @ref, string propertyName, string propertyType, string itemRef)
+ {
+ var properties = this._doc["components"]["schemas"][@ref]["properties"];
+
+ var value = properties[propertyName];
+
+ value.Should().NotBeNull();
+ value.Value("type").Should().Be(propertyType);
+ value["additionalProperties"].Should().NotBeNullOrEmpty();
+ value["additionalProperties"].Value("$ref").Should().Be($"#/components/schemas/{itemRef}");
+
+ this._doc["components"]["schemas"][itemRef].Should().NotBeNullOrEmpty();
+ }
+
+ [DataTestMethod]
+ [DataRow("list_string", "array")]
+ [DataRow("list_int32", "array")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentReferenceSchema(string @ref, string refType)
+ {
+ var schemas = this._doc["components"]["schemas"];
+ var schema = schemas[@ref]["type"];
+
+ schema.Should().NotBeNull();
+ schema.Value().Should().Be(refType);
+ schema.Value().Should().Be(refType);
+ }
+
+ [DataTestMethod]
+ [DataRow("list_string", "array", "string")]
+ [DataRow("list_int32", "array", "integer")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentReferenceSchema(string @ref, string refType, string itemType)
+ {
+ var items = this._doc["components"]["schemas"][@ref];
+ var type = items["items"]["type"];
+ type.Should().NotBeNull();
+ type.Value().Should().Be(itemType);
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_JObject_Tests.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_JObject_Tests.cs
new file mode 100644
index 00000000..ea2194e7
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_ApplicationJson_JObject_Tests.cs
@@ -0,0 +1,83 @@
+using System.Net.Http;
+using System.Threading.Tasks;
+
+using FluentAssertions;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests
+{
+ [TestClass]
+ [TestCategory(Constants.TestCategory)]
+ public class Get_ApplicationJson_JObject_Tests
+ {
+ private static HttpClient http = new HttpClient();
+
+ private JObject _doc;
+
+ [TestInitialize]
+ public async Task Init()
+ {
+ var json = await http.GetStringAsync(Constants.OpenApiDocEndpoint).ConfigureAwait(false);
+ this._doc = JsonConvert.DeserializeObject(json);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-applicationjson-jobject", "get", "200")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponse(string path, string operationType, string responseCode)
+ {
+ var responses = this._doc["paths"][path][operationType]["responses"];
+
+ responses[responseCode].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-applicationjson-jobject", "get", "200", "application/json")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentType(string path, string operationType, string responseCode, string contentType)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ content[contentType].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-applicationjson-jobject", "get", "200", "application/json", "jObjectModel")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentTypeSchema(string path, string operationType, string responseCode, string contentType, string reference)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ var @ref = content[contentType]["schema"]["$ref"];
+
+ @ref.Value().Should().Be($"#/components/schemas/{reference}");
+ }
+
+ [DataTestMethod]
+ [DataRow("jObjectModel", "object")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchema(string @ref, string refType)
+ {
+ var schemas = this._doc["components"]["schemas"];
+
+ var schema = schemas[@ref];
+
+ schema.Should().NotBeNull();
+ schema.Value("type").Should().Be(refType);
+ }
+
+ [DataTestMethod]
+ [DataRow("jObjectModel", "jObjectValue", "object")]
+ [DataRow("jObjectModel", "jTokenValue", "object")]
+ [DataRow("jObjectModel", "jArrayValue", "object")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaProperty(string @ref, string propertyName, string propertyType)
+ {
+ var properties = this._doc["components"]["schemas"][@ref]["properties"];
+
+ var value = properties[propertyName];
+
+ value.Should().NotBeNull();
+ value.Value("type").Should().Be(propertyType);
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_Query_ParameterExamples_Tests.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_Query_ParameterExamples_Tests.cs
new file mode 100644
index 00000000..fbbc4a9e
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_Query_ParameterExamples_Tests.cs
@@ -0,0 +1,304 @@
+using System;
+using System.Linq;
+using System.Net.Http;
+using System.Threading.Tasks;
+
+using FluentAssertions;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests
+{
+ [TestClass]
+ [TestCategory(Constants.TestCategory)]
+ public class Get_Query_ParameterExamples_Tests
+ {
+ private static HttpClient http = new HttpClient();
+
+ private JObject _doc;
+
+ [TestInitialize]
+ public async Task Init()
+ {
+ var json = await http.GetStringAsync(Constants.OpenApiDocEndpoint).ConfigureAwait(false);
+ this._doc = JsonConvert.DeserializeObject(json);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_Path(string path)
+ {
+ var paths = this._doc["paths"];
+
+ paths.Value(path).Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationType(string path, string operationType)
+ {
+ var pathItem = this._doc["paths"][path];
+
+ pathItem.Value(operationType).Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "stringParameter", "query", true)]
+ [DataRow("/get-query-parameter-examples", "get", "int16Parameter", "query", true)]
+ [DataRow("/get-query-parameter-examples", "get", "int32Parameter", "query", true)]
+ [DataRow("/get-query-parameter-examples", "get", "int64Parameter", "query", true)]
+ [DataRow("/get-query-parameter-examples", "get", "uint16Parameter", "query", true)]
+ [DataRow("/get-query-parameter-examples", "get", "uint32Parameter", "query", true)]
+ [DataRow("/get-query-parameter-examples", "get", "uint64Parameter", "query", true)]
+ [DataRow("/get-query-parameter-examples", "get", "singleParameter", "query", true)]
+ [DataRow("/get-query-parameter-examples", "get", "doubleParameter", "query", true)]
+ [DataRow("/get-query-parameter-examples", "get", "dateTimeParameter", "query", true)]
+ [DataRow("/get-query-parameter-examples", "get", "booleanParameter", "query", true)]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationParameter(string path, string operationType, string name, string @in, bool required)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ parameter.Should().NotBeNull();
+ parameter.Value("in").Should().Be(@in);
+ parameter.Value("required").Should().Be(required);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "stringParameter", "string")]
+ [DataRow("/get-query-parameter-examples", "get", "int16Parameter", "integer")]
+ [DataRow("/get-query-parameter-examples", "get", "int32Parameter", "integer")]
+ [DataRow("/get-query-parameter-examples", "get", "int64Parameter", "integer")]
+ [DataRow("/get-query-parameter-examples", "get", "uint16Parameter", "integer")]
+ [DataRow("/get-query-parameter-examples", "get", "uint32Parameter", "integer")]
+ [DataRow("/get-query-parameter-examples", "get", "uint64Parameter", "integer")]
+ [DataRow("/get-query-parameter-examples", "get", "singleParameter", "number")]
+ [DataRow("/get-query-parameter-examples", "get", "doubleParameter", "number")]
+ [DataRow("/get-query-parameter-examples", "get", "dateTimeParameter", "string")]
+ [DataRow("/get-query-parameter-examples", "get", "booleanParameter", "boolean")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationParameterSchema(string path, string operationType, string name, string dataType)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var schema = parameter["schema"];
+
+ schema.Value("type").Should().Be(dataType);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "stringParameter", "stringValue1", "Lorem", "stringValue2", "")]
+ public void Given_OpenApiDocument_StringType_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, string exampleValue1, string exampleName2, string exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(exampleValue1);
+ examples[exampleName2]["value"].Value().Should().Be(exampleValue2);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "int16Parameter", "int16Value1", (short)1, "int16Value2", (short)0)]
+ public void Given_OpenApiDocument_Int16Type_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, short exampleValue1, string exampleName2, short exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(exampleValue1);
+ examples[exampleName2]["value"].Value().Should().Be(exampleValue2);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "int32Parameter", "int32Value1", 1, "int32Value2", 0)]
+ public void Given_OpenApiDocument_Int32Type_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, int exampleValue1, string exampleName2, int exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(exampleValue1);
+ examples[exampleName2]["value"].Value().Should().Be(exampleValue2);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "int64Parameter", "int64Value1", (long)1, "int64Value2", (long)0)]
+ public void Given_OpenApiDocument_Int64Type_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, long exampleValue1, string exampleName2, long exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(exampleValue1);
+ examples[exampleName2]["value"].Value().Should().Be(exampleValue2);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "uint16Parameter", "uint16Value1", (ushort)1, "uint16Value2", (ushort)0)]
+ public void Given_OpenApiDocument_Uint16Type_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, ushort exampleValue1, string exampleName2, ushort exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(exampleValue1);
+ examples[exampleName2]["value"].Value().Should().Be(exampleValue2);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "uint32Parameter", "uint32Value1", (uint)1, "uint32Value2", (uint)0)]
+ public void Given_OpenApiDocument_Uint32Type_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, uint exampleValue1, string exampleName2, uint exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(exampleValue1);
+ examples[exampleName2]["value"].Value().Should().Be(exampleValue2);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "uint64Parameter", "uint64Value1", (ulong)1, "uint64Value2", (ulong)0)]
+ public void Given_OpenApiDocument_Uint64Type_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, ulong exampleValue1, string exampleName2, ulong exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(exampleValue1);
+ examples[exampleName2]["value"].Value().Should().Be(exampleValue2);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "singleParameter", "singleValue1", (float)1.1, "singleValue2", (float)0.0)]
+ public void Given_OpenApiDocument_SingleType_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, float exampleValue1, string exampleName2, float exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(exampleValue1);
+ examples[exampleName2]["value"].Value().Should().Be(exampleValue2);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "doubleParameter", "doubleValue1", (double)1.1, "doubleValue2", (double)0.0)]
+ public void Given_OpenApiDocument_DoubleType_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, double exampleValue1, string exampleName2, double exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(exampleValue1);
+ examples[exampleName2]["value"].Value().Should().Be(exampleValue2);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "dateTimeParameter", "dateTimeValue1", "2021-01-01", "dateTimeValue2", "2021-01-01T12:34:56Z")]
+ public void Given_OpenApiDocument_DateTimeType_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, string exampleValue1, string exampleName2, string exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(DateTime.Parse(exampleValue1));
+ examples[exampleName2]["value"].Value().Should().Be(DateTime.Parse(exampleValue2));
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "dateTimeOffsetParameter", "dateTimeOffsetValue1", "05/01/2008", "dateTimeOffsetValue2", "11:36 PM")]
+ [DataRow("/get-query-parameter-examples", "get", "dateTimeOffsetParameter", "dateTimeOffsetValue3", "05/01/2008 +1:00", "dateTimeOffsetValue4", "Thu May 01, 2008")]
+ public void Given_OpenApiDocument_DateTimeOffsetType_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, string exampleValue1, string exampleName2, string exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(DateTime.Parse(exampleValue1));
+ examples[exampleName2]["value"].Value().Should().Be(DateTime.Parse(exampleValue2));
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "booleanParameter", "booleanValue1", true, "booleanValue2", false)]
+ public void Given_OpenApiDocument_BooleanType_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, bool exampleValue1, string exampleName2, bool exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(exampleValue1);
+ examples[exampleName2]["value"].Value().Should().Be(exampleValue2);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "guidParameter", "guidValue1", "74be27de-1e4e-49d9-b579-fe0b331d3642")]
+ public void Given_OpenApiDocument_GuidType_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName, string exampleValue)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName]["value"].Value().Should().Be(exampleValue);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "byteArrayParameter", "byteArrayValue1", "rBgS8A==", "byteArrayValue2", "/zIR")]
+ public void Given_OpenApiDocument_ByteArrayType_Then_It_Should_Return_OperationParameterExamples(string path, string operationType, string name, string exampleName1, string exampleValue1, string exampleName2, string exampleValue2)
+ {
+ var parameters = this._doc["paths"][path][operationType]["parameters"].Children();
+ var parameter = parameters.SingleOrDefault(p => p["name"].Value() == name);
+
+ var examples = parameter["examples"];
+
+ examples[exampleName1]["value"].Value().Should().Be(exampleValue1);
+ examples[exampleName2]["value"].Value().Should().Be(exampleValue2);
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "200")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponse(string path, string operationType, string responseCode)
+ {
+ var responses = this._doc["paths"][path][operationType]["responses"];
+
+ responses[responseCode].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "200", "text/plain")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentType(string path, string operationType, string responseCode, string contentType)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ content[contentType].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/get-query-parameter-examples", "get", "200", "text/plain", "string")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentTypeSchema(string path, string operationType, string responseCode, string contentType, string dataType)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ var schema = content[contentType]["schema"];
+
+ schema.Value("type").Should().Be(dataType);
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_Query_TextPlain_String_Tests.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_Query_TextPlain_String_Tests.cs
index e8d77472..fefee098 100644
--- a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_Query_TextPlain_String_Tests.cs
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Get_Query_TextPlain_String_Tests.cs
@@ -1,3 +1,4 @@
+using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Post_AppicationJson_Decimal_Tests.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Post_AppicationJson_Decimal_Tests.cs
new file mode 100644
index 00000000..8fdd8cf3
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Post_AppicationJson_Decimal_Tests.cs
@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests
+{
+ [TestClass]
+ [TestCategory(Constants.TestCategory)]
+ public class Post_AppicationJson_Decimal_Tests
+ {
+ private static HttpClient http = new HttpClient();
+
+ private JObject _doc;
+
+ [TestInitialize]
+ public async Task Init()
+ {
+ var json = await http.GetStringAsync(Constants.OpenApiDocEndpoint).ConfigureAwait(false);
+ this._doc = JsonConvert.DeserializeObject(json);
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-decimal", "post")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationRequestBody(string path, string operationType)
+ {
+ var requestBody = this._doc["paths"][path][operationType]["requestBody"];
+
+ requestBody.Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-decimal", "post", "text/plain")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationRequestBodyContentType(string path, string operationType, string contentType)
+ {
+ var content = this._doc["paths"][path][operationType]["requestBody"]["content"];
+
+ content[contentType].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-decimal", "post", "text/plain", "number", "double")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationRequestBodyContentTypeSchema(string path, string operationType, string contentType, string propertyType, string propertyFormat)
+ {
+ var content = this._doc["paths"][path][operationType]["requestBody"]["content"];
+
+ var value = content[contentType]["schema"];
+
+ value.Should().NotBeNull();
+ value.Value("type").Should().Be(propertyType);
+ value.Value("format").Should().Be(propertyFormat);
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-decimal", "post", "200")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponse(string path, string operationType, string responseCode)
+ {
+ var responses = this._doc["paths"][path][operationType]["responses"];
+
+ responses[responseCode].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-decimal", "post", "200", "application/json")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentType(string path, string operationType, string responseCode, string contentType)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ content[contentType].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-decimal", "post", "200", "application/json", "decimalTypeObjectModel")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentTypeSchema(string path, string operationType, string responseCode, string contentType, string reference)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ var @ref = content[contentType]["schema"]["$ref"];
+
+ @ref.Value().Should().Be($"#/components/schemas/{reference}");
+ }
+
+ [DataTestMethod]
+ [DataRow("decimalTypeObjectModel", "object")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchema(string @ref, string refType)
+ {
+ var schemas = this._doc["components"]["schemas"];
+
+ var schema = schemas[@ref];
+
+ schema.Should().NotBeNull();
+ schema.Value("type").Should().Be(refType);
+ }
+
+ [DataTestMethod]
+ [DataRow("decimalTypeObjectModel", "decimalValue", "number", "double")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaProperty(string @ref, string propertyName, string propertyType, string propertyFormat)
+ {
+ var properties = this._doc["components"]["schemas"][@ref]["properties"];
+
+ var value = properties[propertyName];
+
+ value.Should().NotBeNull();
+ value.Value("type").Should().Be(propertyType);
+ value.Value("format").Should().Be(propertyFormat);
+ }
+
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Post_ApplicationJson_Boolean_Tests.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Post_ApplicationJson_Boolean_Tests.cs
new file mode 100644
index 00000000..e19c6307
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Post_ApplicationJson_Boolean_Tests.cs
@@ -0,0 +1,111 @@
+using System.Net.Http;
+using System.Threading.Tasks;
+
+using FluentAssertions;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests
+{
+ [TestClass]
+ [TestCategory(Constants.TestCategory)]
+ public class Post_ApplicationJson_Boolean_Tests
+ {
+ private static HttpClient http = new HttpClient();
+
+ private JObject _doc;
+
+ [TestInitialize]
+ public async Task Init()
+ {
+ var json = await http.GetStringAsync(Constants.OpenApiDocEndpoint).ConfigureAwait(false);
+ this._doc = JsonConvert.DeserializeObject(json);
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-boolean", "post")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationRequestBody(string path, string operationType)
+ {
+ var requestBody = this._doc["paths"][path][operationType]["requestBody"];
+
+ requestBody.Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-boolean", "post", "text/plain")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationRequestBodyContentType(string path, string operationType, string contentType)
+ {
+ var content = this._doc["paths"][path][operationType]["requestBody"]["content"];
+
+ content[contentType].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-boolean", "post", "text/plain", "boolean")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationRequestBodyContentTypeSchema(string path, string operationType, string contentType, string propertyType)
+ {
+ var content = this._doc["paths"][path][operationType]["requestBody"]["content"];
+
+ var value = content[contentType]["schema"];
+
+ value.Should().NotBeNull();
+ value.Value("type").Should().Be(propertyType);
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-boolean", "post", "200")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponse(string path, string operationType, string responseCode)
+ {
+ var responses = this._doc["paths"][path][operationType]["responses"];
+
+ responses[responseCode].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-boolean", "post", "200", "application/json")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentType(string path, string operationType, string responseCode, string contentType)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ content[contentType].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-boolean", "post", "200", "application/json", "booleanObjectModel")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentTypeSchema(string path, string operationType, string responseCode, string contentType, string reference)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ var @ref = content[contentType]["schema"]["$ref"];
+
+ @ref.Value().Should().Be($"#/components/schemas/{reference}");
+ }
+
+ [DataTestMethod]
+ [DataRow("booleanObjectModel", "object")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchema(string @ref, string refType)
+ {
+ var schemas = this._doc["components"]["schemas"];
+
+ var schema = schemas[@ref];
+
+ schema.Should().NotBeNull();
+ schema.Value("type").Should().Be(refType);
+ }
+
+ [DataTestMethod]
+ [DataRow("booleanObjectModel", "booleanValue", "boolean")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaProperty(string @ref, string propertyName, string propertyType)
+ {
+ var properties = this._doc["components"]["schemas"][@ref]["properties"];
+
+ var value = properties[propertyName];
+
+ value.Should().NotBeNull();
+ value.Value("type").Should().Be(propertyType);
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Post_ApplicationJson_Double_Tests.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Post_ApplicationJson_Double_Tests.cs
new file mode 100644
index 00000000..ad98d0fa
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Post_ApplicationJson_Double_Tests.cs
@@ -0,0 +1,113 @@
+using System.Net.Http;
+using System.Threading.Tasks;
+
+using FluentAssertions;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests
+{
+ [TestClass]
+ [TestCategory(Constants.TestCategory)]
+ public class Post_ApplicationJson_Double_Tests
+ {
+ private static HttpClient http = new HttpClient();
+
+ private JObject _doc;
+
+ [TestInitialize]
+ public async Task Init()
+ {
+ var json = await http.GetStringAsync(Constants.OpenApiDocEndpoint).ConfigureAwait(false);
+ this._doc = JsonConvert.DeserializeObject(json);
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-double", "post")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationRequestBody(string path, string operationType)
+ {
+ var requestBody = this._doc["paths"][path][operationType]["requestBody"];
+
+ requestBody.Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-double", "post", "text/plain")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationRequestBodyContentType(string path, string operationType, string contentType)
+ {
+ var content = this._doc["paths"][path][operationType]["requestBody"]["content"];
+
+ content[contentType].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-double", "post", "text/plain", "number", "double")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationRequestBodyContentTypeSchema(string path, string operationType, string contentType, string propertyType, string propertyFormat)
+ {
+ var content = this._doc["paths"][path][operationType]["requestBody"]["content"];
+
+ var value = content[contentType]["schema"];
+
+ value.Should().NotBeNull();
+ value.Value("type").Should().Be(propertyType);
+ value.Value("format").Should().Be(propertyFormat);
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-double", "post", "200")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponse(string path, string operationType, string responseCode)
+ {
+ var responses = this._doc["paths"][path][operationType]["responses"];
+
+ responses[responseCode].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-double", "post", "200", "application/json")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentType(string path, string operationType, string responseCode, string contentType)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ content[contentType].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-double", "post", "200", "application/json", "doubleObjectModel")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentTypeSchema(string path, string operationType, string responseCode, string contentType, string reference)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ var @ref = content[contentType]["schema"]["$ref"];
+
+ @ref.Value().Should().Be($"#/components/schemas/{reference}");
+ }
+
+ [DataTestMethod]
+ [DataRow("doubleObjectModel", "object")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchema(string @ref, string refType)
+ {
+ var schemas = this._doc["components"]["schemas"];
+
+ var schema = schemas[@ref];
+
+ schema.Should().NotBeNull();
+ schema.Value("type").Should().Be(refType);
+ }
+
+ [DataTestMethod]
+ [DataRow("doubleObjectModel", "doubleValue", "number", "double")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaProperty(string @ref, string propertyName, string propertyType, string propertyFormat)
+ {
+ var properties = this._doc["components"]["schemas"][@ref]["properties"];
+
+ var value = properties[propertyName];
+
+ value.Should().NotBeNull();
+ value.Value("type").Should().Be(propertyType);
+ value.Value("format").Should().Be(propertyFormat);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Post_ApplicationJson_String_Tests.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Post_ApplicationJson_String_Tests.cs
new file mode 100644
index 00000000..3addbc6f
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests/Post_ApplicationJson_String_Tests.cs
@@ -0,0 +1,111 @@
+using System.Net.Http;
+using System.Threading.Tasks;
+
+using FluentAssertions;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Document.Tests
+{
+ [TestClass]
+ [TestCategory(Constants.TestCategory)]
+ public class Post_ApplicationJson_String_Tests
+ {
+ private static HttpClient http = new HttpClient();
+
+ private JObject _doc;
+
+ [TestInitialize]
+ public async Task Init()
+ {
+ var json = await http.GetStringAsync(Constants.OpenApiDocEndpoint).ConfigureAwait(false);
+ this._doc = JsonConvert.DeserializeObject(json);
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-string", "post")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationRequestBody(string path, string operationType)
+ {
+ var requestBody = this._doc["paths"][path][operationType]["requestBody"];
+
+ requestBody.Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-string", "post", "text/plain")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationRequestBodyContentType(string path, string operationType, string contentType)
+ {
+ var content = this._doc["paths"][path][operationType]["requestBody"]["content"];
+
+ content[contentType].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-string", "post", "text/plain", "string")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationRequestBodyContentTypeSchema(string path, string operationType, string contentType, string propertyType)
+ {
+ var content = this._doc["paths"][path][operationType]["requestBody"]["content"];
+
+ var value = content[contentType]["schema"];
+
+ value.Should().NotBeNull();
+ value.Value("type").Should().Be(propertyType);
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-string", "post", "200")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponse(string path, string operationType, string responseCode)
+ {
+ var responses = this._doc["paths"][path][operationType]["responses"];
+
+ responses[responseCode].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-string", "post", "200", "application/json")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentType(string path, string operationType, string responseCode, string contentType)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ content[contentType].Should().NotBeNull();
+ }
+
+ [DataTestMethod]
+ [DataRow("/post-applicationjson-string", "post", "200", "application/json", "stringObjectModel")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_OperationResponseContentTypeSchema(string path, string operationType, string responseCode, string contentType, string reference)
+ {
+ var content = this._doc["paths"][path][operationType]["responses"][responseCode]["content"];
+
+ var @ref = content[contentType]["schema"]["$ref"];
+
+ @ref.Value().Should().Be($"#/components/schemas/{reference}");
+ }
+
+ [DataTestMethod]
+ [DataRow("stringObjectModel", "object")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchema(string @ref, string refType)
+ {
+ var schemas = this._doc["components"]["schemas"];
+
+ var schema = schemas[@ref];
+
+ schema.Should().NotBeNull();
+ schema.Value("type").Should().Be(refType);
+ }
+
+ [DataTestMethod]
+ [DataRow("stringObjectModel", "value", "string")]
+ public void Given_OpenApiDocument_Then_It_Should_Return_ComponentSchemaProperty(string @ref, string propertyName, string propertyType)
+ {
+ var properties = this._doc["components"]["schemas"][@ref]["properties"];
+
+ var value = properties[propertyName];
+
+ value.Should().NotBeNull();
+ value.Value("type").Should().Be(propertyType);
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/BooleanParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/BooleanParameterExample.cs
new file mode 100644
index 00000000..09d0acbf
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/BooleanParameterExample.cs
@@ -0,0 +1,16 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class BooleanParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("booleanValue1", true, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("booleanValue2", false, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/ByteArrayParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/ByteArrayParameterExample.cs
new file mode 100644
index 00000000..c9e1acb5
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/ByteArrayParameterExample.cs
@@ -0,0 +1,16 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class ByteArrayParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("byteArrayValue1", new byte[] { 172, 24, 18, 240 }, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("byteArrayValue2", new byte[] { 0xFF, 0x32, 0x11 }, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/DateTimeOffsetParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/DateTimeOffsetParameterExample.cs
new file mode 100644
index 00000000..145126ce
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/DateTimeOffsetParameterExample.cs
@@ -0,0 +1,19 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class DateTimeOffsetParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("dateTimeOffsetValue1", DateTimeOffset.Parse("05/01/2008"), namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("dateTimeOffsetValue2", DateTimeOffset.Parse("11:36 PM"), namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("dateTimeOffsetValue3", DateTimeOffset.Parse("05/01/2008 +1:00"), namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("dateTimeOffsetValue4", DateTimeOffset.Parse("Thu May 01, 2008"), namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/DateTimeParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/DateTimeParameterExample.cs
new file mode 100644
index 00000000..67439cc0
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/DateTimeParameterExample.cs
@@ -0,0 +1,17 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class DateTimeParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("dateTimeValue1", DateTime.Parse("2021-01-01"), namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("dateTimeValue2", DateTime.Parse("2021-01-01T12:34:56Z"), namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/DoubleParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/DoubleParameterExample.cs
new file mode 100644
index 00000000..5fefe9d3
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/DoubleParameterExample.cs
@@ -0,0 +1,16 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class DoubleParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("doubleValue1", 1.1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("doubleValue2", 0.0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/GuidParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/GuidParameterExample.cs
new file mode 100644
index 00000000..1e9127e7
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/GuidParameterExample.cs
@@ -0,0 +1,16 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class GuidParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("guidValue1", new Guid("74be27de-1e4e-49d9-b579-fe0b331d3642"), namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Int16ParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Int16ParameterExample.cs
new file mode 100644
index 00000000..af6e2673
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Int16ParameterExample.cs
@@ -0,0 +1,16 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class Int16ParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("int16Value1", (short)1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("int16Value2", (short)0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Int32ParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Int32ParameterExample.cs
new file mode 100644
index 00000000..474389da
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Int32ParameterExample.cs
@@ -0,0 +1,16 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class Int32ParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("int32Value1", 1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("int32Value2", 0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Int64ParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Int64ParameterExample.cs
new file mode 100644
index 00000000..00fab9cc
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Int64ParameterExample.cs
@@ -0,0 +1,16 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class Int64ParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("int64Value1", (long)1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("int64Value2", (long)0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/SingleParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/SingleParameterExample.cs
new file mode 100644
index 00000000..321d25c2
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/SingleParameterExample.cs
@@ -0,0 +1,16 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class SingleParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("singleValue1", (float)1.1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("singleValue2", (float)0.0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/StringParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/StringParameterExample.cs
new file mode 100644
index 00000000..aa2adbfa
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/StringParameterExample.cs
@@ -0,0 +1,18 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models;
+using Newtonsoft.Json.Serialization;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ class StringParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("stringValue1", "Lorem", namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("stringValue2", "", namingStrategy));
+ return this;
+ }
+ }
+}
+
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Uint16ParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Uint16ParameterExample.cs
new file mode 100644
index 00000000..0576a96d
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Uint16ParameterExample.cs
@@ -0,0 +1,16 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class Uint16ParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("uint16Value1", (ushort)1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("uint16Value2", (ushort)0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Uint32ParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Uint32ParameterExample.cs
new file mode 100644
index 00000000..1c14ad0e
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Uint32ParameterExample.cs
@@ -0,0 +1,16 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class Uint32ParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("uint32Value1", (uint)1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("uint32Value2", (uint)0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Uint64ParameterExample.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Uint64ParameterExample.cs
new file mode 100644
index 00000000..bae99a0a
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Examples/Uint64ParameterExample.cs
@@ -0,0 +1,16 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples
+{
+ public class Uint64ParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("uint64Value1", (ulong)1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("uint64Value2", (ulong)0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_ApplicationJson_BaseObject_HttpTrigger.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_ApplicationJson_BaseObject_HttpTrigger.cs
new file mode 100644
index 00000000..7e9541bc
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_ApplicationJson_BaseObject_HttpTrigger.cs
@@ -0,0 +1,28 @@
+using System.Net;
+using System.Threading.Tasks;
+
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs.Extensions.Http;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models;
+using Microsoft.Extensions.Logging;
+using Microsoft.OpenApi.Models;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp
+{
+ public static class Get_ApplicationJson_BaseObject_HttpTrigger
+ {
+ [FunctionName(nameof(Get_ApplicationJson_BaseObject_HttpTrigger))]
+ [OpenApiOperation(operationId: nameof(Get_ApplicationJson_BaseObject_HttpTrigger.Get_ApplicationJson_BaseObject), tags: new[] { "greeting" })]
+ [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(HasBaseObjectModel), Description = "The OK response")]
+ public static async Task Get_ApplicationJson_BaseObject(
+ [HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "get-applicationjson-baseobject")] HttpRequest req,
+ ILogger log)
+ {
+ var result = new OkResult();
+
+ return await Task.FromResult(result).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_ApplicationJson_DictionaryObject_HttpTrigger.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_ApplicationJson_DictionaryObject_HttpTrigger.cs
new file mode 100644
index 00000000..52dd52b3
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_ApplicationJson_DictionaryObject_HttpTrigger.cs
@@ -0,0 +1,27 @@
+using System.Net;
+using System.Threading.Tasks;
+
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs.Extensions.Http;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models;
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp
+{
+ public class Get_ApplicationJson_DictionaryObject_HttpTrigger
+ {
+ [FunctionName(nameof(Get_ApplicationJson_DictionaryObject_HttpTrigger))]
+ [OpenApiOperation(operationId: nameof(Get_ApplicationJson_DictionaryObject_HttpTrigger.Get_ApplicationJson_DictionaryObjectType), tags: new[] { "dictionary" })]
+ [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DictionaryObjectModel), Description = "The OK response")]
+ public static async Task Get_ApplicationJson_DictionaryObjectType(
+ [HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "get-applicationjson-dictionary")] HttpRequest req,
+ ILogger log)
+ {
+ var result = new OkResult();
+
+ return await Task.FromResult(result).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_ApplicationJson_GenericAndRecursive_HttpTrigger.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_ApplicationJson_GenericAndRecursive_HttpTrigger.cs
new file mode 100644
index 00000000..d0de1072
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_ApplicationJson_GenericAndRecursive_HttpTrigger.cs
@@ -0,0 +1,27 @@
+using System.Net;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs.Extensions.Http;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models;
+using Microsoft.Extensions.Logging;
+using Microsoft.OpenApi.Models;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp
+{
+ public static class Get_ApplicationJson_GenericAndRecursive_HttpTrigger
+ {
+ [FunctionName(nameof(Get_ApplicationJson_GenericAndRecursive_HttpTrigger))]
+ [OpenApiOperation(operationId: nameof(Get_ApplicationJson_GenericAndRecursive), tags: new[] { "genericAndRecursive" })]
+ [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(GenericAndRecursiveModel), Description = "The OK response")]
+ public static async Task Get_ApplicationJson_GenericAndRecursive(
+ [HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "get-applicationjson-genericandrecursive")] HttpRequest req,
+ ILogger log)
+ {
+ var result = new OkResult();
+
+ return await Task.FromResult(result).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_ApplicationJson_JObject_HttpTrigger.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_ApplicationJson_JObject_HttpTrigger.cs
new file mode 100644
index 00000000..4b4d77d8
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_ApplicationJson_JObject_HttpTrigger.cs
@@ -0,0 +1,28 @@
+using System.Net;
+using System.Threading.Tasks;
+
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs.Extensions.Http;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models;
+using Microsoft.Extensions.Logging;
+using Microsoft.OpenApi.Models;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp
+{
+ public static class Get_ApplicationJson_JObject_HttpTrigger
+ {
+ [FunctionName(nameof(Get_ApplicationJson_JObject_HttpTrigger))]
+ [OpenApiOperation(operationId: nameof(Get_ApplicationJson_JObject_HttpTrigger.Get_ApplicationJson_JObject), tags: new[] { "jObject" })]
+ [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(JObjectModel), Description = "The OK response")]
+ public static async Task Get_ApplicationJson_JObject(
+ [HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "get-applicationjson-jobject")] HttpRequest req,
+ ILogger log)
+ {
+ var result = new OkResult();
+
+ return await Task.FromResult(result).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_Query_ParameterExamples_HttpTrigger.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_Query_ParameterExamples_HttpTrigger.cs
new file mode 100644
index 00000000..8b080a11
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_Query_ParameterExamples_HttpTrigger.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Net;
+using System.Threading.Tasks;
+
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs.Extensions.Http;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples;
+using Microsoft.Extensions.Logging;
+using Microsoft.OpenApi.Models;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp
+{
+ public static class Get_Query_ParameterExamples_HttpTrigger
+ {
+ [FunctionName(nameof(Get_Query_ParameterExamples_HttpTrigger))]
+ [OpenApiOperation(operationId: nameof(Get_Query_ParameterExamples_HttpTrigger.Get_Query_ParameterExamples), tags: new[] { "parameter examples" })]
+ [OpenApiParameter(name: "stringParameter", In = ParameterLocation.Query, Required = true, Example = typeof(StringParameterExample), Type = typeof(string), Description = "The **string** parameter")]
+ [OpenApiParameter(name: "int16Parameter", In = ParameterLocation.Query, Required = true, Example = typeof(Int16ParameterExample), Type = typeof(short), Description = "The **int16** parameter")]
+ [OpenApiParameter(name: "int32Parameter", In = ParameterLocation.Query, Required = true, Example = typeof(Int32ParameterExample), Type = typeof(int), Description = "The **int32** parameter")]
+ [OpenApiParameter(name: "int64Parameter", In = ParameterLocation.Query, Required = true, Example = typeof(Int64ParameterExample), Type = typeof(long), Description = "The **int64** parameter")]
+ [OpenApiParameter(name: "uint16Parameter", In = ParameterLocation.Query, Required = true, Example = typeof(Uint16ParameterExample), Type = typeof(ushort), Description = "The **uint16** parameter")]
+ [OpenApiParameter(name: "uint32Parameter", In = ParameterLocation.Query, Required = true, Example = typeof(Uint32ParameterExample), Type = typeof(uint), Description = "The **uint32** parameter")]
+ [OpenApiParameter(name: "uint64Parameter", In = ParameterLocation.Query, Required = true, Example = typeof(Uint64ParameterExample), Type = typeof(ulong), Description = "The **uint64** parameter")]
+ [OpenApiParameter(name: "singleParameter", In = ParameterLocation.Query, Required = true, Example = typeof(SingleParameterExample), Type = typeof(float), Description = "The **single** parameter")]
+ [OpenApiParameter(name: "doubleParameter", In = ParameterLocation.Query, Required = true, Example = typeof(DoubleParameterExample), Type = typeof(double), Description = "The **double** parameter")]
+ [OpenApiParameter(name: "dateTimeParameter", In = ParameterLocation.Query, Required = true, Example = typeof(DateTimeParameterExample), Type = typeof(DateTime), Description = "The **dateTime** parameter")]
+ [OpenApiParameter(name: "dateTimeOffsetParameter", In = ParameterLocation.Query, Required = true, Example = typeof(DateTimeOffsetParameterExample), Type = typeof(DateTimeOffset), Description = "The **dateTimeOffset** parameter")]
+ [OpenApiParameter(name: "booleanParameter", In = ParameterLocation.Query, Required = true, Example = typeof(BooleanParameterExample), Type = typeof(bool), Description = "The **boolean** parameter")]
+ [OpenApiParameter(name: "guidParameter", In = ParameterLocation.Query, Required = true, Example = typeof(GuidParameterExample), Type = typeof(Guid), Description = "The **guid** parameter")]
+ [OpenApiParameter(name: "byteArrayParameter", In = ParameterLocation.Query, Required = true, Example = typeof(ByteArrayParameterExample), Type = typeof(byte[]), Description = "The **byteArray** parameter")]
+ [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "text/plain", bodyType: typeof(string), Description = "The OK response")]
+ public static async Task Get_Query_ParameterExamples(
+ [HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "get-query-parameter-examples")] HttpRequest req,
+ ILogger log)
+ {
+ var result = new OkResult();
+
+ return await Task.FromResult(result).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_Query_TextPlain_String_HttpTrigger.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_Query_TextPlain_String_HttpTrigger.cs
index e4306770..e92509e1 100644
--- a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_Query_TextPlain_String_HttpTrigger.cs
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Get_Query_TextPlain_String_HttpTrigger.cs
@@ -5,6 +5,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Examples;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/ArrayObjectModel.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/ArrayObjectModel.cs
index be327bd8..f4b6c083 100644
--- a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/ArrayObjectModel.cs
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/ArrayObjectModel.cs
@@ -12,5 +12,7 @@ public class ArrayObjectModel
public IReadOnlyCollection DecimalValue { get; set; }
public HashSet StringObjectValue { get; set; }
public ISet Int32ObjectValue { get; set; }
+
+ public IEnumerable StringObjectModel { get; set; }
}
}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/BooleanObjectModel.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/BooleanObjectModel.cs
new file mode 100644
index 00000000..7f03b754
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/BooleanObjectModel.cs
@@ -0,0 +1,7 @@
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models
+{
+ public class BooleanObjectModel
+ {
+ public bool BooleanValue { get; set; }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/DecimalTypeObjectModel.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/DecimalTypeObjectModel.cs
new file mode 100644
index 00000000..f97f0ede
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/DecimalTypeObjectModel.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models
+{
+ public class DecimalTypeObjectModel
+ {
+ public decimal DecimalValue { get; set; }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/DictionaryObjectModel.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/DictionaryObjectModel.cs
new file mode 100644
index 00000000..8acfaee6
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/DictionaryObjectModel.cs
@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models
+{
+ public class DictionaryObjectModel
+ {
+ public Dictionary BoolValue { get; set; }
+ public IDictionary StringValue { get; set; }
+ public IReadOnlyDictionary FloatValue { get; set; }
+ public KeyValuePair Int32ObjectValue { get; set; }
+
+ public IDictionary StringObjectModel { get; set; }
+
+ public Dictionary IntArrayValue { get; set; }
+ public Dictionary StringArrayValue { get; set; }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/DoubleObjectModel.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/DoubleObjectModel.cs
new file mode 100644
index 00000000..3bc36e84
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/DoubleObjectModel.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models
+{
+ public class DoubleObjectModel
+ {
+ public double DoubleValue { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/GenericAndRecursiveModel.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/GenericAndRecursiveModel.cs
new file mode 100644
index 00000000..af7288ae
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/GenericAndRecursiveModel.cs
@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models
+{
+ public class GenericAndRecursiveModel
+ {
+ public List Children { get; set; }
+
+ public Dictionary Children2 { get; set; }
+
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/HasBaseObjectModel.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/HasBaseObjectModel.cs
new file mode 100644
index 00000000..e5db5ad0
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/HasBaseObjectModel.cs
@@ -0,0 +1,14 @@
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models
+{
+ public class HasBaseObjectSubModel
+ {
+ public object SubObjectValue{ get; set; }
+ }
+
+ public class HasBaseObjectModel
+ {
+ public object ObjectValue { get; set; }
+ public int NonObjectValue { get; set; }
+ public HasBaseObjectSubModel SubModel { get; set; }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/JObjectModel.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/JObjectModel.cs
new file mode 100644
index 00000000..84b852ab
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Models/JObjectModel.cs
@@ -0,0 +1,13 @@
+using Newtonsoft.Json.Linq;
+using System.Collections.Generic;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models
+{
+ public class JObjectModel
+ {
+ public JObject JObjectValue { get; set; }
+ public JToken JTokenValue { get; set; }
+ public JArray JArrayValue { get; set; }
+
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Post_ApplicationJson_Boolean_HttpTrigger.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Post_ApplicationJson_Boolean_HttpTrigger.cs
new file mode 100644
index 00000000..ac9b46e2
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Post_ApplicationJson_Boolean_HttpTrigger.cs
@@ -0,0 +1,29 @@
+using System.Net;
+using System.Threading.Tasks;
+
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs.Extensions.Http;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models;
+using Microsoft.Extensions.Logging;
+using Microsoft.OpenApi.Models;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp
+{
+ public static class Post_ApplicationJson_Boolean_HttpTrigger
+ {
+ [FunctionName(nameof(Post_ApplicationJson_Boolean_HttpTrigger))]
+ [OpenApiOperation(operationId: nameof(Post_ApplicationJson_Boolean_HttpTrigger.Post_ApplicationJson_Boolean), tags: new[] { "boolean" })]
+ [OpenApiRequestBody(contentType: "text/plain", bodyType: typeof(bool), Required = true, Description = "The OK response")]
+ [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(BooleanObjectModel), Description = "The OK response")]
+ public static async Task Post_ApplicationJson_Boolean(
+ [HttpTrigger(AuthorizationLevel.Anonymous, "POST", Route = "post-applicationjson-boolean")] HttpRequest req,
+ ILogger log)
+ {
+ var result = new OkResult();
+
+ return await Task.FromResult(result).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Post_ApplicationJson_DecimalType_HttpTrigger.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Post_ApplicationJson_DecimalType_HttpTrigger.cs
new file mode 100644
index 00000000..91b10538
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Post_ApplicationJson_DecimalType_HttpTrigger.cs
@@ -0,0 +1,29 @@
+using System.Net;
+using System.Threading.Tasks;
+
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs.Extensions.Http;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models;
+using Microsoft.Extensions.Logging;
+
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp
+{
+ public class Post_ApplicationJson_DecimalType_HttpTrigger
+ {
+ [FunctionName(nameof(Post_ApplicationJson_DecimalType_HttpTrigger))]
+ [OpenApiOperation(operationId: nameof(Post_ApplicationJson_DecimalType_HttpTrigger.Post_ApplicationJson_DecimalType), tags: new[] { "demical" })]
+ [OpenApiRequestBody(contentType: "text/plain", bodyType: typeof(double), Required = true, Description = "The OK response")]
+ [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DecimalTypeObjectModel), Description = "The OK response")]
+ public static async Task Post_ApplicationJson_DecimalType(
+ [HttpTrigger(AuthorizationLevel.Anonymous, "POST", Route = "post-applicationjson-decimal")] HttpRequest req,
+ ILogger log)
+ {
+ var result = new OkResult();
+
+ return await Task.FromResult(result).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Post_ApplicationJson_Double_HttpTrigger.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Post_ApplicationJson_Double_HttpTrigger.cs
new file mode 100644
index 00000000..c76ab65e
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Post_ApplicationJson_Double_HttpTrigger.cs
@@ -0,0 +1,29 @@
+using System.Net;
+using System.Threading.Tasks;
+
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs.Extensions.Http;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models;
+using Microsoft.Extensions.Logging;
+using Microsoft.OpenApi.Models;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp
+{
+ public static class Post_ApplicationJson_DoubleObject_HttpTrigger
+ {
+ [FunctionName(nameof(Post_ApplicationJson_DoubleObject_HttpTrigger))]
+ [OpenApiOperation(operationId: nameof(Post_ApplicationJson_DoubleObject_HttpTrigger.Post_ApplicationJson_DoubleObject), tags: new[] { "double" })]
+ [OpenApiRequestBody(contentType: "text/plain", bodyType: typeof(double), Required = true, Description = "The OK response")]
+ [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(DoubleObjectModel), Description = "The OK response")]
+ public static async Task Post_ApplicationJson_DoubleObject(
+ [HttpTrigger(AuthorizationLevel.Anonymous, "POST", Route = "post-applicationjson-double")] HttpRequest req,
+ ILogger log)
+ {
+ var result = new OkResult();
+
+ return await Task.FromResult(result).ConfigureAwait(false);
+ }
+ }
+}
\ No newline at end of file
diff --git a/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Post_ApplicationJson_String_HttpTrigger.cs b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Post_ApplicationJson_String_HttpTrigger.cs
new file mode 100644
index 00000000..4c287e80
--- /dev/null
+++ b/test-integration/Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp/Post_ApplicationJson_String_HttpTrigger.cs
@@ -0,0 +1,29 @@
+using System.Net;
+using System.Threading.Tasks;
+
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Azure.WebJobs.Extensions.Http;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp.Models;
+using Microsoft.Extensions.Logging;
+using Microsoft.OpenApi.Models;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.TestApp
+{
+ public static class Post_ApplicationJson_String_HttpTrigger
+ {
+ [FunctionName(nameof(Post_ApplicationJson_String_HttpTrigger))]
+ [OpenApiOperation(operationId: nameof(Post_ApplicationJson_String_HttpTrigger.Post_ApplicationJson_String), tags: new[] { "string" })]
+ [OpenApiRequestBody(contentType: "text/plain", bodyType: typeof(string), Required = true, Description = "The OK response")]
+ [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(StringObjectModel), Description = "The OK response")]
+ public static async Task Post_ApplicationJson_String(
+ [HttpTrigger(AuthorizationLevel.Anonymous, "POST", Route = "post-applicationjson-string")] HttpRequest req,
+ ILogger log)
+ {
+ var result = new OkResult();
+
+ return await Task.FromResult(result).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/DocumentTests.cs b/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/DocumentTests.cs
index f0abba59..05201e06 100644
--- a/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/DocumentTests.cs
+++ b/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/DocumentTests.cs
@@ -72,7 +72,7 @@ public void Given_Info_When_AddMetadata_Invoked_Then_It_Should_Return_Result(str
[DataRow("https", "localhost", 47071, null)]
[DataRow("https", "localhost", 47071, "")]
[DataRow("https", "localhost", 47071, "api")]
- public void Given_NoOptions_When_AddMetadata_Invoked_Then_It_Should_Return_Result(string scheme, string host, int port, string routePrefix)
+ public void Given_NoOptions_When_AddServer_Invoked_Then_It_Should_Return_Result(string scheme, string host, int port, string routePrefix)
{
var helper = new Mock();
var doc = new Document(helper.Object);
@@ -104,7 +104,7 @@ public void Given_NoOptions_When_AddMetadata_Invoked_Then_It_Should_Return_Resul
[DataRow("https", "localhost", 47071, null)]
[DataRow("https", "localhost", 47071, "")]
[DataRow("https", "localhost", 47071, "api")]
- public void Given_EmptyOptions_When_AddMetadata_Invoked_Then_It_Should_Return_Result(string scheme, string host, int port, string routePrefix)
+ public void Given_EmptyOptions_When_AddServer_Invoked_Then_It_Should_Return_Result(string scheme, string host, int port, string routePrefix)
{
var helper = new Mock();
var doc = new Document(helper.Object);
@@ -139,7 +139,7 @@ public void Given_EmptyOptions_When_AddMetadata_Invoked_Then_It_Should_Return_Re
[DataRow("https", "localhost", 47071, null, "helloworld")]
[DataRow("https", "localhost", 47071, "", "helloworld")]
[DataRow("https", "localhost", 47071, "api", "helloworld")]
- public void Given_ExtraServers_And_Include_When_AddMetadata_Invoked_Then_It_Should_Return_Result(string scheme, string host, int port, string routePrefix, string server)
+ public void Given_ExtraServers_And_Include_When_AddServer_Invoked_Then_It_Should_Return_Result(string scheme, string host, int port, string routePrefix, string server)
{
var helper = new Mock();
var doc = new Document(helper.Object);
@@ -177,7 +177,7 @@ public void Given_ExtraServers_And_Include_When_AddMetadata_Invoked_Then_It_Shou
[DataRow("https", "localhost", 47071, null, "helloworld")]
[DataRow("https", "localhost", 47071, "", "helloworld")]
[DataRow("https", "localhost", 47071, "api", "helloworld")]
- public void Given_ExtraServers_And_Exclude_When_AddMetadata_Invoked_Then_It_Should_Return_Result(string scheme, string host, int port, string routePrefix, string server)
+ public void Given_ExtraServers_And_Exclude_When_AddServer_Invoked_Then_It_Should_Return_Result(string scheme, string host, int port, string routePrefix, string server)
{
var helper = new Mock();
var doc = new Document(helper.Object);
@@ -201,6 +201,109 @@ public void Given_ExtraServers_And_Exclude_When_AddMetadata_Invoked_Then_It_Shou
result.OpenApiDocument.Servers.First().Url.Should().Be(server);
}
+ [DataTestMethod]
+ [DataRow("http", "localhost", "api", "http://localhost/api")]
+ [DataRow("https", "localhost", "api", "https://localhost/api")]
+ [DataRow("http", "localhost:7071", "api", "http://localhost:7071/api")]
+ [DataRow("https", "localhost:47071", "api", "https://localhost:47071/api")]
+ [DataRow("http", "localhost", "", "http://localhost")]
+ [DataRow("https", "localhost", "", "https://localhost")]
+ [DataRow("http", "localhost:7071", "", "http://localhost:7071")]
+ [DataRow("https", "localhost:47071", "", "https://localhost:47071")]
+ [DataRow("http", "localhost", null, "http://localhost")]
+ [DataRow("https", "localhost", null, "https://localhost")]
+ [DataRow("http", "localhost:7071", null, "http://localhost:7071")]
+ [DataRow("https", "localhost:47071", null, "https://localhost:47071")]
+ public void Given_NullOptions_When_AddServer_Invoked_Then_It_Should_Return_BaseUrl(string scheme, string host, string routePrefix, string expected)
+ {
+ var helper = new Mock();
+ var doc = new Document(helper.Object);
+
+ var req = new Mock();
+ req.SetupGet(p => p.Scheme).Returns(scheme);
+
+ var hostString = new HostString(host);
+ req.SetupGet(p => p.Host).Returns(hostString);
+
+ var result = doc.InitialiseDocument()
+ .AddServer(req.Object, routePrefix, null);
+
+ result.OpenApiDocument.Servers.Should().HaveCount(1);
+ result.OpenApiDocument.Servers.First().Url.Should().Be(expected);
+ }
+
+ [DataTestMethod]
+ [DataRow("http", "localhost", "api", true, true, "https://localhost/api")]
+ [DataRow("https", "localhost", "api", true, true, "https://localhost/api")]
+ [DataRow("http", "localhost:7071", "api", true, true, "https://localhost:7071/api")]
+ [DataRow("https", "localhost:47071", "api", true, true, "https://localhost:47071/api")]
+ [DataRow("http", "localhost", "", true, true, "https://localhost")]
+ [DataRow("https", "localhost", "", true, true, "https://localhost")]
+ [DataRow("http", "localhost:7071", "", true, true, "https://localhost:7071")]
+ [DataRow("https", "localhost:47071", "", true, true, "https://localhost:47071")]
+ [DataRow("http", "localhost", null, true, true, "https://localhost")]
+ [DataRow("https", "localhost", null, true, true, "https://localhost")]
+ [DataRow("http", "localhost:7071", null, true, true, "https://localhost:7071")]
+ [DataRow("https", "localhost:47071", null, true, true, "https://localhost:47071")]
+ [DataRow("http", "localhost", "api", true, false, "https://localhost/api")]
+ [DataRow("https", "localhost", "api", true, false, "https://localhost/api")]
+ [DataRow("http", "localhost:7071", "api", true, false, "https://localhost:7071/api")]
+ [DataRow("https", "localhost:47071", "api", true, false, "https://localhost:47071/api")]
+ [DataRow("http", "localhost", "", true, false, "https://localhost")]
+ [DataRow("https", "localhost", "", true, false, "https://localhost")]
+ [DataRow("http", "localhost:7071", "", true, false, "https://localhost:7071")]
+ [DataRow("https", "localhost:47071", "", true, false, "https://localhost:47071")]
+ [DataRow("http", "localhost", null, true, false, "https://localhost")]
+ [DataRow("https", "localhost", null, true, false, "https://localhost")]
+ [DataRow("http", "localhost:7071", null, true, false, "https://localhost:7071")]
+ [DataRow("https", "localhost:47071", null, true, false, "https://localhost:47071")]
+ [DataRow("http", "localhost", "api", false, true, "http://localhost/api")]
+ [DataRow("https", "localhost", "api", false, true, "http://localhost/api")]
+ [DataRow("http", "localhost:7071", "api", false, true, "http://localhost:7071/api")]
+ [DataRow("https", "localhost:47071", "api", false, true, "http://localhost:47071/api")]
+ [DataRow("http", "localhost", "", false, true, "http://localhost")]
+ [DataRow("https", "localhost", "", false, true, "http://localhost")]
+ [DataRow("http", "localhost:7071", "", false, true, "http://localhost:7071")]
+ [DataRow("https", "localhost:47071", "", false, true, "http://localhost:47071")]
+ [DataRow("http", "localhost", null, false, true, "http://localhost")]
+ [DataRow("https", "localhost", null, false, true, "http://localhost")]
+ [DataRow("http", "localhost:7071", null, false, true, "http://localhost:7071")]
+ [DataRow("https", "localhost:47071", null, false, true, "http://localhost:47071")]
+ [DataRow("http", "localhost", "api", false, false, "http://localhost/api")]
+ [DataRow("https", "localhost", "api", false, false, "https://localhost/api")]
+ [DataRow("http", "localhost:7071", "api", false, false, "http://localhost:7071/api")]
+ [DataRow("https", "localhost:47071", "api", false, false, "https://localhost:47071/api")]
+ [DataRow("http", "localhost", "", false, false, "http://localhost")]
+ [DataRow("https", "localhost", "", false, false, "https://localhost")]
+ [DataRow("http", "localhost:7071", "", false, false, "http://localhost:7071")]
+ [DataRow("https", "localhost:47071", "", false, false, "https://localhost:47071")]
+ [DataRow("http", "localhost", null, false, false, "http://localhost")]
+ [DataRow("https", "localhost", null, false, false, "https://localhost")]
+ [DataRow("http", "localhost:7071", null, false, false, "http://localhost:7071")]
+ [DataRow("https", "localhost:47071", null, false, false, "https://localhost:47071")]
+ public void Given_Options_When_AddServer_Invoked_Then_It_Should_Return_BaseUrl(string scheme, string host, string routePrefix, bool forceHttps, bool forceHttp, string expected)
+ {
+ var helper = new Mock();
+ var doc = new Document(helper.Object);
+
+ var req = new Mock();
+ req.SetupGet(p => p.Scheme).Returns(scheme);
+
+ var hostString = new HostString(host);
+ req.SetupGet(p => p.Host).Returns(hostString);
+
+ var options = new Mock();
+ options.SetupGet(p => p.ForceHttps).Returns(forceHttps);
+ options.SetupGet(p => p.ForceHttp).Returns(forceHttp);
+ options.SetupGet(p => p.Servers).Returns(new List());
+
+ var result = doc.InitialiseDocument()
+ .AddServer(req.Object, routePrefix, options.Object);
+
+ result.OpenApiDocument.Servers.Should().HaveCount(1);
+ result.OpenApiDocument.Servers.First().Url.Should().Be(expected);
+ }
+
[TestMethod]
public void Given_Null_When_AddNamingStrategy_Invoked_Then_It_Should_Throw_Exception()
{
diff --git a/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/Extensions/HttpRequestDataExtensionsTests.cs b/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/Extensions/HttpRequestDataExtensionsTests.cs
index a06c5965..70d90d73 100644
--- a/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/Extensions/HttpRequestDataExtensionsTests.cs
+++ b/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/Extensions/HttpRequestDataExtensionsTests.cs
@@ -1,7 +1,8 @@
using System;
-
+using System.Collections.Generic;
+using System.Linq;
using FluentAssertions;
-
+using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Extensions;
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests.Fakes;
using Microsoft.Azure.Functions.Worker.Http;
@@ -14,6 +15,128 @@ namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests.Extensions
[TestClass]
public class HttpRequestDataExtensionsTests
{
+ [TestMethod]
+ public void Given_Null_When_Headers_Invoked_Then_It_Should_Throw_Exception()
+ {
+ Action action = () => OpenApiHttpRequestDataExtensions.Headers(null);
+
+ action.Should().Throw();
+ }
+
+ [TestMethod]
+ public void Given_NullHeader_When_Headers_Invoked_Then_It_Should_Return_Result()
+ {
+ var context = new Mock();
+
+ var baseHost = "localhost";
+ var uri = Uri.TryCreate($"http://{baseHost}", UriKind.Absolute, out var tried) ? tried : null;
+
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers: null);
+
+ var result = OpenApiHttpRequestDataExtensions.Headers(req);
+
+ result.Count.Should().Be(0);
+ }
+
+ [TestMethod]
+ public void Given_NoHeader_When_Headers_Invoked_Then_It_Should_Return_Result()
+ {
+ var context = new Mock();
+
+ var baseHost = "localhost";
+ var uri = Uri.TryCreate($"http://{baseHost}", UriKind.Absolute, out var tried) ? tried : null;
+
+ var headers = new Dictionary();
+
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers: headers);
+
+ var result = OpenApiHttpRequestDataExtensions.Headers(req);
+
+ result.Count.Should().Be(0);
+ }
+
+ [DataTestMethod]
+ [DataRow("hello=world", "hello")]
+ [DataRow("hello=world&lorem=ipsum", "hello", "lorem")]
+ public void Given_Headers_When_Headers_Invoked_Then_It_Should_Return_Result(string headerstring, params string[] keys)
+ {
+ var context = new Mock();
+
+ var baseHost = "localhost";
+ var uri = Uri.TryCreate($"http://{baseHost}", UriKind.Absolute, out var tried) ? tried : null;
+
+ var kvps = headerstring.Split('&').ToDictionary(p => p.Split('=').First(), p => p.Split('=').Last());
+ var headers = new Dictionary(kvps);
+
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers: headers);
+
+ var result = OpenApiHttpRequestDataExtensions.Headers(req);
+
+ result.Count.Should().Be(keys.Length);
+ result.Keys.Should().Contain(keys);
+ }
+
+ [TestMethod]
+ public void Given_Null_When_Header_Invoked_Then_It_Should_Throw_Exception()
+ {
+ Action action = () => OpenApiHttpRequestDataExtensions.Header(null, null);
+
+ action.Should().Throw();
+ }
+
+ [DataTestMethod]
+ [DataRow("hello=world", "hello", "world")]
+ [DataRow("hello=world&lorem=ipsum", "hello", "world")]
+ [DataRow("hello=world&lorem=ipsum", "lorem", "ipsum")]
+ public void Given_Headers_When_Header_Invoked_Then_It_Should_Return_Result(string headerstring, string key, string expected)
+ {
+ var context = new Mock();
+
+ var baseHost = "localhost";
+ var uri = Uri.TryCreate($"http://{baseHost}", UriKind.Absolute, out var tried) ? tried : null;
+
+ var kvps = headerstring.Split('&').ToDictionary(p => p.Split('=').First(), p => p.Split('=').Last());
+ var headers = new Dictionary(kvps);
+
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers: headers);
+
+ var result = (string) OpenApiHttpRequestDataExtensions.Header(req, key);
+
+ result.Should().Be(expected);
+ }
+
+ [TestMethod]
+ public void Given_NullHeader_When_Header_Invoked_Then_It_Should_Return_Result()
+ {
+ var context = new Mock();
+
+ var baseHost = "localhost";
+ var uri = Uri.TryCreate($"http://{baseHost}", UriKind.Absolute, out var tried) ? tried : null;
+
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers: null);
+
+ var result = (string) OpenApiHttpRequestDataExtensions.Header(req, "hello");
+
+ result.Should().BeNull();
+ }
+
+ [TestMethod]
+ public void Given_NoHeader_When_Header_Invoked_Then_It_Should_Return_Result()
+ {
+ var context = new Mock();
+
+ var baseHost = "localhost";
+ var uri = Uri.TryCreate($"http://{baseHost}", UriKind.Absolute, out var tried) ? tried : null;
+
+ var headers = new Dictionary();
+
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers: headers);
+
+ var result = (string) OpenApiHttpRequestDataExtensions.Query(req, "hello");
+
+ result.Should().BeNull();
+ }
+
[TestMethod]
public void Given_Null_When_Queries_Invoked_Then_It_Should_Throw_Exception()
{
@@ -30,7 +153,7 @@ public void Given_NullQuerystring_When_Queries_Invoked_Then_It_Should_Return_Res
var baseHost = "localhost";
var uri = Uri.TryCreate($"http://{baseHost}", UriKind.Absolute, out var tried) ? tried : null;
- var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, body: null);
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers: null);
var result = OpenApiHttpRequestDataExtensions.Queries(req);
@@ -47,7 +170,7 @@ public void Given_NoQuerystring_When_Queries_Invoked_Then_It_Should_Return_Resul
var baseHost = "localhost";
var uri = Uri.TryCreate($"http://{baseHost}?{querystring}", UriKind.Absolute, out var tried) ? tried : null;
- var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, body: null);
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers: null);
var result = OpenApiHttpRequestDataExtensions.Queries(req);
@@ -64,7 +187,7 @@ public void Given_Querystring_When_Queries_Invoked_Then_It_Should_Return_Result(
var baseHost = "localhost";
var uri = Uri.TryCreate($"http://{baseHost}?{querystring}", UriKind.Absolute, out var tried) ? tried : null;
- var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, body: null);
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers: null);
var result = OpenApiHttpRequestDataExtensions.Queries(req);
@@ -91,7 +214,7 @@ public void Given_Querystring_When_Query_Invoked_Then_It_Should_Return_Result(st
var baseHost = "localhost";
var uri = Uri.TryCreate($"http://{baseHost}?{querystring}", UriKind.Absolute, out var tried) ? tried : null;
- var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, body: null);
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers: null);
var result = (string) OpenApiHttpRequestDataExtensions.Query(req, key);
@@ -106,7 +229,7 @@ public void Given_NullQuerystring_When_Query_Invoked_Then_It_Should_Return_Resul
var baseHost = "localhost";
var uri = Uri.TryCreate($"http://{baseHost}", UriKind.Absolute, out var tried) ? tried : null;
- var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, body: null);
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers: null);
var result = (string) OpenApiHttpRequestDataExtensions.Query(req, "hello");
@@ -123,7 +246,7 @@ public void Given_NoQuerystring_When_Query_Invoked_Then_It_Should_Return_Result(
var baseHost = "localhost";
var uri = Uri.TryCreate($"http://{baseHost}?{querystring}", UriKind.Absolute, out var tried) ? tried : null;
- var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, body: null);
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers: null);
var result = (string) OpenApiHttpRequestDataExtensions.Query(req, "hello");
diff --git a/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/Fakes/FakeHttpRequestData.cs b/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/Fakes/FakeHttpRequestData.cs
index 21469656..c20532dd 100644
--- a/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/Fakes/FakeHttpRequestData.cs
+++ b/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/Fakes/FakeHttpRequestData.cs
@@ -2,22 +2,24 @@
using System.Collections.Generic;
using System.IO;
using System.Security.Claims;
-
+using Microsoft.AspNetCore.Http;
using Microsoft.Azure.Functions.Worker.Http;
+using Microsoft.Extensions.Primitives;
namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests.Fakes
{
public class FakeHttpRequestData : HttpRequestData
{
- public FakeHttpRequestData(FunctionContext functionContext, Uri uri, Stream body) : base(functionContext)
+ public FakeHttpRequestData(FunctionContext functionContext, Uri uri, Dictionary headers, Stream body = null) : base(functionContext)
{
this.Url = uri;
this.Body = body;
+ this.Headers = new HttpHeadersCollection(headers ?? new Dictionary());
}
public override Stream Body { get; }
- public override HttpHeadersCollection Headers => throw new NotImplementedException();
+ public override HttpHeadersCollection Headers { get; }
public override IReadOnlyCollection Cookies => throw new NotImplementedException();
diff --git a/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/Fakes/FakeOpenApiHttpTriggerAuthorization.cs b/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/Fakes/FakeOpenApiHttpTriggerAuthorization.cs
new file mode 100644
index 00000000..77ac1522
--- /dev/null
+++ b/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/Fakes/FakeOpenApiHttpTriggerAuthorization.cs
@@ -0,0 +1,27 @@
+using System.Net;
+using System.Threading.Tasks;
+
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
+
+namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests.Fakes
+{
+ public class FakeOpenApiHttpTriggerAuthorization : DefaultOpenApiHttpTriggerAuthorization
+ {
+ public const HttpStatusCode StatusCode = HttpStatusCode.Redirect;
+ public const string ContentType = "text/html";
+ public const string Payload = "";
+
+ public override async Task AuthorizeAsync(IHttpRequestDataObject req)
+ {
+ var result = new OpenApiAuthorizationResult()
+ {
+ StatusCode = StatusCode,
+ ContentType = ContentType,
+ Payload = Payload,
+ };
+
+ return await Task.FromResult(result).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/HttpRequestObjectTests.cs b/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/HttpRequestObjectTests.cs
index 01e255ed..9618629a 100644
--- a/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/HttpRequestObjectTests.cs
+++ b/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/HttpRequestObjectTests.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
@@ -36,15 +37,19 @@ public void Given_Parameter_When_Instantiated_Then_It_Should_Return_Result(strin
var ports = new[] { 80, 443 };
var baseHost = $"{hostname}{(ports.Contains(port) ? string.Empty : $":{port}")}";
var uri = Uri.TryCreate($"{scheme}://{baseHost}?{key}={value}", UriKind.Absolute, out var tried) ? tried : null;
+
+ var headers = new Dictionary() { { key, value } };
+
var bytes = Encoding.UTF8.GetBytes(payload);
var body = new MemoryStream(bytes);
- var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, body);
+ var req = (HttpRequestData) new FakeHttpRequestData(context.Object, uri, headers, body);
var result = new HttpRequestObject(req);
result.Scheme.Should().Be(scheme);
result.Host.Value.Should().Be(baseHost);
+ result.Headers.Should().ContainKey(key);
result.Query.Should().ContainKey(key);
((string) result.Query[key]).Should().Be(value);
(new StreamReader(result.Body)).ReadToEnd().Should().Be(payload);
diff --git a/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/OpenApiHttpTriggerContextTests.cs b/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/OpenApiHttpTriggerContextTests.cs
index 3df8352f..3c6e1376 100644
--- a/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/OpenApiHttpTriggerContextTests.cs
+++ b/test/Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests/OpenApiHttpTriggerContextTests.cs
@@ -7,10 +7,14 @@
using FluentAssertions;
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Functions;
+using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests.Fakes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
using Microsoft.OpenApi;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+
namespace Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Tests
{
[TestClass]
@@ -71,7 +75,6 @@ public async Task Given_Type_When_Initiated_Then_It_Should_Return_PackageAssembl
.PackageAssembly;
assembly.DefinedTypes.Should().Contain(typeof(ISwaggerUI).GetTypeInfo());
- assembly.DefinedTypes.Should().NotContain(typeof(IOpenApiHttpTriggerContext).GetTypeInfo());
}
[TestMethod]
@@ -113,6 +116,21 @@ public async Task Given_Type_When_Initiated_Then_It_Should_Return_HttpSettings()
}
+ [TestMethod]
+ public async Task Given_Authorization_When_AuthorizeAsync_Invoked_Then_It_Should_Return_Result()
+ {
+ var location = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName;
+ var req = new Mock();
+ var context = new OpenApiHttpTriggerContext();
+
+ var result = await context.SetApplicationAssemblyAsync(location, false)
+ .AuthorizeAsync(req.Object);
+
+ result.StatusCode.Should().Be(FakeOpenApiHttpTriggerAuthorization.StatusCode);
+ result.ContentType.Should().Be(FakeOpenApiHttpTriggerAuthorization.ContentType);
+ result.Payload.Should().Be(FakeOpenApiHttpTriggerAuthorization.Payload);
+ }
+
[DataTestMethod]
[DataRow("v2", OpenApiSpecVersion.OpenApi2_0)]
[DataRow("v3", OpenApiSpecVersion.OpenApi3_0)]
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.Tests/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.Tests.csproj b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.Tests/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.Tests.csproj
index e52fe24f..e89f5cf1 100644
--- a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.Tests/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.Tests.csproj
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.Tests/Microsoft.Azure.WebJobs.Extensions.OpenApi.CLI.Tests.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.1;netcoreapp3.1;net5.0
+ netcoreapp3.1
false
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeAliasCollectionModel.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeAliasCollectionModel.cs
new file mode 100644
index 00000000..826f708f
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeAliasCollectionModel.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeAliasCollectionModel
+ {
+ [JsonRequired]
+ public string @String { get; set; }
+
+ public ICollection FakeAliasSubModel { get; set; }
+ public ICollection FakeSubModel { get; set; }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeAliasDictionaryModel.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeAliasDictionaryModel.cs
new file mode 100644
index 00000000..6805b6ef
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeAliasDictionaryModel.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeAliasDictionaryModel
+ {
+ [JsonRequired]
+ public string @String { get; set; }
+
+ public IDictionary FakeAliasSubModel { get; set; }
+ public IDictionary FakeSubModel { get; set; }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeAliasSubModel.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeAliasSubModel.cs
new file mode 100644
index 00000000..f9af0e33
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeAliasSubModel.cs
@@ -0,0 +1,13 @@
+using Newtonsoft.Json;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeAliasSubModel
+ {
+ [JsonRequired]
+ public string @String { get; set; }
+
+ public FakeSubModel FakeSubModel { get; set; }
+ public FakeDummyModel FakeDummyModel { get; set; }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeBooleanParameterExample.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeBooleanParameterExample.cs
new file mode 100644
index 00000000..fa46849b
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeBooleanParameterExample.cs
@@ -0,0 +1,19 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeBooleanParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("booleanValue1", true, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("booleanValue2", false, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeByteArrayParameterExample.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeByteArrayParameterExample.cs
new file mode 100644
index 00000000..aa0dc895
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeByteArrayParameterExample.cs
@@ -0,0 +1,19 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeByteArrayParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("byteArrayValue1", new byte[] { 172, 24, 18, 240 }, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("byteArrayValue2", new byte[] { 0xFF, 0x32, 0x11 }, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeClassModel.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeClassModel.cs
index a0f9cb9d..4bfa3781 100644
--- a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeClassModel.cs
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeClassModel.cs
@@ -1,8 +1,11 @@
+using System.Collections.Generic;
+
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
{
public class FakeClassModel
{
public int Number { get; set; }
public string Text { get; set; }
+ public List Children { get; set; }
}
}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeDateTimeOffsetParameterExample.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeDateTimeOffsetParameterExample.cs
new file mode 100644
index 00000000..527a9e0b
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeDateTimeOffsetParameterExample.cs
@@ -0,0 +1,19 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeDateTimeOffsetParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("dateTimeOffsetValue1", DateTimeOffset.Parse("05/01/2008"), namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("dateTimeOffsetValue2", DateTimeOffset.Parse("11:36 PM"), namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("dateTimeOffsetValue3", DateTimeOffset.Parse("05/01/2008 +1:00"), namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("dateTimeOffsetValue4", DateTimeOffset.Parse("Thu May 01, 2008"), namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeDateTimeParameterExample.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeDateTimeParameterExample.cs
new file mode 100644
index 00000000..fed49681
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeDateTimeParameterExample.cs
@@ -0,0 +1,19 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeDateTimeParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("dateTimeValue1", DateTime.Parse("2021-01-01"), namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("dateTimeValue2", DateTime.Parse("2021-01-01T12:34:56Z"), namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeDoubleParameterExample.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeDoubleParameterExample.cs
new file mode 100644
index 00000000..a0dd7aee
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeDoubleParameterExample.cs
@@ -0,0 +1,19 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeDoubleParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("doubleValue1", 1.1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("doubleValue2", 0.0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeDummyModel.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeDummyModel.cs
new file mode 100644
index 00000000..5b6c11b5
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeDummyModel.cs
@@ -0,0 +1,6 @@
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeDummyModel
+ {
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeExample.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeExample.cs
index b585f466..627b9683 100644
--- a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeExample.cs
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeExample.cs
@@ -2,6 +2,7 @@
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
using Newtonsoft.Json.Serialization;
+using System;
namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
{
@@ -12,7 +13,6 @@ public override IOpenApiExample Build(NamingStrategy namingStrat
this.Examples.Add(OpenApiExampleResolver.Resolve("first", new FakeClassModel() { Number = 1, Text = "Hello World" }, namingStrategy));
this.Examples.Add(OpenApiExampleResolver.Resolve("second", "this is summary", new FakeClassModel() { Number = 3, Text = "Lorem Ipsum" }, namingStrategy));
this.Examples.Add(OpenApiExampleResolver.Resolve("third", "this is summary", "this is description", new FakeClassModel() { Number = 2, Text = "Hello Ipsum" }, namingStrategy));
-
return this;
}
}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeGuidParameterExample.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeGuidParameterExample.cs
new file mode 100644
index 00000000..55673f38
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeGuidParameterExample.cs
@@ -0,0 +1,16 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeGuidParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("guidValue1", new Guid("74be27de-1e4e-49d9-b579-fe0b331d3642"), namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeInt16ParameterExample.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeInt16ParameterExample.cs
new file mode 100644
index 00000000..805e1a28
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeInt16ParameterExample.cs
@@ -0,0 +1,19 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeInt16ParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("int16Value1", (short)1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("int16Value2", (short)0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeInt32ParameterExample.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeInt32ParameterExample.cs
new file mode 100644
index 00000000..562a817d
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeInt32ParameterExample.cs
@@ -0,0 +1,19 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeInt32ParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("int32Value1", 1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("int32Value2", 0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeInt64ParameterExample.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeInt64ParameterExample.cs
new file mode 100644
index 00000000..9d4c526a
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeInt64ParameterExample.cs
@@ -0,0 +1,19 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeInt64ParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("int64Value1", (long)1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("int64Value2", (long)0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeModel.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeModel.cs
index 5cddbdaf..aa7b1b27 100644
--- a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeModel.cs
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeModel.cs
@@ -25,6 +25,8 @@ public class FakeModel
[JsonProperty]
public string FakePropertyNoAnnotation { get; set; }
+ public object FakeObject { get; set; }
+
///
/// Gets or sets the nullable int value.
///
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeSingleParameterExample.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeSingleParameterExample.cs
new file mode 100644
index 00000000..aa53e713
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeSingleParameterExample.cs
@@ -0,0 +1,19 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeSingleParameterExample : OpenApiExample
+ {
+ public override IOpenApiExample Build(NamingStrategy namingStrategy = null)
+ {
+ this.Examples.Add(OpenApiExampleResolver.Resolve("singleValue1", (float)1.1, namingStrategy));
+ this.Examples.Add(OpenApiExampleResolver.Resolve("singleValue2", (float)0.0, namingStrategy));
+ return this;
+ }
+ }
+}
diff --git a/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeStringParameterExample.cs b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeStringParameterExample.cs
new file mode 100644
index 00000000..229abd68
--- /dev/null
+++ b/test/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes/FakeStringParameterExample.cs
@@ -0,0 +1,19 @@
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
+using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Resolvers;
+using Newtonsoft.Json.Serialization;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Tests.Fakes
+{
+ public class FakeStringParameterExample : OpenApiExample