Skip to content

Commit

Permalink
Feature/Azure#139 OpenAPI query string/path parameter examples (Azure…
Browse files Browse the repository at this point in the history
  • Loading branch information
choipureum authored and DoHoon Kim committed Oct 5, 2021
1 parent 8b9d84b commit 0f625c7
Show file tree
Hide file tree
Showing 39 changed files with 1,164 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System;

using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;

using Microsoft.OpenApi.Models;
Expand Down Expand Up @@ -71,5 +71,10 @@ public OpenApiParameterAttribute(string name)
/// Gets or sets the value indicating whether the parameter is deprecated or not.
/// </summary>
public virtual bool Deprecated { get; set; }

/// <summary>
/// Gets or sets the type of the example. It SHOULD be inheriting the <see cref="OpenApiExample{T}"/> class.
/// </summary>
public virtual Type Example { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
using Microsoft.OpenApi.Models;

using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions
{
Expand All @@ -20,8 +23,9 @@ public static class OpenApiParameterAttributeExtensions
/// <param name="attribute"><see cref="OpenApiParameterAttribute"/> instance.</param>
/// <param name="namingStrategy"><see cref="NamingStrategy"/> instance.</param>
/// <param name="collection"><see cref="VisitorCollection"/> instance.</param>
/// <param name="version"><see cref="OpenApiVersionType"/> value.</param>
/// <returns><see cref="OpenApiParameter"/> instance.</returns>
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();

Expand Down Expand Up @@ -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<string, OpenApiExample>)example.Build(namingStrategy).Examples;

parameter.Examples = examples;
if (version == OpenApiVersionType.V2)
{
parameter.Example = examples.First().Value.Value;
}

return parameter;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Microsoft.OpenApi.Any;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core
{
/// <summary>
/// This represents the factory entity to create a openApiExample instance based on the OpenAPI document format.
/// </summary>
public static class OpenApiExampleFactory
{
/// <summary>
/// Creates a new instance of <see cref="IOpenApiAny"/> based on the OpenAPI document format.
/// </summary>
/// <param name="instance">instance.</param>
/// <param name="settings"><see cref="JsonSerializerSettings"/>settings.</param>
/// <returns><see cref="IOpenApiAny"/> instance.</returns>
public static IOpenApiAny CreateInstance<T>(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;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;

using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Extensions;
Expand Down Expand Up @@ -56,16 +57,19 @@ public static class OpenApiExampleResolver
public static KeyValuePair<string, OpenApiExample> Resolve<T>(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<T>(instance,settings);
var example = new OpenApiExample()
{
Summary = summary,
Description = description,
Value = new OpenApiString(JsonConvert.SerializeObject(instance, settings)),
Value = openApiExampleValue,
};
var kvp = new KeyValuePair<string, OpenApiExample>(name, example);

Expand Down
Loading

0 comments on commit 0f625c7

Please sign in to comment.