-
Notifications
You must be signed in to change notification settings - Fork 0
/
ExternalizeDocumentFilter.cs
135 lines (120 loc) · 5.73 KB
/
ExternalizeDocumentFilter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// -----------------------------------------------------------------------
// <copyright file="ExternalizeDocumentFilter.cs" company="Microsoft Corp.">
// Copyright (c) Microsoft Corp. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.ArmSwashbuckleStarterKit.Swagger
{
using System.Collections.Generic;
using System.Linq;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
/// <summary>
/// Reference shared definitions where available.
/// </summary>
public class ExternalizeDocumentFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
var operations = swaggerDoc.Paths.Values
.SelectMany(path => path.Operations.Values);
foreach (var operation in operations)
{
var parameters = new List<OpenApiParameter>();
foreach (var parameter in operation.Parameters)
{
parameters.Add(Translate(parameter) ?? parameter);
}
operation.Parameters = parameters;
foreach (var (responseSchemaName, responseSchemas) in operation.Responses
.Select(response => (response.Key, response.Value.Content.FirstOrDefault().Value?.Schema)))
{
this.DeepTranslate(responseSchemaName, responseSchemas);
}
operation.Parameters.Add(new OpenApiParameter
{
Reference = new OpenApiReference { Id = $"parameters/{SwaggerConstants.ApiVersionParameter}", ExternalResource = SwaggerConstants.CommonTypesV3 }
});
}
foreach (var (schemaName, schema) in swaggerDoc.Components.Schemas)
{
this.DeepTranslate(schemaName, schema);
}
}
private static OpenApiReference Translate(OpenApiReference reference)
{
#pragma warning disable IDE0066 // Convert switch statement to expression
switch (reference.Id)
#pragma warning restore IDE0066 // Convert switch statement to expression
{
case "SystemDataModel":
return new OpenApiReference { Id = $"definitions/{SwaggerConstants.SystemData}", ExternalResource = SwaggerConstants.CommonTypesV3 };
case "UserAssignedIdentity":
return new OpenApiReference { Id = $"definitions/{SwaggerConstants.UserAssignedIdentity}", ExternalResource = SwaggerConstants.SwaggerFileName };
case SwaggerConstants.MockResource:
return new OpenApiReference { Id = $"definitions/{SwaggerConstants.Resource}", ExternalResource = SwaggerConstants.CommonTypesV3 };
case SwaggerConstants.MockTrackedResource:
return new OpenApiReference { Id = $"definitions/{SwaggerConstants.TrackedResource}", ExternalResource = SwaggerConstants.CommonTypesV3 };
case "ErrorResponse":
return new OpenApiReference { Id = $"definitions/{SwaggerConstants.ErrorResponse}", ExternalResource = SwaggerConstants.SwaggerFileName };
default:
return null;
}
}
private static OpenApiParameter Translate(OpenApiParameter opParam)
{
if (opParam.In == ParameterLocation.Path && opParam.Schema.Type == "string")
{
switch (opParam.Name)
{
case "subscriptionId":
return new OpenApiParameter
{
Reference = new OpenApiReference { Id = $"parameters/{SwaggerConstants.SubscriptionIdParameter}", ExternalResource = SwaggerConstants.CommonTypesV3 }
};
case "resourceGroupName":
return new OpenApiParameter
{
Reference = new OpenApiReference { Id = $"parameters/{SwaggerConstants.ResourceGroupNameParameter}", ExternalResource = SwaggerConstants.CommonTypesV3 }
};
case "systemData":
return new OpenApiParameter
{
Reference = new OpenApiReference { Id = $"parameters/{SwaggerConstants.SystemData}", ExternalResource = SwaggerConstants.SwaggerFileName }
};
}
}
return null;
}
/// <summary>
/// Recursively drill into a schema and update any references
/// </summary>
private OpenApiSchema DeepTranslate(string schemaName, OpenApiSchema schema)
{
if (schema?.Reference != null)
{
schema.Reference = Translate(schema.Reference) ?? schema.Reference;
if (schema.Reference.Id == $"definitions/{SwaggerConstants.SystemData}")
{
schema.ReadOnly = true;
}
return schema;
}
if (schema?.AllOf?.Count != 0)
{
for (int i = 0; i < schema?.AllOf?.Count; i++)
{
schema.AllOf[i] = this.DeepTranslate(schemaName, schema.AllOf[i]);
}
}
if (schema != null && schema?.Properties?.Count != 0)
{
foreach (var innerSchema in schema?.Properties)
{
schema.Properties[innerSchema.Key] = this.DeepTranslate(innerSchema.Key, innerSchema.Value) ?? innerSchema.Value;
}
}
return schema;
}
}
}