-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Description of the problem/issue
When generating an OpenAPI 3.1 spec for a JAX-RS resource, I want to represent a map with an enum key type by specifying the enum class in @Schema(propertyNames).
At the same time, I’m filtering out unreferenced schemas by overriding AbstractSpecFilter#isRemovingUnreferencedDefinitions() to return true.
The problem is that the schema referenced in propertyNames is being incorrectly removed from the final contract.
This occurs under the following combined conditions:
- All enums are resolved as references
- A custom
AbstractSpecFilterimplementation returns true forisRemovingUnreferencedDefinitions()
Affected Version
Using version:
2.2.38
Steps to Reproduce
Reproducer test:
@Test
void testPropertyNames() {
ModelResolver.enumsAsRef = true;
SwaggerConfiguration config = new SwaggerConfiguration().openAPI31(true);
Reader reader = new Reader(config);
OpenAPI openAPI = reader.read(ResourceWithEnumMap.class);
OpenAPISpecFilter filterImpl = new RemoveUnusedSchemasOAS31Filter();
SpecFilter f = new SpecFilter();
openAPI = f.filter(openAPI, filterImpl, null, null, null);
String yaml = "openapi: 3.1.0\n" +
"paths:\n" +
" /test:\n" +
" get:\n" +
" operationId: myMethod\n" +
" requestBody:\n" +
" content:\n" +
" '*/*':\n" +
" schema:\n" +
" $ref: \"#/components/schemas/Example\"\n" +
" responses:\n" +
" default:\n" +
" description: default response\n" +
" content:\n" +
" '*/*': {}\n" +
"components:\n" +
" schemas:\n" +
" Example:\n" +
" type: object\n" +
" properties:\n" +
" myMap:\n" +
" type: object\n" +
" additionalProperties:\n" +
" type: string\n" +
" propertyNames:\n" +
" $ref: \"#/components/schemas/MyEnum\"\n" +
" MyEnum:\n" +
" type: string\n" +
" enum:\n" +
" - FOO\n" +
" - BAR\n";
SerializationMatchers.assertEqualsToYaml31(openAPI, yaml);
}
The resource class:
@Path("test")
public class ResourceWithEnumMap {
@GET
public void myMethod(Example request) {
}
public static class Example {
@Schema(propertyNames = MyEnum.class)
private Map<MyEnum, String> myMap;
public Map<MyEnum, String> getMyMap() {
return myMap;
}
public void setMyMap(Map<MyEnum, String> myMap) {
this.myMap = myMap;
}
}
public enum MyEnum {
FOO,BAR
}
}
Filter (copy of io.swagger.v3.core.filter.resources.RemoveUnreferencedDefinitionsFilter with OpenAPI 3.1 setting)
public class RemoveUnusedSchemasOAS31Filter extends AbstractSpecFilter {
@Override
public boolean isRemovingUnreferencedDefinitions() {
return true;
}
@Override
public boolean isOpenAPI31Filter() {
return true;
}
}
Expected Behavior
The reference schema for the enum should be present in the spec.
The reproducer test should pass once the reported issue is resolved.
Actual Behavior
The reference schema is removed from the spec because it is incorrectly identified as "unreferenced".
The reproducer fails and shows that MyEnum schema is missing from the generated contract.
Checklist
- I have searched the existing issues and this is not a duplicate.
- I have provided sufficient information for maintainers to reproduce the issue.