Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refs #3060 #3935 - build time / ext app applicationPath resolving #3936

Merged
merged 1 commit into from
Apr 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions modules/swagger-gradle-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ Parameter | Description | Required | Default
`resourceClasses`|see [configuration property](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties)|false|
`prettyPrint`|see [configuration property](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties)|false|`TRUE`
`sortOutput`|see [configuration property](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties)|false|`FALSE`
`alwaysResolveAppPath`|see [configuration property](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties)|false|`FALSE`
`openApiFile`|openapi file to be merged with resolved specification, equivalent to [config](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties) openAPI|false|
`filterClass`|see [configuration property](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties)|false|
`readerClass`|see [configuration property](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties)|false|
Expand Down Expand Up @@ -118,3 +119,5 @@ info:

Since version 2.1.6, `sortOutput` parameter is available, allowing to sort object properties and map keys alphabetically.
Since version 2.1.6, `objectMapperProcessorClass` allows to configure also the ObjectMapper instance used to serialize the resolved OpenAPI
Since version 2.1.9, `alwaysResolveAppPath` parameter is available, allowing to trigger resolving of Application Path from annotaion also not in runtime (e.g. using servlet in separate application, or in maven plugin at build time, etc)

Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public enum Format {JSON, YAML, JSONANDYAML};
private String objectMapperProcessorClass;

private Boolean sortOutput = Boolean.FALSE;
private Boolean alwaysResolveAppPath = Boolean.FALSE;


private String contextId;

Expand Down Expand Up @@ -306,6 +308,15 @@ public void setSortOutput(Boolean sortOutput) {
this.sortOutput = sortOutput;
}

@Input
@Optional
public Boolean getAlwaysResolveAppPath() {
return alwaysResolveAppPath;
}

public void setAlwaysResolveAppPath(Boolean alwaysResolveAppPath) {
this.alwaysResolveAppPath = alwaysResolveAppPath;
}

