Skip to content

Commit

Permalink
working on multilevel schema
Browse files Browse the repository at this point in the history
  • Loading branch information
chidozieononiwu committed Jun 13, 2023
1 parent aee696e commit bb313b5
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ public class SchemaCache
public Dictionary<string, Dictionary<string, Schema>> Cache;
public Dictionary<string, Schema> ResolvedCache;
public Dictionary<string, Dictionary<string, Parameter>> ParametersCache;
public Dictionary<string, Dictionary<string, Response>> ResponsesCache;

public SchemaCache()
{
this.Cache = new Dictionary<string, Dictionary<string, Schema>>();
this.ResolvedCache = new Dictionary<string, Schema>();
this.ParametersCache = new Dictionary<string, Dictionary<string, Parameter>>();
this.ResponsesCache = new Dictionary<string, Dictionary<string, Response>>();
}

public void AddSchema(string swaggerFilePath, string key, Schema value)
Expand All @@ -41,6 +43,18 @@ public void AddParameter(string swaggerFilePath, string key, Parameter parameter
parameterCache.TryAdd(key, parameter);
}

public void AddResponse(string swaggerFilePath, string key, Response response)
{
this.ResponsesCache.TryGetValue(swaggerFilePath, out var responseCache);
if (responseCache == null)
{
responseCache = new Dictionary<string, Response>();
this.ResponsesCache.TryAdd(swaggerFilePath, responseCache);
}

responseCache.TryAdd(key, response);
}

