diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/SchemaValidator.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/SchemaValidator.java index 2b857a0feba9..3b505dd5a143 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/SchemaValidator.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/SchemaValidator.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import io.swagger.util.Json; import io.swagger.v3.oas.models.OpenAPI; +import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.synapse.MessageContext; @@ -31,6 +32,8 @@ import org.wso2.carbon.apimgt.gateway.handlers.security.model.OpenAPIResponse; import org.wso2.carbon.apimgt.gateway.utils.GatewayUtils; +import java.util.HashMap; + /** * This SchemaValidator handler validates the request/response messages against schema defined in the swagger. */ @@ -40,6 +43,7 @@ public class SchemaValidator extends AbstractHandler { private static final Log logger = LogFactory.getLog(SchemaValidator.class); private static final String HTTP_SC_CODE = "400"; public static final String REG_TIME_MODULE = "register.timeModule"; + public static HashMap validatorMap = new HashMap<>(); /** * Method to generate OpenApiInteractionValidator when the openAPI is provided. @@ -69,10 +73,10 @@ public boolean handleRequest(MessageContext messageContext) { } logger.debug("Validating the API request Body content.."); OpenAPI openAPI = (OpenAPI) messageContext.getProperty(APIMgtGatewayConstants.OPEN_API_OBJECT); - if (openAPI != null) { - OpenApiInteractionValidator validator = getOpenAPIValidator(openAPI); + Object openAPIStringObject = messageContext.getProperty(APIMgtGatewayConstants.OPEN_API_STRING); + if (openAPI != null && openAPIStringObject != null) { + OpenApiInteractionValidator validator = getOpenApiValidator(openAPI, openAPIStringObject.toString()); OpenAPIRequest request = new OpenAPIRequest(messageContext); - ValidationReport validationReport = validator.validateRequest(request); messageContext.setProperty(APIMgtGatewayConstants.SCHEMA_VALIDATION_REPORT, validationReport); if (validationReport.hasErrors()) { @@ -92,10 +96,10 @@ public boolean handleRequest(MessageContext messageContext) { public boolean handleResponse(MessageContext messageContext) { OpenAPI openAPI = (OpenAPI) messageContext.getProperty(APIMgtGatewayConstants.OPEN_API_OBJECT); - if (openAPI != null) { - OpenApiInteractionValidator validator = getOpenAPIValidator(openAPI); + Object openAPIStringObject = messageContext.getProperty(APIMgtGatewayConstants.OPEN_API_STRING); + if (openAPI != null && openAPIStringObject != null) { + OpenApiInteractionValidator validator = getOpenApiValidator(openAPI, openAPIStringObject.toString()); OpenAPIResponse response = new OpenAPIResponse(messageContext); - ValidationReport validationReport = validator.validateResponse(response.getPath(), response.getMethod(), response); if (validationReport.hasErrors()) { @@ -110,4 +114,26 @@ public boolean handleResponse(MessageContext messageContext) { } return true; } + + /** + * Method to get OpenApiInteractionValidator for the given openAPI. + * If the validator is already created for the given openAPI, it will return the existing one. + * Created validators are mapped against the hash of the yaml. + * + * @param openAPI - OpenAPI object + * @param openAPIString - OpenAPI string (yaml) + * @return OpenApiInteractionValidator + */ + private OpenApiInteractionValidator getOpenApiValidator(OpenAPI openAPI, String openAPIString) { + + OpenApiInteractionValidator validator; + String apiIdentifier = DigestUtils.md5Hex(openAPIString); + if (validatorMap.containsKey(apiIdentifier)) { + validator = validatorMap.get(apiIdentifier); + } else { + validator = getOpenAPIValidator(openAPI); + validatorMap.put(apiIdentifier, validator); + } + return validator; + } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/model/OpenAPIRequest.java b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/model/OpenAPIRequest.java index 627be5ba03b1..ac7594eec13e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/model/OpenAPIRequest.java +++ b/components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/handlers/security/model/OpenAPIRequest.java @@ -19,11 +19,8 @@ import com.atlassian.oai.validator.model.Request; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; -import io.swagger.parser.OpenAPIParser; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Paths; -import io.swagger.v3.parser.core.models.ParseOptions; -import io.swagger.v3.parser.core.models.SwaggerParseResult; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.synapse.MessageContext; @@ -33,7 +30,6 @@ import org.wso2.carbon.apimgt.gateway.handlers.security.utils.SchemaValidationUtils; import java.io.UnsupportedEncodingException; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Locale; @@ -73,12 +69,8 @@ public OpenAPIRequest(MessageContext messageContext) { //Set Request path path = SchemaValidationUtils.getRestSubRequestPath( messageContext.getProperty(REST_SUB_REQUEST_PATH).toString()); - String swagger = messageContext.getProperty(APIMgtGatewayConstants.OPEN_API_STRING).toString(); - if (swagger != null) { - OpenAPIParser openAPIParser = new OpenAPIParser(); - SwaggerParseResult swaggerParseResult = - openAPIParser.readContents(swagger, new ArrayList<>(), new ParseOptions()); - OpenAPI openAPI = swaggerParseResult.getOpenAPI(); + OpenAPI openAPI = (OpenAPI) messageContext.getProperty(APIMgtGatewayConstants.OPEN_API_OBJECT); + if (openAPI != null) { validatePath(openAPI); } //extract transport headers