Skip to content

Commit

Permalink
Merge branch 'master' into bug/4672-fix-thread-safety-in-json-object-…
Browse files Browse the repository at this point in the history
…mapper
  • Loading branch information
frantuma authored Sep 23, 2024
2 parents 68162f7 + 5fc5d0e commit 3d27828
Show file tree
Hide file tree
Showing 60 changed files with 1,525 additions and 111 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ The OpenAPI Specification has undergone several revisions since initial creation

Swagger core Version | Release Date | OpenAPI Spec compatibility | Notes | Status
------------------------- | ------------ | -------------------------- | ----- | ----
2.2.22 (**current stable**)| 2024-05-15 | 3.x | [tag v2.2.22](https://github.com/swagger-api/swagger-core/tree/v2.2.22) | Supported
2.2.23 (**current stable**)| 2024-08-28 | 3.x | [tag v2.2.23](https://github.com/swagger-api/swagger-core/tree/v2.2.23) | Supported
2.2.22 | 2024-05-15 | 3.x | [tag v2.2.22](https://github.com/swagger-api/swagger-core/tree/v2.2.22) | Supported
2.2.21 | 2024-03-20 | 3.x | [tag v2.2.21](https://github.com/swagger-api/swagger-core/tree/v2.2.21) | Supported
2.2.20 | 2023-12-19 | 3.x | [tag v2.2.20](https://github.com/swagger-api/swagger-core/tree/v2.2.20) | Supported
2.2.19 | 2023-11-10 | 3.x | [tag v2.2.19](https://github.com/swagger-api/swagger-core/tree/v2.2.19) | Supported
Expand Down Expand Up @@ -115,7 +116,7 @@ You need the following installed and available in your $PATH:
* Jackson 2.4.5 or greater


### To build from source (currently 2.2.23-SNAPSHOT)
### To build from source (currently 2.2.24-SNAPSHOT)
```
# first time building locally
mvn -N
Expand Down
2 changes: 1 addition & 1 deletion modules/swagger-annotations/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<parent>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-project</artifactId>
<version>2.2.23-SNAPSHOT</version>
<version>2.2.24-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down
2 changes: 1 addition & 1 deletion modules/swagger-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<parent>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-project</artifactId>
<version>2.2.23-SNAPSHOT</version>
<version>2.2.24-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ public ModelConverters(boolean openapi31) {
}
}

public ModelConverters(boolean openapi31, Schema.SchemaResolution schemaResolution) {
converters = new CopyOnWriteArrayList<>();
if (openapi31) {
converters.add(new ModelResolver(Json31.mapper()).openapi31(true).schemaResolution(schemaResolution));
} else {
converters.add(new ModelResolver(Json.mapper()).schemaResolution(schemaResolution));
}
}

public Set<String> getSkippedPackages() {
return skippedPackages;
}
Expand All @@ -61,6 +70,30 @@ public static ModelConverters getInstance(boolean openapi31) {
return SINGLETON;
}

public static void reset() {
synchronized (ModelConverters.class) {
SINGLETON = null;
SINGLETON31 = null;
}
}

public static ModelConverters getInstance(boolean openapi31, Schema.SchemaResolution schemaResolution) {
synchronized (ModelConverters.class) {
if (openapi31) {
if (SINGLETON31 == null) {
SINGLETON31 = new ModelConverters(openapi31, Schema.SchemaResolution.DEFAULT);
init(SINGLETON31);
}
return SINGLETON31;
}
if (SINGLETON == null) {
SINGLETON = new ModelConverters(openapi31, schemaResolution);
init(SINGLETON);
}
return SINGLETON;
}
}

private static void init(ModelConverters converter) {
converter.addPackageToSkip("java.lang");
converter.addPackageToSkip("groovy.lang");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public OpenAPI filter(OpenAPI openAPI, OpenAPISpecFilter filter, Map<String, Lis

if (filteredOpenAPI.getWebhooks() != null) {
for (String resourcePath : filteredOpenAPI.getWebhooks().keySet()) {
PathItem pathItem = filteredOpenAPI.getPaths().get(resourcePath);
PathItem pathItem = filteredOpenAPI.getWebhooks().get(resourcePath);

PathItem filteredPathItem = filterPathItem(filter, pathItem, resourcePath, params, cookies, headers);
PathItem clonedPathItem = cloneFilteredPathItem(filter,filteredPathItem, resourcePath, params, cookies, headers, allowedTags, filteredTags);
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -587,24 +587,46 @@ public static Optional<Schema> getSchemaFromAnnotation(
boolean openapi31,
Schema existingSchema,
ModelConverterContext context) {
return getSchemaFromAnnotation(schema, components, jsonViewAnnotation, openapi31, existingSchema, Schema.SchemaResolution.DEFAULT, null);
}
public static Optional<Schema> getSchemaFromAnnotation(
io.swagger.v3.oas.annotations.media.Schema schema,
Components components,
JsonView jsonViewAnnotation,
boolean openapi31,
Schema existingSchema,
Schema.SchemaResolution schemaResolution,
ModelConverterContext context) {
if (schema == null || !hasSchemaAnnotation(schema)) {
if (existingSchema == null || !openapi31) {
if (existingSchema == null || (!openapi31 && Schema.SchemaResolution.DEFAULT.equals(schemaResolution))) {
return Optional.empty();
} else if (existingSchema != null && openapi31) {
} else if (existingSchema != null && (openapi31 || Schema.SchemaResolution.INLINE.equals(schemaResolution))) {
return Optional.of(existingSchema);
}
}
Schema schemaObject = null;
if (!openapi31) {
if (existingSchema != null) {
return Optional.of(existingSchema);
if (!Schema.SchemaResolution.DEFAULT.equals(schemaResolution)) {
schemaObject = existingSchema;
} else {
return Optional.of(existingSchema);
}
}
if (schema.oneOf().length > 0 ||
schema.allOf().length > 0 ||
schema.anyOf().length > 0) {
schemaObject = new ComposedSchema();
} else {
schemaObject = new Schema();
if (Schema.SchemaResolution.DEFAULT.equals(schemaResolution)) {
if (schema != null && (schema.oneOf().length > 0 ||
schema.allOf().length > 0 ||
schema.anyOf().length > 0)) {
schemaObject = new ComposedSchema();
} else {
schemaObject = new Schema();
}
} else if (Schema.SchemaResolution.ALL_OF.equals(schemaResolution)) {
if (existingSchema == null) {
schemaObject = new Schema();
} else {
schemaObject = existingSchema;
}
}
} else {
if (existingSchema == null) {
Expand All @@ -613,6 +635,9 @@ public static Optional<Schema> getSchemaFromAnnotation(
schemaObject = existingSchema;
}
}
if (schema == null) {
return Optional.of(schemaObject);
}
if (StringUtils.isNotBlank(schema.description())) {
schemaObject.setDescription(schema.description());
}
Expand Down Expand Up @@ -1956,11 +1981,15 @@ public static void updateAnnotation(Class<?> clazz, io.swagger.v3.oas.annotation

}

public static Annotation mergeSchemaAnnotations(
Annotation[] ctxAnnotations, JavaType type) {
return mergeSchemaAnnotations(ctxAnnotations, type, false);
}
/*
* returns null if no annotations, otherwise either ArraySchema or Schema
*/
public static Annotation mergeSchemaAnnotations(
Annotation[] ctxAnnotations, JavaType type) {
Annotation[] ctxAnnotations, JavaType type, boolean contextWins) {
// get type array and schema
io.swagger.v3.oas.annotations.media.Schema tS = type.getRawClass().getDeclaredAnnotation(io.swagger.v3.oas.annotations.media.Schema.class);
if (!hasSchemaAnnotation(tS)) {
Expand Down Expand Up @@ -2020,6 +2049,9 @@ else if (tS != null && tA == null && cS == null && cA != null) {
}

else if (tA != null && cA != null) {
if (contextWins) {
return mergeArraySchemaAnnotations(tA, cA);
}
return mergeArraySchemaAnnotations(cA, tA);
}

Expand All @@ -2028,6 +2060,9 @@ else if (tS != null && cS == null && cA == null) {
}

else if (tS != null && cS != null) {
if (contextWins) {
return mergeSchemaAnnotations(cS, tS);
}
return mergeSchemaAnnotations(tS, cS);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class OpenAPI30To31 {

public void process(OpenAPI openAPI) {
openAPI.openapi("3.1.0")
.jsonSchemaDialect("https://json-schema.org/draft/2020-12/schema")
.jsonSchemaDialect("https://spec.openapis.org/oas/3.1/dialect/base")
.specVersion(SpecVersion.V31);

removeReservedExtensionsName(openAPI.getExtensions());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ public static Parameter applyAnnotations(
String[] methodTypes,
JsonView jsonViewAnnotation,
boolean openapi31) {
return applyAnnotations(parameter, type, annotations, components, classTypes, methodTypes, jsonViewAnnotation, openapi31, null);
}

public static Parameter applyAnnotations(
Parameter parameter,
Type type,
List<Annotation> annotations,
Components components,
String[] classTypes,
String[] methodTypes,
JsonView jsonViewAnnotation,
boolean openapi31,
Schema.SchemaResolution schemaResolution) {

final AnnotationsHelper helper = new AnnotationsHelper(annotations, type);
if (helper.isContext()) {
Expand All @@ -59,17 +72,57 @@ public static Parameter applyAnnotations(
if (paramSchemaOrArrayAnnotation != null) {
reworkedAnnotations.add(paramSchemaOrArrayAnnotation);
}
io.swagger.v3.oas.annotations.media.Schema ctxSchema = AnnotationsUtils.getSchemaAnnotation(annotations.toArray(new Annotation[0]));
io.swagger.v3.oas.annotations.media.ArraySchema ctxArraySchema = AnnotationsUtils.getArraySchemaAnnotation(annotations.toArray(new Annotation[0]));
Annotation[] ctxAnnotation31 = null;

if (Schema.SchemaResolution.ALL_OF.equals(schemaResolution)) {
List<Annotation> ctxAnnotations31List = new ArrayList<>();
if (annotations != null) {
for (Annotation a : annotations) {
if (
!(a instanceof io.swagger.v3.oas.annotations.media.Schema) &&
!(a instanceof io.swagger.v3.oas.annotations.media.ArraySchema)) {
ctxAnnotations31List.add(a);
}
}
ctxAnnotation31 = ctxAnnotations31List.toArray(new Annotation[ctxAnnotations31List.size()]);
}
}
AnnotatedType annotatedType = new AnnotatedType()
.type(type)
.resolveAsRef(true)
.skipOverride(true)
.jsonViewAnnotation(jsonViewAnnotation)
.ctxAnnotations(reworkedAnnotations.toArray(new Annotation[reworkedAnnotations.size()]));
.jsonViewAnnotation(jsonViewAnnotation);

if (Schema.SchemaResolution.ALL_OF.equals(schemaResolution)) {
annotatedType.ctxAnnotations(ctxAnnotation31);
} else {
annotatedType.ctxAnnotations(reworkedAnnotations.toArray(new Annotation[reworkedAnnotations.size()]));
}

final ResolvedSchema resolvedSchema = ModelConverters.getInstance(openapi31).resolveAsResolvedSchema(annotatedType);
final ResolvedSchema resolvedSchema = ModelConverters.getInstance(openapi31, schemaResolution).resolveAsResolvedSchema(annotatedType);

if (resolvedSchema.schema != null) {
parameter.setSchema(resolvedSchema.schema);
Schema resSchema = AnnotationsUtils.clone(resolvedSchema.schema, openapi31);
Schema ctxSchemaObject = null;
if (Schema.SchemaResolution.ALL_OF.equals(schemaResolution)) {
Optional<Schema> reResolvedSchema = AnnotationsUtils.getSchemaFromAnnotation(ctxSchema, annotatedType.getComponents(), null, openapi31, null, schemaResolution, null);
if (reResolvedSchema.isPresent()) {
ctxSchemaObject = reResolvedSchema.get();
}
reResolvedSchema = AnnotationsUtils.getArraySchema(ctxArraySchema, annotatedType.getComponents(), null, openapi31, ctxSchemaObject);
if (reResolvedSchema.isPresent()) {
ctxSchemaObject = reResolvedSchema.get();
}

}
if (Schema.SchemaResolution.ALL_OF.equals(schemaResolution) && ctxSchemaObject != null) {
resSchema = new Schema()
.addAllOfItem(ctxSchemaObject)
.addAllOfItem(resolvedSchema.schema);
}
parameter.setSchema(resSchema);
}
resolvedSchema.referencedSchemas.forEach(components::addSchemas);

Expand Down
Loading

0 comments on commit 3d27828

Please sign in to comment.