public static string GetRefKey(string Ref)
{
var key = Ref.Split("/").Last();
Expand All @@ -66,13 +80,13 @@ private Schema GetSchemaFromResolvedCache(string Ref, string currentSwaggerFileP
return resolvedSchema;
}

private Schema GetSchemaFromCache(string Ref, string currentSwaggerFilePath)
public Schema GetSchemaFromCache(string Ref, string currentSwaggerFilePath, bool resolveSwaggerPath = true)
{
// try get from resolved cache.


var referenceSwaggerFilePath = Utils.GetReferencedSwaggerFile(Ref, currentSwaggerFilePath);

var referenceSwaggerFilePath = currentSwaggerFilePath;
if (resolveSwaggerPath)
{
referenceSwaggerFilePath = Utils.GetReferencedSwaggerFile(Ref, currentSwaggerFilePath);
}

this.Cache.TryGetValue(referenceSwaggerFilePath, out var swaggerSchema);
if (swaggerSchema == null)
Expand All @@ -91,11 +105,14 @@ private Schema GetSchemaFromCache(string Ref, string currentSwaggerFilePath)
return ret;
}

public Parameter GetParameterFromCache(string Ref, string currentSwaggerFilePath, ref string referenceSwaggerFilePath)
public Parameter GetParameterFromCache(string Ref, string currentSwaggerFilePath, bool resolveSwaggerPath = true)
{
// try get from resolved cache.
referenceSwaggerFilePath = Utils.GetReferencedSwaggerFile(Ref, currentSwaggerFilePath);

var referenceSwaggerFilePath = currentSwaggerFilePath;
if (resolveSwaggerPath)
{
referenceSwaggerFilePath = Utils.GetReferencedSwaggerFile(Ref, currentSwaggerFilePath);
}

this.ParametersCache.TryGetValue(referenceSwaggerFilePath, out var parameterCache);
if (parameterCache == null)
{
Expand All @@ -113,12 +130,36 @@ public Parameter GetParameterFromCache(string Ref, string currentSwaggerFilePath
return ret;
}

public Response GetResponseFromCache(string Ref, string currentSwaggerFilePath, bool resolveSwaggerPath = true)
{
var referenceSwaggerFilePath = currentSwaggerFilePath;
if (resolveSwaggerPath)
{
referenceSwaggerFilePath = Utils.GetReferencedSwaggerFile(Ref, currentSwaggerFilePath);
}

this.ResponsesCache.TryGetValue(referenceSwaggerFilePath, out var responseCache);
if (responseCache == null)
{
return null;
}

var key = GetRefKey(Ref);
responseCache.TryGetValue(key, out var ret);

if (ret == null)
{
throw new Exception($"Reference not found. $ref: {Ref}");
}

return ret;
}

public Parameter GetResolvedParameter(Parameter parameter, string currentSwaggerFilePath)
{
if (parameter.IsRefObject())
{
var resolvedFromPath = String.Empty;
return this.GetParameterFromCache(parameter.@ref, currentSwaggerFilePath, ref resolvedFromPath);
return this.GetParameterFromCache(parameter.@ref, currentSwaggerFilePath);
}

return parameter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
Expand Down Expand Up @@ -78,42 +77,41 @@ public static async Task<SwaggerApiViewSpec> GenerateSwaggerApiView(Swagger swag
foreach (var parameter in operation.parameters)
{
var param = parameter;
var resolvedFromPath = swaggerFilePath;
var referenceSwaggerFilePath = swaggerFilePath;

// Resolve Parameter from multilevel reference
if (parameter.IsRefObject())
{
param = (Parameter)swaggerSpec.ResolveRefObj(parameter.@ref);
if (param == null)
{
param = (Parameter)schemaCache.GetParameterFromCache(parameter.@ref, swaggerFilePath, ref resolvedFromPath);
param = (Parameter)schemaCache.GetParameterFromCache(parameter.@ref, swaggerFilePath);
}
}

if (param == null)
{
var referencePath = parameter.@ref;
do
if (param == null)
{
if (!Path.IsPathFullyQualified(referencePath))
var referencePath = parameter.@ref;
do
{
var referenceSwaggerFilePath = Utils.GetReferencedSwaggerFile(referencePath, swaggerFilePath);
var referenceSwaggerSpec = await SwaggerDeserializer.Deserialize(referenceSwaggerFilePath);
referenceSwaggerSpec.swaggerFilePath = Path.GetFullPath(referenceSwaggerFilePath);
AddDefinitionsToCache(referenceSwaggerSpec, referenceSwaggerFilePath, schemaCache);
param = schemaCache.GetParameterFromCache(referencePath, swaggerFilePath, ref resolvedFromPath);
}
else
{
var referenceSwaggerSpec = await SwaggerDeserializer.Deserialize(referencePath);
referenceSwaggerSpec.swaggerFilePath = Path.GetFullPath(referencePath);
AddDefinitionsToCache(referenceSwaggerSpec, referencePath, schemaCache);
param = schemaCache.GetParameterFromCache(referencePath, swaggerFilePath, ref resolvedFromPath);
}
if (!Path.IsPathFullyQualified(referencePath))
{
referenceSwaggerFilePath = Utils.GetReferencedSwaggerFile(referencePath, referenceSwaggerFilePath);
var referenceSwaggerSpec = await SwaggerDeserializer.Deserialize(referenceSwaggerFilePath);
AddDefinitionsToCache(referenceSwaggerSpec, referenceSwaggerFilePath, schemaCache);
param = schemaCache.GetParameterFromCache(referencePath, referenceSwaggerFilePath, false);
}
else
{
var referenceSwaggerSpec = await SwaggerDeserializer.Deserialize(referencePath);
AddDefinitionsToCache(referenceSwaggerSpec, referencePath, schemaCache);
param = schemaCache.GetParameterFromCache(referencePath, referencePath, false);
}

if (param != null && param.IsRefObject())
referencePath = param.@ref;
if (param != null && param.IsRefObject())
referencePath = param.@ref;
}
while (param != null && param.IsRefObject());
}
while(param != null && param.IsRefObject());
}

var swaggerApiViewOperationParameter = new SwaggerApiViewParameter
Expand All @@ -122,7 +120,7 @@ public static async Task<SwaggerApiViewSpec> GenerateSwaggerApiView(Swagger swag
@in = param.@in,
description = param.description,
required = param.required,
schema = schemaCache.GetResolvedSchema(param.schema, resolvedFromPath),
schema = schemaCache.GetResolvedSchema(param.schema, referenceSwaggerFilePath),
format = param.format,
@ref = param.@ref,
type = param.type
Expand All @@ -149,18 +147,69 @@ public static async Task<SwaggerApiViewSpec> GenerateSwaggerApiView(Swagger swag

foreach (var (statusCode, response) in operation.responses)
{
var schema = response.schema;
var currentSwaggerFilePath = swaggerFilePath;
var resp = response;
var referenceSwaggerFilePath = swaggerFilePath;

if (response.IsRefObject())
{
resp = (Response)swaggerSpec.ResolveRefObj(response.@ref);
if (resp == null)
{
resp = (Response)schemaCache.GetResponseFromCache(response.@ref, swaggerFilePath);
}

if (resp == null)
{
var referencePath = response.@ref;
do
{
if (!Path.IsPathFullyQualified(referencePath))
{
referenceSwaggerFilePath = Utils.GetReferencedSwaggerFile(referencePath, swaggerFilePath);
var referenceSwaggerSpec = await SwaggerDeserializer.Deserialize(referenceSwaggerFilePath);
AddDefinitionsToCache(referenceSwaggerSpec, referenceSwaggerFilePath, schemaCache);
resp = schemaCache.GetResponseFromCache(referencePath, referenceSwaggerFilePath, false);
}
else
{
var referenceSwaggerSpec = await SwaggerDeserializer.Deserialize(referencePath);
AddDefinitionsToCache(referenceSwaggerSpec, referencePath, schemaCache);
resp = schemaCache.GetResponseFromCache(referencePath, referencePath, false);
}

if (resp != null && resp.IsRefObject())
referencePath = resp.@ref;
}
while (resp != null && resp.IsRefObject());
}
}

var schema = resp.schema;

//Resolve ref obj for response schema.

if (response.schema != null)
if (schema != null)
{
// The initial refChain is the root level schema.
// There are some scenarios that the property of the root level schema is a ref to the root level itself (circular reference).
// Like "errorDetail" schema in common types.
LinkedList<string> refChain = new LinkedList<string>();
schema = schemaCache.GetResolvedSchema(schema, currentSwaggerFilePath, refChain);
if (schema.IsRefObject())
{
var referencePath = schema.@ref;
do
{
referenceSwaggerFilePath = Utils.GetReferencedSwaggerFile(referencePath, referenceSwaggerFilePath);
var referenceSwaggerSpec = await SwaggerDeserializer.Deserialize(referenceSwaggerFilePath);
AddDefinitionsToCache(referenceSwaggerSpec, referenceSwaggerFilePath, schemaCache);
schema = schemaCache.GetSchemaFromCache(referencePath, referenceSwaggerFilePath, false);
}
while (schema != null && schema.IsRefObject());
}
else
{
LinkedList<string> refChain = new LinkedList<string>();
// The initial refChain is the root level schema.
// There are some scenarios that the property of the root level schema is a ref to the root level itself (circular reference).
// Like "errorDetail" schema in common types.
schema = schemaCache.GetResolvedSchema(schema, referenceSwaggerFilePath, refChain);
}
}

var headers = response.headers ?? new Dictionary<string, Header>();
Expand Down Expand Up @@ -229,6 +278,17 @@ public static void AddDefinitionsToCache(Swagger swaggerSpec, string swaggerFile
}
}
}

if (swaggerSpec.responses != null)
{
foreach (var response in swaggerSpec.responses)
{
if (!schemaCache.ResponsesCache.ContainsKey(response.Key))
{
schemaCache.AddResponse(fullPath, response.Key, response.Value);
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,6 @@ public CodeFileToken[] TokenSerialize(SerializeContext context)
ret.Add(TokenSerializer.NewLine());
}

//if (this.xMsLongRunningOperation)
//{
// ret.Add(TokenSerializer.NavigableToken("x-ms-long-running-operation", CodeFileTokenKind.Keyword, context.IteratorPath.CurrentNextPath("x-ms-long-running-operation")));
// ret.Add(TokenSerializer.Colon());
// ret.Add(new CodeFileToken("true", CodeFileTokenKind.Literal));
// ret.Add(TokenSerializer.NewLine());
//}
//
//if (this.xMSPageable != null)
//{
// ret.Add(TokenSerializer.NavigableToken("x-ms-pageable", CodeFileTokenKind.Keyword, context.IteratorPath.CurrentNextPath("x-ms-pageable")));
// ret.Add(TokenSerializer.Colon());
// ret.Add(new CodeFileToken(this.xMSPageable.nextLinkName, CodeFileTokenKind.Literal));
// ret.Add(TokenSerializer.NewLine());
//}

// new line for `Parameters` section.
ret.Add(TokenSerializer.NewLine());

Expand Down

0 comments on commit bb313b5

Please sign in to comment.