@TaskAction
public void resolve() throws GradleException {
Expand Down Expand Up @@ -406,6 +417,9 @@ public void resolve() throws GradleException {
method=swaggerLoaderClass.getDeclaredMethod("setSortOutput", Boolean.class);
method.invoke(swaggerLoader, sortOutput);

method=swaggerLoaderClass.getDeclaredMethod("setAlwaysResolveAppPath", Boolean.class);
method.invoke(swaggerLoader, alwaysResolveAppPath);

method=swaggerLoaderClass.getDeclaredMethod("setReadAllResources", Boolean.class);
method.invoke(swaggerLoader, readAllResources);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,9 @@ private OpenAPIConfiguration mergeParentConfiguration(OpenAPIConfiguration confi
if (merged.isSortOutput() == null) {
merged.setSortOutput(parentConfig.isSortOutput());
}
if (merged.isAlwaysResolveAppPath() == null) {
merged.setAlwaysResolveAppPath(parentConfig.isAlwaysResolveAppPath());
}
if (merged.isReadAllResources() == null) {
merged.setReadAllResources(parentConfig.isReadAllResources());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public class SwaggerConfiguration implements OpenAPIConfiguration {

private Boolean sortOutput;

private Boolean alwaysResolveAppPath;

public Long getCacheTTL() {
return cacheTTL;
}
Expand Down Expand Up @@ -256,4 +258,27 @@ public SwaggerConfiguration sortOutput(Boolean sortOutput) {
setSortOutput(sortOutput);
return this;
}

/**
* @since 2.1.9
*/
@Override
public Boolean isAlwaysResolveAppPath() {
return alwaysResolveAppPath;
}

/**
* @since 2.1.9
*/
public void setAlwaysResolveAppPath(Boolean alwaysResolveAppPath) {
this.alwaysResolveAppPath = alwaysResolveAppPath;
}

/**
* @since 2.1.9
*/
public SwaggerConfiguration alwaysResolveAppPath(Boolean alwaysResolveAppPath) {
setAlwaysResolveAppPath(alwaysResolveAppPath);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,9 @@ public interface OpenAPIConfiguration {
*/
Boolean isSortOutput();

/**
* @since 2.1.9
*/
Boolean isAlwaysResolveAppPath();

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.Path;
import java.util.HashSet;
import java.util.LinkedHashSet;
Expand All @@ -20,7 +21,7 @@
*
* @since 2.1.2
*/
@HandlesTypes({Path.class, OpenAPIDefinition.class})
@HandlesTypes({Path.class, OpenAPIDefinition.class, ApplicationPath.class})
public class SwaggerServletInitializer implements ServletContainerInitializer {

static final Set<String> ignored = new HashSet();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.Path;
import java.util.HashSet;
import java.util.LinkedHashSet;
Expand All @@ -20,7 +21,7 @@
* swagger-jaxrs2-servlet-initializer-v2
*/
@Deprecated
@HandlesTypes({Path.class, OpenAPIDefinition.class})
@HandlesTypes({Path.class, OpenAPIDefinition.class, ApplicationPath.class})
public class SwaggerServletInitializer implements ServletContainerInitializer {

static final Set<String> ignored = new HashSet();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ public OpenAPI read(Class<?> cls) {
* @return the generated OpenAPI definition
*/
public OpenAPI read(Set<Class<?>> classes) {

Set<Class<?>> sortedClasses = new TreeSet<>((class1, class2) -> {
if (class1.equals(class2)) {
return 0;
Expand All @@ -146,6 +147,8 @@ public OpenAPI read(Set<Class<?>> classes) {

Map<Class<?>, ReaderListener> listeners = new HashMap<>();

String appPath = "";

for (Class<?> cls : sortedClasses) {
if (ReaderListener.class.isAssignableFrom(cls) && !listeners.containsKey(cls)) {
try {
Expand All @@ -154,6 +157,14 @@ public OpenAPI read(Set<Class<?>> classes) {
LOGGER.error("Failed to create ReaderListener", e);
}
}
if (config != null && Boolean.TRUE.equals(config.isAlwaysResolveAppPath())) {
if (Application.class.isAssignableFrom(cls)) {
ApplicationPath appPathAnnotation = ReflectionUtils.getAnnotation(cls, ApplicationPath.class);
if (appPathAnnotation != null) {
appPath = appPathAnnotation.value();
}
}
}
}

for (ReaderListener listener : listeners.values()) {
Expand All @@ -163,9 +174,13 @@ public OpenAPI read(Set<Class<?>> classes) {
LOGGER.error("Unexpected error invoking beforeScan listener [" + listener.getClass().getName() + "]", e);
}
}
String appPathRuntime = resolveApplicationPath();
if (StringUtils.isNotBlank(appPathRuntime)) {
appPath = appPathRuntime;
}

for (Class<?> cls : sortedClasses) {
read(cls, resolveApplicationPath(), null, false, null, null, new LinkedHashSet<String>(), new ArrayList<Parameter>(), new HashSet<Class<?>>());
read(cls, appPath, null, false, null, null, new LinkedHashSet<String>(), new ArrayList<Parameter>(), new HashSet<Class<?>>());
}

for (ReaderListener listener : listeners.values()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -92,6 +93,9 @@ public Set<Class<?>> classes() {
try (ScanResult scanResult = graph.scan()) {
classes = new HashSet<>(scanResult.getClassesWithAnnotation(javax.ws.rs.Path.class.getName()).loadClasses());
classes.addAll(new HashSet<>(scanResult.getClassesWithAnnotation(OpenAPIDefinition.class.getName()).loadClasses()));
if (Boolean.TRUE.equals(openApiConfiguration.isAlwaysResolveAppPath())) {
classes.addAll(new HashSet<>(scanResult.getClassesWithAnnotation(ApplicationPath.class.getName()).loadClasses()));
}
}

for (Class<?> cls : classes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ public class ServletConfigContextUtils {
*/
public static final String OPENAPI_CONFIGURATION_SORTOUTPUT_KEY = "openApi.configuration.sortOutput";

/**
* @since 2.1.9
*/
public static final String OPENAPI_CONFIGURATION_ALWAYSRESOLVEAPPPATH_KEY = "openApi.configuration.alwaysResolveAppPath";

/**
* @since 2.0.6
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static io.swagger.v3.jaxrs2.integration.ServletConfigContextUtils.OPENAPI_CONFIGURATION_READER_KEY;
import static io.swagger.v3.jaxrs2.integration.ServletConfigContextUtils.OPENAPI_CONFIGURATION_SCANNER_KEY;
import static io.swagger.v3.jaxrs2.integration.ServletConfigContextUtils.OPENAPI_CONFIGURATION_SORTOUTPUT_KEY;
import static io.swagger.v3.jaxrs2.integration.ServletConfigContextUtils.OPENAPI_CONFIGURATION_ALWAYSRESOLVEAPPPATH_KEY;
import static io.swagger.v3.jaxrs2.integration.ServletConfigContextUtils.getBooleanInitParam;
import static io.swagger.v3.jaxrs2.integration.ServletConfigContextUtils.getInitParam;
import static io.swagger.v3.jaxrs2.integration.ServletConfigContextUtils.getLongInitParam;
Expand Down Expand Up @@ -55,6 +56,7 @@ public OpenAPIConfiguration load(String path) throws IOException {
.readAllResources(getBooleanInitParam(servletConfig, OPENAPI_CONFIGURATION_READALLRESOURCES_KEY))
.prettyPrint(getBooleanInitParam(servletConfig, OPENAPI_CONFIGURATION_PRETTYPRINT_KEY))
.sortOutput(getBooleanInitParam(servletConfig, OPENAPI_CONFIGURATION_SORTOUTPUT_KEY))
.alwaysResolveAppPath(getBooleanInitParam(servletConfig, OPENAPI_CONFIGURATION_ALWAYSRESOLVEAPPPATH_KEY))
.readerClass(getInitParam(servletConfig, OPENAPI_CONFIGURATION_READER_KEY))
.cacheTTL(getLongInitParam(servletConfig, OPENAPI_CONFIGURATION_CACHE_TTL_KEY))
.scannerClass(getInitParam(servletConfig, OPENAPI_CONFIGURATION_SCANNER_KEY))
Expand Down Expand Up @@ -112,6 +114,9 @@ public boolean exists(String path) {
if (getBooleanInitParam(servletConfig, OPENAPI_CONFIGURATION_SORTOUTPUT_KEY) != null) {
return true;
}
if (getBooleanInitParam(servletConfig, OPENAPI_CONFIGURATION_ALWAYSRESOLVEAPPPATH_KEY) != null) {
return true;
}
if (getInitParam(servletConfig, OPENAPI_CONFIGURATION_READER_KEY) != null) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public class SwaggerLoader {

private Boolean sortOutput = false;

private Boolean alwaysResolveAppPath = false;

/**
* @since 2.0.6
*/
Expand Down Expand Up @@ -177,6 +179,19 @@ public void setSortOutput(Boolean sortOutput) {
this.sortOutput = sortOutput;
}

/**
* @since 2.1.9
*/
public Boolean getAlwaysResolveAppPath() {
return alwaysResolveAppPath;
}

/**
* @since 2.1.9
*/
public void setAlwaysResolveAppPath(Boolean alwaysResolveAppPath) {
this.alwaysResolveAppPath = alwaysResolveAppPath;
}

public Map<String, String> resolve() throws Exception{

Expand Down Expand Up @@ -223,7 +238,8 @@ public Map<String, String> resolve() throws Exception{
.resourcePackages(resourcePackagesSet)
.objectMapperProcessorClass(objectMapperProcessorClass)
.modelConverterClasses(modelConverterSet)
.sortOutput(sortOutput);
.sortOutput(sortOutput)
.alwaysResolveAppPath(alwaysResolveAppPath);
try {
GenericOpenApiContextBuilder builder = new JaxrsOpenApiContextBuilder()
.openApiConfiguration(config);
Expand Down
2 changes: 2 additions & 0 deletions modules/swagger-maven-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ Parameter | Description | Required | Default
`resourceClasses`|see [configuration property](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties)|false|
`prettyPrint`|see [configuration property](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties)|false|`TRUE`
`sortOutput`|see [configuration property](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties)|false|`FALSE`
`alwaysResolveAppPath`|see [configuration property](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties)|false|`FALSE`
`openapiFilePath`|path to openapi file to be merged with resolved specification, see [config](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties)|false|
`configurationFilePath`|path to swagger config file to be merged with resolved specification, see [config](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration)|false|
`filterClass`|see [configuration property](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#configuration-properties)|false|
Expand All @@ -204,3 +205,4 @@ Since version 2.0.8, `configurationFilePath` parameter is available, allowing to

Since version 2.1.6, `sortOutput` parameter is available, allowing to sort object properties and map keys alphabetically.
Since version 2.1.6, `objectMapperProcessorClass` allows to configure also the ObjectMapper instance used to serialize the resolved OpenAPI
Since version 2.1.9, `alwaysResolveAppPath` parameter is available, allowing to trigger resolving of Application Path from annotaion also not in runtime (e.g. using servlet in separate application, or in maven plugin at build time, etc)
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ private void setDefaultsIfMissing(SwaggerConfiguration config) {
if (sortOutput == null) {
sortOutput = Boolean.FALSE;
}
if (alwaysResolveAppPath == null) {
alwaysResolveAppPath = Boolean.FALSE;
}
if (config.isPrettyPrint() == null) {
config.prettyPrint(prettyPrint);
}
Expand All @@ -160,6 +163,9 @@ private void setDefaultsIfMissing(SwaggerConfiguration config) {
if (config.isSortOutput() == null) {
config.sortOutput(sortOutput);
}
if (config.isAlwaysResolveAppPath() == null) {
config.alwaysResolveAppPath(alwaysResolveAppPath);
}
}

/**
Expand Down Expand Up @@ -283,6 +289,9 @@ private SwaggerConfiguration mergeConfig(OpenAPI openAPIInput, SwaggerConfigurat
if (sortOutput != null) {
config.sortOutput(sortOutput);
}
if (alwaysResolveAppPath != null) {
config.alwaysResolveAppPath(alwaysResolveAppPath);
}
if (readAllResources != null) {
config.readAllResources(readAllResources);
}
Expand Down Expand Up @@ -377,6 +386,13 @@ private boolean isCollectionNotBlank(Collection<?> collection) {
@Parameter(property = "resolve.sortOutput")
private Boolean sortOutput;

/**
* @since 2.1.9
*/
@Parameter(property = "resolve.alwaysResolveAppPath")
private Boolean alwaysResolveAppPath;


private String projectEncoding = "UTF-8";
private SwaggerConfiguration config;

Expand Down