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

EXTGW-677 response filter code merge #762

Open
wants to merge 1 commit into
base: core-3.2.0-upgrade
Choose a base branch
from
Open
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 @@ -15,43 +15,49 @@
*/
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();

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) {
Expand All @@ -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<String> 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;
Expand All @@ -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<String>())) {
filterSchema = resultSet.getString(2);
}
}
} catch (Exception e) {
throw new Exception(e);
} finally {
DbUtils.closeAllConnections(statement, connection, resultSet);
}
Expand Down