From 84a42fd691a75b61128748ed0609cdebc2cf648d Mon Sep 17 00:00:00 2001 From: AndeyLapkoMobiDev Date: Tue, 9 Aug 2022 12:18:10 +0300 Subject: [PATCH 1/3] Keep track of the subAcceptors that have been applied and do not run multiple times for the same type. --- .../Visitors/ObjectTypeVisitor.cs | 46 +++++++++---------- .../Visitors/RecursiveObjectTypeVisitor.cs | 37 +++++++++------ 2 files changed, 46 insertions(+), 37 deletions(-) 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 b0fad9fc..8dd5779b 100644 --- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs +++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs @@ -20,6 +20,8 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors /// public class ObjectTypeVisitor : TypeVisitor { + private readonly Dictionary visitedTypes = new Dictionary(); + private readonly HashSet _noVisitableTypes = new HashSet { typeof(Guid), @@ -118,7 +120,25 @@ public override void Visit(IAcceptor acceptor, KeyValuePair type, .Where(p => !p.ExistsCustomAttribute()) .ToDictionary(p => p.GetJsonPropertyName(namingStrategy), p => p); - this.ProcessProperties(instance, name, properties, namingStrategy); + // Get subAcceptor + OpenApiSchemaAcceptor subAcceptor; + if (!this.visitedTypes.ContainsKey(type.Value)) + { + subAcceptor = new OpenApiSchemaAcceptor + { + Properties = properties, + RootSchemas = instance.RootSchemas, + Schemas = new Dictionary(), + }; + this.visitedTypes.Add(type.Value, subAcceptor); + subAcceptor.Accept(this.VisitorCollection, namingStrategy); + } + else + { + subAcceptor = this.visitedTypes[type.Value]; + } + + this.ProcessProperties(instance, subAcceptor, name, properties, namingStrategy); // Adds the reference. var reference = new OpenApiReference() @@ -172,19 +192,8 @@ public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrat return this.PayloadVisit(dataType: "object", dataFormat: null); } - private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaName, Dictionary properties, NamingStrategy namingStrategy) + private void ProcessProperties(IOpenApiSchemaAcceptor instance, IOpenApiSchemaAcceptor subAcceptor, string schemaName, Dictionary properties, NamingStrategy namingStrategy) { - var schemas = new Dictionary(); - - var subAcceptor = new OpenApiSchemaAcceptor() - { - Properties = properties, - RootSchemas = instance.RootSchemas, - Schemas = schemas, - }; - - subAcceptor.Accept(this.VisitorCollection, namingStrategy); - // Add required properties to schema. var jsonPropertyAttributes = properties.Where(p => !p.Value.GetCustomAttribute(inherit: false).IsNullOrDefault()) .Select(p => new KeyValuePair(p.Key, p.Value.GetCustomAttribute(inherit: false))) @@ -239,17 +248,6 @@ private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaNam instance.RootSchemas.Add(schema.Key, schema.Value); } - - // Removes title of each property. - var subSchemas = instance.Schemas[schemaName].Properties; - subSchemas = subSchemas.Select(p => - { - p.Value.Title = null; - return new KeyValuePair(p.Key, p.Value); - }) - .ToDictionary(p => p.Key, p => p.Value); - - instance.Schemas[schemaName].Properties = subSchemas; } private IOpenApiAny GetExample(Type type, NamingStrategy namingStrategy = null) 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 d245d0c8..4085d3c9 100644 --- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/RecursiveObjectTypeVisitor.cs +++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/RecursiveObjectTypeVisitor.cs @@ -18,6 +18,8 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors /// public class RecursiveObjectTypeVisitor : TypeVisitor { + private readonly Dictionary visitedTypes = new Dictionary(); + private readonly HashSet _noAddedKeys = new HashSet { "OBJECT", @@ -76,6 +78,8 @@ public override bool IsVisitable(Type type) /// public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) { + Console.WriteLine($"Recu {type.Value.FullName}"); + var title = namingStrategy.GetPropertyName(type.Value.Name, hasSpecifiedName: false); var name = this.Visit(acceptor, name: type.Key, title: title, dataType: "object", dataFormat: null, attributes: attributes); @@ -102,7 +106,25 @@ public override void Visit(IAcceptor acceptor, KeyValuePair type, .Where(p => p.PropertyType != type.Value) .ToDictionary(p => p.GetJsonPropertyName(namingStrategy), p => p); - this.ProcessProperties(instance, name, properties, namingStrategy); + // Get subAcceptor + OpenApiSchemaAcceptor subAcceptor; + if (!this.visitedTypes.ContainsKey(type.Value)) + { + subAcceptor = new OpenApiSchemaAcceptor + { + Properties = properties, + RootSchemas = instance.RootSchemas, + Schemas = new Dictionary(), + }; + this.visitedTypes.Add(type.Value, subAcceptor); + subAcceptor.Accept(this.VisitorCollection, namingStrategy); + } + else + { + subAcceptor = this.visitedTypes[type.Value]; + } + + this.ProcessProperties(instance, subAcceptor, name, properties, namingStrategy); // Processes recursive properties var recursiveProperties = type.Value @@ -175,19 +197,8 @@ public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrat return this.PayloadVisit(dataType: "object", dataFormat: null); } - private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaName, Dictionary properties, NamingStrategy namingStrategy) + private void ProcessProperties(IOpenApiSchemaAcceptor instance, IOpenApiSchemaAcceptor subAcceptor, string schemaName, Dictionary properties, NamingStrategy namingStrategy) { - var schemas = new Dictionary(); - - var subAcceptor = new OpenApiSchemaAcceptor() - { - Properties = properties, - RootSchemas = instance.RootSchemas, - Schemas = schemas, - }; - - subAcceptor.Accept(this.VisitorCollection, namingStrategy); - // Add required properties to schema. var jsonPropertyAttributes = properties.Where(p => !p.Value.GetCustomAttribute(inherit: false).IsNullOrDefault()) .Select(p => new KeyValuePair(p.Key, p.Value.GetCustomAttribute(inherit: false))) From ddacb7312093bbb2af2810ecabc6a49cb171fe83 Mon Sep 17 00:00:00 2001 From: AndeyLapkoMobiDev Date: Tue, 9 Aug 2022 14:55:53 +0300 Subject: [PATCH 2/3] Reverted RecursiveObjectTypeVisitor --- .../Visitors/RecursiveObjectTypeVisitor.cs | 37 +++++++------------ 1 file changed, 13 insertions(+), 24 deletions(-) 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 4085d3c9..d245d0c8 100644 --- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/RecursiveObjectTypeVisitor.cs +++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/RecursiveObjectTypeVisitor.cs @@ -18,8 +18,6 @@ namespace Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Visitors /// public class RecursiveObjectTypeVisitor : TypeVisitor { - private readonly Dictionary visitedTypes = new Dictionary(); - private readonly HashSet _noAddedKeys = new HashSet { "OBJECT", @@ -78,8 +76,6 @@ public override bool IsVisitable(Type type) /// public override void Visit(IAcceptor acceptor, KeyValuePair type, NamingStrategy namingStrategy, params Attribute[] attributes) { - Console.WriteLine($"Recu {type.Value.FullName}"); - var title = namingStrategy.GetPropertyName(type.Value.Name, hasSpecifiedName: false); var name = this.Visit(acceptor, name: type.Key, title: title, dataType: "object", dataFormat: null, attributes: attributes); @@ -106,25 +102,7 @@ public override void Visit(IAcceptor acceptor, KeyValuePair type, .Where(p => p.PropertyType != type.Value) .ToDictionary(p => p.GetJsonPropertyName(namingStrategy), p => p); - // Get subAcceptor - OpenApiSchemaAcceptor subAcceptor; - if (!this.visitedTypes.ContainsKey(type.Value)) - { - subAcceptor = new OpenApiSchemaAcceptor - { - Properties = properties, - RootSchemas = instance.RootSchemas, - Schemas = new Dictionary(), - }; - this.visitedTypes.Add(type.Value, subAcceptor); - subAcceptor.Accept(this.VisitorCollection, namingStrategy); - } - else - { - subAcceptor = this.visitedTypes[type.Value]; - } - - this.ProcessProperties(instance, subAcceptor, name, properties, namingStrategy); + this.ProcessProperties(instance, name, properties, namingStrategy); // Processes recursive properties var recursiveProperties = type.Value @@ -197,8 +175,19 @@ public override OpenApiSchema PayloadVisit(Type type, NamingStrategy namingStrat return this.PayloadVisit(dataType: "object", dataFormat: null); } - private void ProcessProperties(IOpenApiSchemaAcceptor instance, IOpenApiSchemaAcceptor subAcceptor, string schemaName, Dictionary properties, NamingStrategy namingStrategy) + private void ProcessProperties(IOpenApiSchemaAcceptor instance, string schemaName, Dictionary properties, NamingStrategy namingStrategy) { + var schemas = new Dictionary(); + + var subAcceptor = new OpenApiSchemaAcceptor() + { + Properties = properties, + RootSchemas = instance.RootSchemas, + Schemas = schemas, + }; + + subAcceptor.Accept(this.VisitorCollection, namingStrategy); + // Add required properties to schema. var jsonPropertyAttributes = properties.Where(p => !p.Value.GetCustomAttribute(inherit: false).IsNullOrDefault()) .Select(p => new KeyValuePair(p.Key, p.Value.GetCustomAttribute(inherit: false))) From ac9a5662a65db07af5f12126d9a3b15706a59c9f Mon Sep 17 00:00:00 2001 From: AndeyLapkoMobiDev Date: Fri, 26 Aug 2022 17:43:42 +0300 Subject: [PATCH 3/3] Fixed integration tests --- .../Visitors/ObjectTypeVisitor.cs | 1 + 1 file changed, 1 insertion(+) 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 8dd5779b..515e96fb 100644 --- a/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs +++ b/src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Visitors/ObjectTypeVisitor.cs @@ -235,6 +235,7 @@ private void ProcessProperties(IOpenApiSchemaAcceptor instance, IOpenApiSchemaAc var schemasToBeAdded = subAcceptor.Schemas .Where(p => !instance.Schemas.Keys.Contains(p.Key)) .Where(p => p.Value.IsOpenApiSchemaObject()) + .Where(p => !string.IsNullOrEmpty(p.Value.Title)) .GroupBy(p => p.Value.Title) .Select(p => p.First()) .ToDictionary(p => p.Value.Title, p => p.Value);