From 85a2961d01046060c208d8941162b50f027e2e90 Mon Sep 17 00:00:00 2001 From: Steve Hu Date: Thu, 17 Dec 2020 20:24:44 -0500 Subject: [PATCH] fixes #158 make OpenApiHelper a singleton with an init method and load it in each handler (#159) --- openapi-helper/pom.xml | 5 +++ .../com/networknt/openapi/OpenApiHelper.java | 41 ++++++++++--------- .../networknt/openapi/OpenApiHelperTest.java | 4 +- .../com/networknt/openapi/OpenApiHandler.java | 17 ++++++-- .../openapi/OpenApiEndpointSourceTest.java | 6 +++ .../networknt/openapi/JwtVerifyHandler.java | 18 +++++++- .../networknt/openapi/ResponseValidator.java | 2 +- .../networknt/openapi/ValidatorHandler.java | 13 ++++++ 8 files changed, 79 insertions(+), 27 deletions(-) diff --git a/openapi-helper/pom.xml b/openapi-helper/pom.xml index b08a1d05..16803737 100644 --- a/openapi-helper/pom.xml +++ b/openapi-helper/pom.xml @@ -57,6 +57,11 @@ junit test + + com.networknt + config + test + diff --git a/openapi-helper/src/main/java/com/networknt/openapi/OpenApiHelper.java b/openapi-helper/src/main/java/com/networknt/openapi/OpenApiHelper.java index 19ccbdc6..4759c887 100644 --- a/openapi-helper/src/main/java/com/networknt/openapi/OpenApiHelper.java +++ b/openapi-helper/src/main/java/com/networknt/openapi/OpenApiHelper.java @@ -16,7 +16,6 @@ package com.networknt.openapi; -import com.networknt.config.Config; import com.networknt.oas.OpenApiParser; import com.networknt.oas.model.OpenApi3; import com.networknt.oas.model.SecurityScheme; @@ -41,27 +40,15 @@ * @author Steve Hu */ public class OpenApiHelper { - - static final String OPENAPI_YML_CONFIG = "openapi.yml"; - static final String OPENAPI_YAML_CONFIG = "openapi.yaml"; - static final String OPENAPI_JSON_CONFIG = "openapi.json"; - static final Logger logger = LoggerFactory.getLogger(OpenApiHelper.class); public static OpenApi3 openApi3; public static List oauth2Names; public static String basePath; + private static OpenApiHelper INSTANCE = null; - static { + private OpenApiHelper(String spec) { try { - // first try to load the specification into a string regardless it is in YAML or JSON. - String spec = Config.getInstance().getStringFromFile(OPENAPI_YML_CONFIG); - if(spec == null) { - spec = Config.getInstance().getStringFromFile(OPENAPI_YAML_CONFIG); - if(spec == null) { - spec = Config.getInstance().getStringFromFile(OPENAPI_JSON_CONFIG); - } - } openApi3 = (OpenApi3) new OpenApiParser().parse(spec, new URL("https://oas.lightapi.net/")); } catch (MalformedURLException e) { logger.error("MalformedURLException", e); @@ -73,9 +60,25 @@ public class OpenApiHelper { oauth2Names = getOAuth2Name(); basePath = getBasePath(); } + + } + + public static OpenApiHelper getInstance() { + if(INSTANCE == null) { + return null; + } + return INSTANCE; + } + + public synchronized static OpenApiHelper init(String spec) { + if(INSTANCE != null) { + return INSTANCE; + } + INSTANCE = new OpenApiHelper(spec); + return INSTANCE; } - public static Optional findMatchingApiPath(final NormalisedPath requestPath) { + public Optional findMatchingApiPath(final NormalisedPath requestPath) { if(OpenApiHelper.openApi3 != null) { return OpenApiHelper.openApi3.getPaths().keySet() .stream() @@ -87,7 +90,7 @@ public static Optional findMatchingApiPath(final NormalisedPath } } - private static List getOAuth2Name() { + private List getOAuth2Name() { List names = new ArrayList<>(); Map defMap = openApi3.getSecuritySchemes(); if(defMap != null) { @@ -100,7 +103,7 @@ private static List getOAuth2Name() { return names; } - private static String getBasePath() { + private String getBasePath() { String basePath = ""; String url = null; @@ -119,7 +122,7 @@ private static String getBasePath() { return basePath; } - private static boolean pathMatches(final NormalisedPath requestPath, final NormalisedPath apiPath) { + private boolean pathMatches(final NormalisedPath requestPath, final NormalisedPath apiPath) { if (requestPath.parts().size() != apiPath.parts().size()) { return false; } diff --git a/openapi-helper/src/test/java/com/networknt/openapi/OpenApiHelperTest.java b/openapi-helper/src/test/java/com/networknt/openapi/OpenApiHelperTest.java index 4584442b..ac76ccd8 100644 --- a/openapi-helper/src/test/java/com/networknt/openapi/OpenApiHelperTest.java +++ b/openapi-helper/src/test/java/com/networknt/openapi/OpenApiHelperTest.java @@ -16,7 +16,7 @@ package com.networknt.openapi; -import com.networknt.oas.OpenApiParser; +import com.networknt.config.Config; import org.junit.Assert; import org.junit.Test; @@ -26,6 +26,8 @@ public class OpenApiHelperTest { @Test public void testOAuth2Name() { + String spec = Config.getInstance().getStringFromFile("openapi.yaml"); + OpenApiHelper.init(spec); Assert.assertEquals(1, OpenApiHelper.oauth2Names.size()); Assert.assertEquals("petstore_auth", OpenApiHelper.oauth2Names.get(0)); } diff --git a/openapi-meta/src/main/java/com/networknt/openapi/OpenApiHandler.java b/openapi-meta/src/main/java/com/networknt/openapi/OpenApiHandler.java index 6967998c..e8ee11b9 100644 --- a/openapi-meta/src/main/java/com/networknt/openapi/OpenApiHandler.java +++ b/openapi-meta/src/main/java/com/networknt/openapi/OpenApiHandler.java @@ -54,7 +54,10 @@ public class OpenApiHandler implements MiddlewareHandler { static final Logger logger = LoggerFactory.getLogger(OpenApiHandler.class); public static final String CONFIG_NAME = "openapi"; - + static final String OPENAPI_YML_CONFIG = "openapi.yml"; + static final String OPENAPI_YAML_CONFIG = "openapi.yaml"; + static final String OPENAPI_JSON_CONFIG = "openapi.json"; + public static final AttachmentKey> DESERIALIZED_QUERY_PARAMETERS = AttachmentKey.create(Map.class); public static final AttachmentKey> DESERIALIZED_PATH_PARAMETERS = AttachmentKey.create(Map.class); public static final AttachmentKey> DESERIALIZED_HEADER_PARAMETERS = AttachmentKey.create(Map.class); @@ -64,16 +67,22 @@ public class OpenApiHandler implements MiddlewareHandler { static final String STATUS_METHOD_NOT_ALLOWED = "ERR10008"; private volatile HttpHandler next; - public OpenApiHandler() { - + String spec = Config.getInstance().getStringFromFile(OPENAPI_YML_CONFIG); + if(spec == null) { + spec = Config.getInstance().getStringFromFile(OPENAPI_YAML_CONFIG); + if(spec == null) { + spec = Config.getInstance().getStringFromFile(OPENAPI_JSON_CONFIG); + } + } + OpenApiHelper.init(spec); } @Override public void handleRequest(final HttpServerExchange exchange) throws Exception { final NormalisedPath requestPath = new ApiNormalisedPath(exchange.getRequestURI()); - final Optional maybeApiPath = OpenApiHelper.findMatchingApiPath(requestPath); + final Optional maybeApiPath = OpenApiHelper.getInstance().findMatchingApiPath(requestPath); if (!maybeApiPath.isPresent()) { setExchangeStatus(exchange, STATUS_INVALID_REQUEST_PATH, requestPath.normalised()); return; diff --git a/openapi-meta/src/test/java/com/networknt/openapi/OpenApiEndpointSourceTest.java b/openapi-meta/src/test/java/com/networknt/openapi/OpenApiEndpointSourceTest.java index 27068988..f5968832 100644 --- a/openapi-meta/src/test/java/com/networknt/openapi/OpenApiEndpointSourceTest.java +++ b/openapi-meta/src/test/java/com/networknt/openapi/OpenApiEndpointSourceTest.java @@ -23,7 +23,9 @@ import java.util.stream.Collectors; import java.util.stream.StreamSupport; +import com.networknt.config.Config; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; import com.networknt.handler.config.EndpointSource; @@ -35,6 +37,10 @@ public class OpenApiEndpointSourceTest { "/v1/pets/{petId}@get", "/v1/pets/{petId}@delete" )); + static { + String spec = Config.getInstance().getStringFromFile("openapi.yaml"); + OpenApiHelper.init(spec); + } @Test public void testFindBasePath() { diff --git a/openapi-security/src/main/java/com/networknt/openapi/JwtVerifyHandler.java b/openapi-security/src/main/java/com/networknt/openapi/JwtVerifyHandler.java index d5ed8517..909f8f89 100644 --- a/openapi-security/src/main/java/com/networknt/openapi/JwtVerifyHandler.java +++ b/openapi-security/src/main/java/com/networknt/openapi/JwtVerifyHandler.java @@ -52,6 +52,9 @@ */ public class JwtVerifyHandler implements MiddlewareHandler, IJwtVerifyHandler { static final Logger logger = LoggerFactory.getLogger(JwtVerifyHandler.class); + static final String OPENAPI_YML_CONFIG = "openapi.yml"; + static final String OPENAPI_YAML_CONFIG = "openapi.yaml"; + static final String OPENAPI_JSON_CONFIG = "openapi.json"; static final String OPENAPI_SECURITY_CONFIG = "openapi-security"; static final String ENABLE_VERIFY_SCOPE = "enableVerifyScope"; @@ -81,7 +84,18 @@ public class JwtVerifyHandler implements MiddlewareHandler, IJwtVerifyHandler { private volatile HttpHandler next; - public JwtVerifyHandler() {} + public JwtVerifyHandler() { + if(OpenApiHelper.getInstance() == null) { + String spec = Config.getInstance().getStringFromFile(OPENAPI_YML_CONFIG); + if(spec == null) { + spec = Config.getInstance().getStringFromFile(OPENAPI_YAML_CONFIG); + if(spec == null) { + spec = Config.getInstance().getStringFromFile(OPENAPI_JSON_CONFIG); + } + } + OpenApiHelper.init(spec); + } + } @Override public void handleRequest(final HttpServerExchange exchange) throws Exception { @@ -115,7 +129,7 @@ public void handleRequest(final HttpServerExchange exchange) throws Exception { OpenApiOperation openApiOperation = (OpenApiOperation)auditInfo.get(Constants.OPENAPI_OPERATION_STRING); if(openApiOperation == null) { final NormalisedPath requestPath = new ApiNormalisedPath(exchange.getRequestURI()); - final Optional maybeApiPath = OpenApiHelper.findMatchingApiPath(requestPath); + final Optional maybeApiPath = OpenApiHelper.getInstance().findMatchingApiPath(requestPath); if (!maybeApiPath.isPresent()) { setExchangeStatus(exchange, STATUS_INVALID_REQUEST_PATH); return; diff --git a/openapi-validator/src/main/java/com/networknt/openapi/ResponseValidator.java b/openapi-validator/src/main/java/com/networknt/openapi/ResponseValidator.java index e322d15d..68fd52e2 100644 --- a/openapi-validator/src/main/java/com/networknt/openapi/ResponseValidator.java +++ b/openapi-validator/src/main/java/com/networknt/openapi/ResponseValidator.java @@ -193,7 +193,7 @@ private Object convertStrToObjTree(String s) { private OpenApiOperation getOpenApiOperation(String uri, String httpMethod) throws URISyntaxException { String uriWithoutQuery = new URI(uri).getPath(); NormalisedPath requestPath = new ApiNormalisedPath(uriWithoutQuery); - Optional maybeApiPath = OpenApiHelper.findMatchingApiPath(requestPath); + Optional maybeApiPath = OpenApiHelper.getInstance().findMatchingApiPath(requestPath); if (!maybeApiPath.isPresent()) { return null; } diff --git a/openapi-validator/src/main/java/com/networknt/openapi/ValidatorHandler.java b/openapi-validator/src/main/java/com/networknt/openapi/ValidatorHandler.java index 860f8b43..bb952f57 100644 --- a/openapi-validator/src/main/java/com/networknt/openapi/ValidatorHandler.java +++ b/openapi-validator/src/main/java/com/networknt/openapi/ValidatorHandler.java @@ -44,6 +44,9 @@ public class ValidatorHandler implements MiddlewareHandler { public static final String OPENAPI_CONFIG_NAME = "openapi-validator"; public static final String CONFIG_NAME = "validator"; + static final String OPENAPI_YML_CONFIG = "openapi.yml"; + static final String OPENAPI_YAML_CONFIG = "openapi.yaml"; + static final String OPENAPI_JSON_CONFIG = "openapi.json"; static final String STATUS_MISSING_OPENAPI_OPERATION = "ERR10012"; @@ -64,6 +67,16 @@ public class ValidatorHandler implements MiddlewareHandler { ResponseValidator responseValidator; public ValidatorHandler() { + if(OpenApiHelper.getInstance() == null) { + String spec = Config.getInstance().getStringFromFile(OPENAPI_YML_CONFIG); + if(spec == null) { + spec = Config.getInstance().getStringFromFile(OPENAPI_YAML_CONFIG); + if(spec == null) { + spec = Config.getInstance().getStringFromFile(OPENAPI_JSON_CONFIG); + } + } + OpenApiHelper.init(spec); + } final SchemaValidator schemaValidator = new SchemaValidator(OpenApiHelper.openApi3); this.requestValidator = new RequestValidator(schemaValidator); this.responseValidator = new ResponseValidator();