diff --git a/components/response-filter/src/main/java/com/wso2telco/dep/responsefilter/ResponseFilterMediator.java b/components/response-filter/src/main/java/com/wso2telco/dep/responsefilter/ResponseFilterMediator.java index 7a3e662fb..1652c312d 100644 --- a/components/response-filter/src/main/java/com/wso2telco/dep/responsefilter/ResponseFilterMediator.java +++ b/components/response-filter/src/main/java/com/wso2telco/dep/responsefilter/ResponseFilterMediator.java @@ -15,32 +15,36 @@ */ package com.wso2telco.dep.responsefilter; +import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Iterator; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.wso2telco.core.dbutils.DbUtils; import com.wso2telco.core.dbutils.util.DataSourceNames; import lk.chathurabuddi.json.schema.constants.FreeFormAction; import lk.chathurabuddi.json.schema.filter.JsonSchemaFilter; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.synapse.MessageContext; import org.apache.synapse.commons.json.JsonUtil; import org.apache.synapse.core.axis2.Axis2MessageContext; import org.apache.synapse.mediators.AbstractMediator; +import org.glassfish.jersey.uri.UriTemplate; public class ResponseFilterMediator extends AbstractMediator { - private static final Log log = LogFactory.getLog(ResponseFilterMediator.class); - public boolean mediate(MessageContext messageContext) { String api = messageContext.getProperty("api.ut.api").toString() + ":" + messageContext.getProperty("api.ut.version").toString(); - String operation = messageContext.getProperty("api.ut.HTTP_METHOD").toString() + " " + messageContext.getProperty("api.ut.resource").toString(); + String httpVerb = messageContext.getProperty("api.ut.HTTP_METHOD").toString(); + String resource = messageContext.getProperty("api.ut.resource").toString(); String userId = messageContext.getProperty("api.ut.userId").toString().split("@")[0]; String appName = messageContext.getProperty("api.ut.application.name").toString(); - log.debug("API : " + api + " | USER : " + userId + " | APP_NAME : " + appName + " | OPERATION : " + operation); + log.debug("API : " + api + " | USER : " + userId + " | APP_NAME : " + appName + " | HTTP_VERB : " + httpVerb + " | RESOURCE : " + resource); org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext) messageContext) .getAxis2MessageContext(); @@ -48,10 +52,12 @@ public boolean mediate(MessageContext messageContext) { try { String jsonString = (String) messageContext.getProperty("jsonPayload"); if (jsonString != null && !"".equals(jsonString.trim())){ - String filterSchema = findFilterSchema(userId, appName, api, operation); - if (filterSchema != null) { + String filterSchema = findFilterSchema(userId, appName, api, httpVerb, resource); + if (filterSchema != null && isMatchingPayload(jsonString, filterSchema)) { String filteredJson = new JsonSchemaFilter(filterSchema, jsonString, FreeFormAction.DETACH).filter(); - JsonUtil.getNewJsonPayload(axis2MessageContext, filteredJson, true, true); + if (isNonEmptyJson(filteredJson)) { + JsonUtil.getNewJsonPayload(axis2MessageContext, filteredJson, true, true); + } } } } catch (Exception e) { @@ -61,7 +67,32 @@ public boolean mediate(MessageContext messageContext) { return true; } - public String findFilterSchema(String sp, String application, String api, String operation) throws Exception { + // compare the root elements of the payload according to the filter schema + private boolean isMatchingPayload(String jsonString, String filterSchema) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + JsonNode json = mapper.readTree(jsonString); + JsonNode schema = mapper.readTree(filterSchema); + String rootElementType = schema.findPath("type").asText(); + return !((json.isArray() != "array".equals(rootElementType)) || + ("object".equals(rootElementType) && !rootElementsMatched(json, schema))); + } + + private boolean rootElementsMatched(JsonNode json, JsonNode schema) { + Iterator properties = schema.findPath("properties").fieldNames(); + while (properties.hasNext()) { + String property = properties.next(); + if (json.has(property)) { + return true; + } + } + return false; + } + + private boolean isNonEmptyJson(String filteredJson) { + return filteredJson != null && !filteredJson.isEmpty() && !"{}".equals(filteredJson); + } + + public String findFilterSchema(String sp, String application, String api, String httpVerb, String resource) throws Exception { Connection connection = null; PreparedStatement statement = null; ResultSet resultSet = null; @@ -70,23 +101,25 @@ public String findFilterSchema(String sp, String application, String api, String try { connection = DbUtils.getDbConnection(DataSourceNames.WSO2TELCO_DEP_DB); if (connection == null) { - throw new Exception("database connection error"); + throw new SQLException("database connection error"); } - StringBuilder query = new StringBuilder("SELECT fields FROM response_filter"); - query.append(" WHERE sp=? AND application=? AND api=? AND operation=?"); + StringBuilder query = new StringBuilder("SELECT operation, fields FROM response_filter"); + query.append(" WHERE sp=? AND application=? AND api=?"); statement = connection.prepareStatement(query.toString()); statement.setString(1, sp); statement.setString(2, application); statement.setString(3, api); - statement.setString(4, operation); resultSet = statement.executeQuery(); - if (resultSet.next()) { - filterSchema = resultSet.getString(1); + while (resultSet.next()) { + String[] uriTemplateComponents = resultSet.getString(1).split(" "); + if (httpVerb != null && + httpVerb.equals(uriTemplateComponents[0]) && + new UriTemplate(uriTemplateComponents[1]).match(resource, new ArrayList())) { + filterSchema = resultSet.getString(2); + } } - } catch (Exception e) { - throw new Exception(e); } finally { DbUtils.closeAllConnections(statement, connection, resultSet); }