diff --git a/microprofile/openapi-smallrye/src/main/java/org/wildfly/extension/microprofile/openapi/deployment/OpenAPIDocumentBuilder.java b/microprofile/openapi-smallrye/src/main/java/org/wildfly/extension/microprofile/openapi/deployment/OpenAPIDocumentBuilder.java deleted file mode 100644 index 0e10f0c9e866..000000000000 --- a/microprofile/openapi-smallrye/src/main/java/org/wildfly/extension/microprofile/openapi/deployment/OpenAPIDocumentBuilder.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.extension.microprofile.openapi.deployment; - -import org.eclipse.microprofile.openapi.OASFilter; -import org.eclipse.microprofile.openapi.models.OpenAPI; - -import io.smallrye.openapi.api.OpenApiConfig; -import io.smallrye.openapi.api.OpenApiDocument; - -/** - * Builder facade to workaround singleton nature of {@link OpenApiDocument}. - * @author Michael Edgar - */ -public class OpenAPIDocumentBuilder { - - private OpenApiConfig config; - private OpenAPI annotationsModel; - private OpenAPI readerModel; - private OpenAPI staticFileModel; - private OASFilter filter; - private String archiveName; - - public OpenAPIDocumentBuilder config(OpenApiConfig config) { - this.config = config; - return this; - } - - public OpenAPIDocumentBuilder archiveName(String archiveName) { - this.archiveName = archiveName; - return this; - } - - public OpenAPIDocumentBuilder staticFileModel(OpenAPI staticFileModel) { - this.staticFileModel = staticFileModel; - return this; - } - - public OpenAPIDocumentBuilder annotationsModel(OpenAPI annotationsModel) { - this.annotationsModel = annotationsModel; - return this; - } - - public OpenAPIDocumentBuilder readerModel(OpenAPI readerModel) { - this.readerModel = readerModel; - return this; - } - - public OpenAPIDocumentBuilder filter(OASFilter filter) { - this.filter = filter; - return this; - } - - public OpenAPI build() { - OpenAPI result = null; - OpenApiDocument instance = OpenApiDocument.INSTANCE; - - synchronized (instance) { - instance.reset(); - instance.config(this.config); - instance.modelFromReader(this.readerModel); - instance.modelFromStaticFile(this.staticFileModel); - instance.modelFromAnnotations(this.annotationsModel); - instance.filter(this.filter); - instance.archiveName(this.archiveName); - instance.initialize(); - - result = instance.get(); - - // Release statically referenced intermediate objects - instance.reset(); - } - - return result; - } -} diff --git a/microprofile/openapi-smallrye/src/main/java/org/wildfly/extension/microprofile/openapi/deployment/OpenAPIModelServiceConfigurator.java b/microprofile/openapi-smallrye/src/main/java/org/wildfly/extension/microprofile/openapi/deployment/OpenAPIModelServiceConfigurator.java index 4ad3435a86d5..cffa9cc14589 100644 --- a/microprofile/openapi-smallrye/src/main/java/org/wildfly/extension/microprofile/openapi/deployment/OpenAPIModelServiceConfigurator.java +++ b/microprofile/openapi-smallrye/src/main/java/org/wildfly/extension/microprofile/openapi/deployment/OpenAPIModelServiceConfigurator.java @@ -26,6 +26,7 @@ import java.util.stream.Collectors; import io.smallrye.openapi.api.OpenApiConfig; +import io.smallrye.openapi.api.OpenApiDocument; import io.smallrye.openapi.runtime.OpenApiProcessor; import io.smallrye.openapi.runtime.OpenApiStaticFile; import io.smallrye.openapi.runtime.io.Format; @@ -81,12 +82,6 @@ public class OpenAPIModelServiceConfigurator extends SimpleServiceNameProvider i private static final String RELATIVE_SERVER_URLS = "mp.openapi.extensions.servers.relative"; private static final String DEFAULT_TITLE = "Generated API"; private static final Set REQUISITE_LISTENERS = Collections.singleton("http"); - private static final Iterable SCANNERS = WildFlySecurityManager.doUnchecked(new PrivilegedAction<>() { - @Override - public Iterable run() { - return ServiceLoader.load(AnnotationScanner.class, AnnotationScanner.class.getClassLoader()).stream().map(ServiceLoader.Provider::get).collect(Collectors.toList()); - } - }); static { // Set the static OASFactoryResolver eagerly avoiding the need perform TCCL service loading later @@ -143,24 +138,32 @@ public OpenAPI get() { OpenApiConfig config = this.configuration.getOpenApiConfig(); IndexView indexView = new FilteredIndexView(this.index, config); - OpenAPIDocumentBuilder builder = new OpenAPIDocumentBuilder(); - builder.config(config); + OpenApiDocument document = OpenApiDocument.newInstance(); + document.config(config); + document.modelFromReader(OpenApiProcessor.modelFromReader(config, this.module.getClassLoader(), indexView)); Map.Entry entry = this.configuration.getStaticFile(); if (entry != null) { VirtualFile file = entry.getKey(); Format format = entry.getValue(); try (OpenApiStaticFile staticFile = new OpenApiStaticFile(file.openStream(), format)) { - builder.staticFileModel(OpenApiProcessor.modelFromStaticFile(config, staticFile)); + document.modelFromStaticFile(OpenApiProcessor.modelFromStaticFile(config, staticFile)); } catch (IOException e) { throw MicroProfileOpenAPILogger.LOGGER.failedToLoadStaticFile(e, file.getPathNameRelativeTo(this.root), this.deploymentName); } } - builder.annotationsModel(OpenApiProcessor.modelFromAnnotations(config, this.module.getClassLoader(), indexView, Functions.constantSupplier(SCANNERS))); - builder.readerModel(OpenApiProcessor.modelFromReader(config, this.module.getClassLoader(), indexView)); - builder.filter(OpenApiProcessor.getFilter(config, this.module.getClassLoader(), indexView)); - OpenAPI model = builder.build(); + // AnnotationScanner implementations are not stateless, so we must create new instances per deployment + Iterable scanners = WildFlySecurityManager.doUnchecked(new PrivilegedAction<>() { + @Override + public Iterable run() { + return ServiceLoader.load(AnnotationScanner.class, AnnotationScanner.class.getClassLoader()).stream().map(ServiceLoader.Provider::get).collect(Collectors.toList()); + } + }); + document.modelFromAnnotations(OpenApiProcessor.modelFromAnnotations(config, this.module.getClassLoader(), indexView, Functions.constantSupplier(scanners))); + document.filter(OpenApiProcessor.getFilter(config, this.module.getClassLoader(), indexView)); + document.initialize(); + OpenAPI model = document.get(); // Generate default title and description based on web metadata DescriptionGroupMetaData descriptionMetaData = this.metaData.getDescriptionGroup();