Skip to content

Allow to use of multiple Swagger configurations per single ServletConfig using base path as descriminator #1656

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

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ public class BeanConfig extends AbstractScanner implements Scanner, SwaggerConfi
String configId;
String contextId;

private boolean usePathBasedConfig = false;

public boolean isUsePathBasedConfig() {
return usePathBasedConfig;
}

public void setUsePathBasedConfig(boolean usePathBasedConfig) {
this.usePathBasedConfig = usePathBasedConfig;
}

public String getResourcePackage() {
return this.resourcePackage;
}
Expand Down Expand Up @@ -209,6 +219,8 @@ public void setScan(boolean shouldScan) {
.withServletConfig(servletConfig)
.withSwaggerConfig(this)
.withScanner(this)
.withBasePath(getBasePath())
.withPathBasedConfig(isUsePathBasedConfig())
.initConfig()
.initScanner();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import javax.servlet.ServletConfig;

import org.apache.commons.lang3.StringUtils;

public class SwaggerContextService {

private static Logger LOGGER = LoggerFactory.getLogger(SwaggerContextService.class);
Expand All @@ -22,13 +24,32 @@ public class SwaggerContextService {
public static final String SCANNER_ID_DEFAULT = SCANNER_ID_PREFIX + "default";

public static final String CONTEXT_ID_KEY = "swagger.context.id";
public static final String USE_PATH_BASED_CONFIG = "swagger.use.path.based.config";

private ServletConfig sc;
private String configId;
private SwaggerConfig swaggerConfig;
private String scannerId;
private Scanner scanner;
private String contextId;
private String basePath;
private boolean usePathBasedConfig = false;

public boolean isUsePathBasedConfig() {
return usePathBasedConfig;
}

public void setUsePathBasedConfig(boolean usePathBasedConfig) {
this.usePathBasedConfig = usePathBasedConfig;
}

public void setBasePath(String basePath) {
this.basePath = normalizeBasePath(basePath);
}

public String getBasePath() {
return basePath;
}

public void setScannerId(String scannerId) {
this.scannerId = scannerId;
Expand Down Expand Up @@ -72,6 +93,16 @@ private static boolean isServletConfigAvailable (ServletConfig sc) {
return true;
}

public SwaggerContextService withBasePath(String basePath) {
this.basePath = normalizeBasePath(basePath);
return this;
}

public SwaggerContextService withPathBasedConfig(boolean usePathBasedConfig) {
this.usePathBasedConfig = usePathBasedConfig;
return this;
}

public SwaggerContextService withConfigId(String configId) {
this.configId = configId;
return this;
Expand Down Expand Up @@ -112,10 +143,19 @@ public SwaggerContextService initConfig(Swagger swagger) {
if (isServletConfigAvailable(sc)) {
configIdKey = (sc.getInitParameter(CONFIG_ID_KEY) != null) ? CONFIG_ID_PREFIX + sc.getInitParameter(CONFIG_ID_KEY) : null;
if (configIdKey == null) {
configIdKey = (sc.getInitParameter(CONTEXT_ID_KEY) != null) ? CONFIG_ID_PREFIX + sc.getInitParameter(CONTEXT_ID_KEY) : CONFIG_ID_DEFAULT;
boolean usePathBasedConfig = Boolean.valueOf(sc.getInitParameter(USE_PATH_BASED_CONFIG));
if (usePathBasedConfig && StringUtils.isNotBlank(basePath)) {
configIdKey = CONFIG_ID_PREFIX + basePath;
} else {
configIdKey = (sc.getInitParameter(CONTEXT_ID_KEY) != null) ? CONFIG_ID_PREFIX + sc.getInitParameter(CONTEXT_ID_KEY) : CONFIG_ID_DEFAULT;
}
}
} else {
configIdKey = CONFIG_ID_DEFAULT;
if (isUsePathBasedConfig() && StringUtils.isNotBlank(basePath)) {
configIdKey = CONFIG_ID_PREFIX + basePath;
} else {
configIdKey = CONFIG_ID_DEFAULT;
}
}
}
SwaggerConfig value = (swaggerConfig != null) ? swaggerConfig : null;
Expand All @@ -142,7 +182,12 @@ private Object getConfigOrSwagger(boolean returnSwagger) {
if (isServletConfigAvailable(sc)) {
configIdKey = (sc.getInitParameter(CONFIG_ID_KEY) != null) ? CONFIG_ID_PREFIX + sc.getInitParameter(CONFIG_ID_KEY) : null;
if (configIdKey == null) {
configIdKey = (sc.getInitParameter(CONTEXT_ID_KEY) != null) ? CONFIG_ID_PREFIX + sc.getInitParameter(CONTEXT_ID_KEY) : CONFIG_ID_DEFAULT;
boolean usePathBasedConfig = Boolean.valueOf(sc.getInitParameter(USE_PATH_BASED_CONFIG));
if (usePathBasedConfig && StringUtils.isNotBlank(basePath)) {
configIdKey = CONFIG_ID_PREFIX + basePath;
} else {
configIdKey = (sc.getInitParameter(CONTEXT_ID_KEY) != null) ? CONFIG_ID_PREFIX + sc.getInitParameter(CONTEXT_ID_KEY) : CONFIG_ID_DEFAULT;
}
}
} else {
configIdKey = CONFIG_ID_DEFAULT;
Expand Down Expand Up @@ -179,10 +224,19 @@ public SwaggerContextService updateSwagger(Swagger swagger) {
if (isServletConfigAvailable(sc)) {
configIdKey = (sc.getInitParameter(CONFIG_ID_KEY) != null) ? CONFIG_ID_PREFIX + sc.getInitParameter(CONFIG_ID_KEY) : null;
if (configIdKey == null) {
configIdKey = (sc.getInitParameter(CONTEXT_ID_KEY) != null) ? CONFIG_ID_PREFIX + sc.getInitParameter(CONTEXT_ID_KEY) : CONFIG_ID_DEFAULT;
boolean usePathBasedConfig = Boolean.valueOf(sc.getInitParameter(USE_PATH_BASED_CONFIG));
if (usePathBasedConfig && StringUtils.isNotBlank(basePath)) {
configIdKey = CONFIG_ID_PREFIX + basePath;
} else {
configIdKey = (sc.getInitParameter(CONTEXT_ID_KEY) != null) ? CONFIG_ID_PREFIX + sc.getInitParameter(CONTEXT_ID_KEY) : CONFIG_ID_DEFAULT;
}
}
} else {
configIdKey = CONFIG_ID_DEFAULT;
if (isUsePathBasedConfig() && StringUtils.isNotBlank(basePath)) {
configIdKey = CONFIG_ID_PREFIX + basePath;
} else {
configIdKey = CONFIG_ID_DEFAULT;
}
}
}
if (swagger != null) {
Expand All @@ -202,10 +256,19 @@ public SwaggerContextService initScanner() {
if (isServletConfigAvailable(sc)) {
scannerIdKey = (sc.getInitParameter(SCANNER_ID_KEY) != null) ? SCANNER_ID_PREFIX + sc.getInitParameter(SCANNER_ID_KEY) : null;
if (scannerIdKey == null) {
scannerIdKey = (sc.getInitParameter(CONTEXT_ID_KEY) != null) ? SCANNER_ID_PREFIX + sc.getInitParameter(CONTEXT_ID_KEY) : SCANNER_ID_DEFAULT;
boolean usePathBasedConfig = Boolean.valueOf(sc.getInitParameter(USE_PATH_BASED_CONFIG));
if (usePathBasedConfig && StringUtils.isNotBlank(basePath)) {
scannerIdKey = SCANNER_ID_PREFIX + basePath;
} else {
scannerIdKey = (sc.getInitParameter(CONTEXT_ID_KEY) != null) ? SCANNER_ID_PREFIX + sc.getInitParameter(CONTEXT_ID_KEY) : SCANNER_ID_DEFAULT;
}
}
} else {
scannerIdKey = SCANNER_ID_DEFAULT;
if (isUsePathBasedConfig() && StringUtils.isNotBlank(basePath)) {
scannerIdKey = SCANNER_ID_PREFIX + basePath;
} else {
scannerIdKey = SCANNER_ID_DEFAULT;
}
}
}
Scanner value = (scanner != null) ? scanner : new DefaultJaxrsScanner();
Expand Down Expand Up @@ -233,7 +296,12 @@ public Scanner getScanner() {
if (isServletConfigAvailable(sc)) {
scannerIdKey = (sc.getInitParameter(SCANNER_ID_KEY) != null) ? SCANNER_ID_PREFIX + sc.getInitParameter(SCANNER_ID_KEY) : null;
if (scannerIdKey == null) {
scannerIdKey = (sc.getInitParameter(CONTEXT_ID_KEY) != null) ? SCANNER_ID_PREFIX + sc.getInitParameter(CONTEXT_ID_KEY) : SCANNER_ID_DEFAULT;
boolean usePathBasedConfig = Boolean.valueOf(sc.getInitParameter(USE_PATH_BASED_CONFIG));
if (usePathBasedConfig && StringUtils.isNotBlank(basePath)) {
scannerIdKey = SCANNER_ID_PREFIX + basePath;
} else {
scannerIdKey = (sc.getInitParameter(CONTEXT_ID_KEY) != null) ? SCANNER_ID_PREFIX + sc.getInitParameter(CONTEXT_ID_KEY) : SCANNER_ID_DEFAULT;
}
}
value = (Scanner) sc.getServletContext().getAttribute(scannerIdKey);
} else {
Expand All @@ -250,6 +318,16 @@ public Scanner getScanner() {
return ScannerFactory.getScanner();
}

public static boolean isUsePathBasedConfigInitParamDefined(ServletConfig sc) {
if (!isServletConfigAvailable(sc)) return false;
String key = sc.getInitParameter(USE_PATH_BASED_CONFIG);
if (key != null){
return true;
} else {
return (sc.getInitParameter(CONTEXT_ID_KEY) != null) ? true : false;
}
}

public static boolean isScannerIdInitParamDefined(ServletConfig sc) {
if (!isServletConfigAvailable(sc)) return false;
String key = sc.getInitParameter(SCANNER_ID_KEY);
Expand Down Expand Up @@ -289,4 +367,26 @@ public static String getConfigIdFromInitParam(ServletConfig sc) {
return sc.getInitParameter(CONTEXT_ID_KEY);
}
}

/**
* Normalize base path to the canonical form by adding trailing and leading slashes
* @param basePath base path to normalize
* @return normalized base path
*/
private static String normalizeBasePath(final String basePath) {
if (basePath == null) {
return basePath;
}

String normalizedBasePath = basePath.trim();
if (!normalizedBasePath.startsWith("/")) {
normalizedBasePath = "/" + normalizedBasePath;
}

if (!normalizedBasePath.endsWith("/")) {
normalizedBasePath = normalizedBasePath + "/";
}

return normalizedBasePath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,20 @@ public abstract class BaseApiListingResource {
private static Logger LOGGER = LoggerFactory.getLogger(BaseApiListingResource.class);


private static synchronized Swagger scan(Application app, ServletContext context, ServletConfig sc) {
private static synchronized Swagger scan(Application app, ServletContext context, ServletConfig sc, UriInfo uriInfo) {
Swagger swagger = null;
SwaggerContextService ctxService = new SwaggerContextService().withServletConfig(sc);

SwaggerContextService ctxService = new SwaggerContextService()
.withServletConfig(sc)
.withBasePath(getBasePath(uriInfo));

Scanner scanner = ctxService.getScanner();
if (scanner != null) {
SwaggerSerializers.setPrettyPrint(scanner.getPrettyPrint());
swagger = new SwaggerContextService().withServletConfig(sc).getSwagger();
swagger = new SwaggerContextService()
.withServletConfig(sc)
.withBasePath(getBasePath(uriInfo))
.getSwagger();
Set<Class<?>> classes;
if (scanner instanceof JaxrsScanner) {
JaxrsScanner jaxrsScanner = (JaxrsScanner) scanner;
Expand All @@ -65,13 +72,18 @@ private static synchronized Swagger scan(Application app, ServletContext context
LOGGER.debug("no configurator");
}
}
new SwaggerContextService().withServletConfig(sc).updateSwagger(swagger);
new SwaggerContextService()
.withServletConfig(sc)
.withBasePath(getBasePath(uriInfo))
.updateSwagger(swagger);
}
}
if (SwaggerContextService.isScannerIdInitParamDefined(sc)) {
initializedScanner.put(sc.getServletName() + "_" + SwaggerContextService.getScannerIdFromInitParam(sc), true);
} else if (SwaggerContextService.isConfigIdInitParamDefined(sc)) {
initializedConfig.put(sc.getServletName() + "_" + SwaggerContextService.getConfigIdFromInitParam(sc), true);
} else if (SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)) {
initializedConfig.put(sc.getServletName() + "_" + ctxService.getBasePath(), true);
} else {
initialized = true;
}
Expand All @@ -85,21 +97,27 @@ private Swagger process(
ServletConfig sc,
HttpHeaders headers,
UriInfo uriInfo) {
Swagger swagger = new SwaggerContextService().withServletConfig(sc).getSwagger();
SwaggerContextService ctxService = new SwaggerContextService()
.withServletConfig(sc)
.withBasePath(getBasePath(uriInfo));

Swagger swagger = ctxService.getSwagger();
synchronized (ApiListingResource.class) {
if (SwaggerContextService.isScannerIdInitParamDefined(sc)) {
if (!initializedScanner.containsKey(sc.getServletName() + "_" + SwaggerContextService.getScannerIdFromInitParam(sc))) {
swagger = scan(app, servletContext, sc);
swagger = scan(app, servletContext, sc, uriInfo);
}
} else {
if (SwaggerContextService.isConfigIdInitParamDefined(sc)) {
if (!initializedConfig.containsKey(sc.getServletName() + "_" + SwaggerContextService.getConfigIdFromInitParam(sc))) {
swagger = scan(app, servletContext, sc);
swagger = scan(app, servletContext, sc, uriInfo);
}
} else {
if (!initialized) {
swagger = scan(app, servletContext, sc);
} else if (SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)) {
if (!initializedConfig.containsKey(sc.getServletName() + "_" + ctxService.getBasePath())) {
swagger = scan(app, servletContext, sc, uriInfo);
}
} else if (!initialized) {
swagger = scan(app, servletContext, sc, uriInfo);
}
}
}
Expand Down Expand Up @@ -186,5 +204,12 @@ private static Map<String, List<String>> getHeaders(HttpHeaders headers) {
return output;
}

private static String getBasePath(UriInfo uriInfo) {
if (uriInfo != null) {
return uriInfo.getBaseUri().getPath();
} else {
return "/";
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ void initMock() {
bc.setDescription("Bean Config test 2");
beanConfigScanner2 = bc;
}

void stubWithPathBasedConfigInitParam() {

when(servletContext1.getAttribute(SCANNER_ID_PREFIX + "/url1")).thenReturn(beanConfigScanner1);
when(servletContext2.getAttribute(SCANNER_ID_PREFIX + "/url2")).thenReturn(beanConfigScanner2);

when(servletConfig1.getServletContext()).thenReturn(servletContext1);
when(servletConfig2.getServletContext()).thenReturn(servletContext2);

when(servletConfig1.getInitParameter(USE_PATH_BASED_CONFIG)).thenReturn("true");
when(servletConfig2.getInitParameter(USE_PATH_BASED_CONFIG)).thenReturn("true");
}

private void stubWithInitParam() {
when(servletContext1.getAttribute(SCANNER_ID_PREFIX + "test.1")).thenReturn(beanConfigScanner1);
Expand Down Expand Up @@ -281,4 +293,24 @@ public void initConfigViaContextParamSwagger() {

}

@Test(description = "should add SwaggerConfig to SwaggerConfigLocator map with keys path-based keys")
public void initializeAndGetConfigBasedOnPath() {
stubWithPathBasedConfigInitParam();

new SwaggerContextService()
.withServletConfig(servletConfig1)
.withBasePath("/url1")
.initConfig();

new SwaggerContextService()
.withServletConfig(servletConfig2)
.withBasePath("url2")
.initConfig();

assertTrue(SwaggerConfigLocator.getInstance().getConfig(CONFIG_ID_PREFIX + "/url1/") instanceof WebXMLReader);
assertTrue(SwaggerConfigLocator.getInstance().getConfig(CONFIG_ID_PREFIX + "/url2/") instanceof WebXMLReader);

verify(servletConfig1, times(1)).getInitParameter(eq(USE_PATH_BASED_CONFIG));
verify(servletConfig2, times(1)).getInitParameter(eq(USE_PATH_BASED_CONFIG));
}
}