Skip to content

Commit 5af90da

Browse files
committed
fix: AnnotationUtils processed types cache misses
1 parent 91b2dec commit 5af90da

5 files changed

Lines changed: 40 additions & 20 deletions

File tree

modules/swagger-core/src/main/java/io/swagger/v3/core/converter/ModelConverterContextImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public Schema resolve(AnnotatedType type) {
8787
processedTypes.add(type);
8888
}
8989
if (LOGGER.isDebugEnabled()) {
90-
LOGGER.debug(String.format("resolve %s", type.getType()));
90+
LOGGER.debug(String.format("resolve %s from %s", type.getType(), System.identityHashCode(this)));
9191
}
9292
Iterator<ModelConverter> converters = this.getConverters();
9393
Schema resolved = null;

modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,7 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
817817
property = reResolvedProperty.get();
818818
}
819819

820-
reResolvedProperty = resolveArraySchemaWithCycleGuard(ctxArraySchema, annotatedType, openapi31, property);
820+
reResolvedProperty = resolveArraySchemaWithCycleGuard(ctxArraySchema, annotatedType, openapi31, property, context);
821821
if (reResolvedProperty.isPresent()) {
822822
property = reResolvedProperty.get();
823823
}
@@ -3549,14 +3549,14 @@ private Optional<Schema> resolveArraySchemaWithCycleGuard(
35493549
io.swagger.v3.oas.annotations.media.ArraySchema ctxArraySchema,
35503550
AnnotatedType annotatedType,
35513551
boolean openapi31,
3552-
Schema<?> property) {
3552+
Schema<?> property, ModelConverterContext context) {
35533553
boolean processSchemaImplementation = !typesBeingResolved.contains(annotatedType);
35543554
Optional<Schema> reResolvedProperty;
35553555
if (processSchemaImplementation) {
35563556
typesBeingResolved.add(annotatedType);
35573557
} try {
35583558
reResolvedProperty = AnnotationsUtils.getArraySchema(ctxArraySchema, annotatedType.getComponents(), null,
3559-
openapi31, property, processSchemaImplementation );
3559+
openapi31, property, processSchemaImplementation, context);
35603560
} finally {
35613561
if (processSchemaImplementation) {
35623562
typesBeingResolved.remove(annotatedType);

modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -489,10 +489,16 @@ public static Optional<ArraySchema> getArraySchema(io.swagger.v3.oas.annotations
489489
}
490490
return Optional.empty();
491491
}
492+
492493
public static Optional<Schema> getArraySchema(io.swagger.v3.oas.annotations.media.ArraySchema arraySchema, Components components, JsonView jsonViewAnnotation, boolean openapi31, Schema existingSchema) {
493494
return getArraySchema(arraySchema, components, jsonViewAnnotation, openapi31, existingSchema, false);
494495
}
496+
495497
public static Optional<Schema> getArraySchema(io.swagger.v3.oas.annotations.media.ArraySchema arraySchema, Components components, JsonView jsonViewAnnotation, boolean openapi31, Schema existingSchema, boolean processSchemaImplementation) {
498+
return getArraySchema(arraySchema, components, jsonViewAnnotation, openapi31, existingSchema, processSchemaImplementation, null);
499+
}
500+
501+
public static Optional<Schema> getArraySchema(io.swagger.v3.oas.annotations.media.ArraySchema arraySchema, Components components, JsonView jsonViewAnnotation, boolean openapi31, Schema existingSchema, boolean processSchemaImplementation, ModelConverterContext context) {
496502
if (arraySchema == null || !hasArrayAnnotation(arraySchema)) {
497503
if (existingSchema == null) {
498504
return Optional.empty();
@@ -525,8 +531,8 @@ public static Optional<Schema> getArraySchema(io.swagger.v3.oas.annotations.medi
525531
arraySchemaObject.setMinItems(arraySchema.minItems());
526532
}
527533

528-
getSchemaFromAnnotation(arraySchema.contains(), components, jsonViewAnnotation, openapi31).ifPresent(arraySchemaObject::setContains);
529-
getSchemaFromAnnotation(arraySchema.unevaluatedItems(), components, jsonViewAnnotation, openapi31).ifPresent(arraySchemaObject::setUnevaluatedItems);
534+
getSchemaFromAnnotation(arraySchema.contains(), components, jsonViewAnnotation, openapi31, null, context).ifPresent(arraySchemaObject::setContains);
535+
getSchemaFromAnnotation(arraySchema.unevaluatedItems(), components, jsonViewAnnotation, openapi31, null, context).ifPresent(arraySchemaObject::setUnevaluatedItems);
530536

531537
if (arraySchema.maxContains() > 0) {
532538
arraySchemaObject.setMaxContains(arraySchema.maxContains());
@@ -536,7 +542,7 @@ public static Optional<Schema> getArraySchema(io.swagger.v3.oas.annotations.medi
536542
}
537543
if (arraySchema.prefixItems().length > 0) {
538544
for (io.swagger.v3.oas.annotations.media.Schema prefixItem : arraySchema.prefixItems()) {
539-
getSchemaFromAnnotation(prefixItem, components, jsonViewAnnotation, openapi31).ifPresent(arraySchemaObject::addPrefixItem);
545+
getSchemaFromAnnotation(prefixItem, components, jsonViewAnnotation, openapi31, null, context).ifPresent(arraySchemaObject::addPrefixItem);
540546
}
541547
}
542548

@@ -550,10 +556,10 @@ public static Optional<Schema> getArraySchema(io.swagger.v3.oas.annotations.medi
550556

551557
if (arraySchema.schema() != null) {
552558
if (arraySchema.schema().implementation().equals(Void.class)) {
553-
getSchemaFromAnnotation(arraySchema.schema(), components, jsonViewAnnotation, openapi31, arraySchemaObject.getItems())
559+
getSchemaFromAnnotation(arraySchema.schema(), components, jsonViewAnnotation, openapi31, arraySchemaObject.getItems(), context)
554560
.ifPresent(arraySchemaObject::setItems);
555561
} else if (processSchemaImplementation) {
556-
getSchema(arraySchema.schema(), arraySchema, false, arraySchema.schema().implementation(), components, jsonViewAnnotation, openapi31)
562+
getSchema(arraySchema.schema(), arraySchema, false, arraySchema.schema().implementation(), components, jsonViewAnnotation, openapi31, context)
557563
.ifPresent(arraySchemaObject::setItems);
558564
}
559565
}
@@ -1848,21 +1854,31 @@ public static Optional<? extends Schema> getSchema(io.swagger.v3.oas.annotations
18481854
return getSchema(schemaAnnotation, arrayAnnotation, isArray, schemaImplementation, components, jsonViewAnnotation, false);
18491855

18501856
}
1851-
18521857
public static Optional<? extends Schema> getSchema(io.swagger.v3.oas.annotations.media.Schema schemaAnnotation,
18531858
io.swagger.v3.oas.annotations.media.ArraySchema arrayAnnotation,
18541859
boolean isArray,
18551860
Class<?> schemaImplementation,
18561861
Components components,
18571862
JsonView jsonViewAnnotation,
18581863
boolean openapi31) {
1864+
return getSchema(schemaAnnotation, arrayAnnotation, isArray, schemaImplementation, components, jsonViewAnnotation, openapi31, null);
1865+
}
1866+
1867+
public static Optional<? extends Schema> getSchema(io.swagger.v3.oas.annotations.media.Schema schemaAnnotation,
1868+
io.swagger.v3.oas.annotations.media.ArraySchema arrayAnnotation,
1869+
boolean isArray,
1870+
Class<?> schemaImplementation,
1871+
Components components,
1872+
JsonView jsonViewAnnotation,
1873+
boolean openapi31,
1874+
ModelConverterContext context) {
18591875
if (schemaImplementation != Void.class) {
1860-
Schema schemaObject = resolveSchemaFromType(schemaImplementation, components, jsonViewAnnotation, openapi31, schemaAnnotation, arrayAnnotation, null);
1876+
Schema schemaObject = resolveSchemaFromType(schemaImplementation, components, jsonViewAnnotation, openapi31, schemaAnnotation, arrayAnnotation, context);
18611877
if (StringUtils.isNotBlank(schemaAnnotation.format())) {
18621878
schemaObject.setFormat(schemaAnnotation.format());
18631879
}
18641880
if (isArray) {
1865-
Optional<Schema> arraySchema = AnnotationsUtils.getArraySchema(arrayAnnotation, components, jsonViewAnnotation, openapi31, null);
1881+
Optional<Schema> arraySchema = AnnotationsUtils.getArraySchema(arrayAnnotation, components, jsonViewAnnotation, openapi31, null, false, context);
18661882
if (arraySchema.isPresent()) {
18671883
arraySchema.get().setItems(schemaObject);
18681884
return arraySchema;
@@ -1874,15 +1890,15 @@ public static Optional<? extends Schema> getSchema(io.swagger.v3.oas.annotations
18741890
}
18751891

18761892
} else {
1877-
Optional<Schema> schemaFromAnnotation = AnnotationsUtils.getSchemaFromAnnotation(schemaAnnotation, components, jsonViewAnnotation, openapi31);
1893+
Optional<Schema> schemaFromAnnotation = AnnotationsUtils.getSchemaFromAnnotation(schemaAnnotation, components, jsonViewAnnotation, openapi31, null, context);
18781894
if (schemaFromAnnotation.isPresent()) {
18791895
if (StringUtils.isBlank(schemaFromAnnotation.get().get$ref()) && StringUtils.isBlank(schemaFromAnnotation.get().getType()) && !(schemaFromAnnotation.get() instanceof ComposedSchema)) {
18801896
// default to string
18811897
schemaFromAnnotation.get().setType("string");
18821898
}
18831899
return Optional.of(schemaFromAnnotation.get());
18841900
} else {
1885-
Optional<Schema> arraySchemaFromAnnotation = AnnotationsUtils.getArraySchema(arrayAnnotation, components, jsonViewAnnotation, openapi31, null);
1901+
Optional<Schema> arraySchemaFromAnnotation = AnnotationsUtils.getArraySchema(arrayAnnotation, components, jsonViewAnnotation, openapi31, null, false, context);
18861902
if (arraySchemaFromAnnotation.isPresent()) {
18871903
if (arraySchemaFromAnnotation.get().getItems() != null && StringUtils.isBlank(arraySchemaFromAnnotation.get().getItems().get$ref()) && StringUtils.isBlank(arraySchemaFromAnnotation.get().getItems().getType())) {
18881904
// default to string

modules/swagger-core/src/test/java/io/swagger/v3/core/converting/ComplexPolymorphicModelTimingTest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,28 @@
33
import io.swagger.v3.core.converter.ModelConverters;
44
import io.swagger.v3.core.oas.models.ModelWithArrayOfSubclasses;
55
import io.swagger.v3.core.oas.models.ModelWithManySubtypesAndRecursion;
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
68
import org.testng.annotations.Test;
79

810
import static org.testng.AssertJUnit.assertTrue;
911

1012
public class ComplexPolymorphicModelTimingTest {
13+
private static final Logger LOGGER = LoggerFactory.getLogger(ComplexPolymorphicModelTimingTest.class);
14+
1115
@Test
1216
public void complexPolymorphicModelTimingTest() {
1317
final long durationComplexModel =
1418
measureTiming(1, () -> ModelConverters.getInstance(true).readAllAsResolvedSchema(ModelWithManySubtypesAndRecursion.Holder.class));
15-
System.out.println("Complex model duration: " + durationComplexModel + "ms");
19+
LOGGER.debug("Complex model duration: " + durationComplexModel + "ms");
1620
final long durationSimpleModel =
1721
measureTiming(10, () -> ModelConverters.getInstance(true).readAllAsResolvedSchema(ModelWithArrayOfSubclasses.Holder.class));
18-
System.out.println("Simple model duration: " + durationSimpleModel + "ms");
22+
LOGGER.debug("Simple model duration: " + durationSimpleModel + "ms");
1923

2024
// The complex model shouldn't take 5000 times longer
2125
final float factor = (float) durationComplexModel / durationSimpleModel;
22-
System.out.println("Factor: " + factor);
23-
assertTrue(factor <= 5000);
26+
LOGGER.debug("Factor: " + factor);
27+
assertTrue(factor <= 200);
2428
}
2529

2630
private long measureTiming(int iterations, Runnable runnable) {

modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/ModelWithManySubtypesAndRecursion.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ public class Holder extends SubA {
1919
@DiscriminatorMapping(schema = SubF.class, value = "f"),
2020
@DiscriminatorMapping(schema = SubG.class, value = "g"),
2121
@DiscriminatorMapping(schema = SubH.class, value = "h"),
22-
//@DiscriminatorMapping(schema = SubI.class, value = "i"),
23-
//@DiscriminatorMapping(schema = SubJ.class, value = "j"),
22+
@DiscriminatorMapping(schema = SubI.class, value = "i"),
23+
@DiscriminatorMapping(schema = SubJ.class, value = "j"),
2424
},
2525
description = "Stuff"
2626
)

0 commit comments

Comments
 (0)