diff options
author | Jorge Hernandez <jorge.hernandez-herrero@att.com> | 2019-02-22 13:25:42 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2019-02-22 13:25:42 +0000 |
commit | c150cf1a2327696e289c3a80ef28842f014b1866 (patch) | |
tree | 7cfa7224433a6841573e7942efdf199d007adebc /policy-management/src/main | |
parent | d914823eb7a992cd3410072970a2643c7d0c432c (diff) | |
parent | fa2a5a43c82cd35cca9e7d4b51f83ce70e1e3e59 (diff) |
Merge "Add Nested JSON Filtering"
Diffstat (limited to 'policy-management/src/main')
4 files changed, 203 insertions, 608 deletions
diff --git a/policy-management/src/main/java/org/onap/policy/drools/controller/DroolsControllerFactory.java b/policy-management/src/main/java/org/onap/policy/drools/controller/DroolsControllerFactory.java index 24fc6de9..16daa947 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/controller/DroolsControllerFactory.java +++ b/policy-management/src/main/java/org/onap/policy/drools/controller/DroolsControllerFactory.java @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -25,7 +25,6 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Properties; - import org.onap.policy.common.endpoints.event.comm.Topic; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; import org.onap.policy.common.endpoints.event.comm.TopicSink; @@ -38,7 +37,6 @@ import org.onap.policy.drools.protocol.coders.JsonProtocolFilter; import org.onap.policy.drools.protocol.coders.TopicCoderFilterConfiguration; import org.onap.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomGsonCoder; import org.onap.policy.drools.protocol.coders.TopicCoderFilterConfiguration.PotentialCoderFilter; -import org.onap.policy.drools.utils.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,11 +48,11 @@ public interface DroolsControllerFactory { /** * Constructs a Drools Controller based on properties. - * + * * @param properties properties containing initialization parameters * @param eventSources list of event sources * @param eventSinks list of event sinks - * + * * @return the instantiated Drools Controller * @throws IllegalArgumentException with invalid parameters * @throws LinkageError Failure to link rules and models in Drools Libraries @@ -64,13 +62,13 @@ public interface DroolsControllerFactory { /** * Explicit construction of a Drools Controller. - * + * * @param groupId maven group id of drools artifact * @param artifactId maven artifact id of drools artifact * @param version maven version id of drools artifact * @param decoderConfigurations list of decoder configurations * @param encoderConfigurations list of encoder configurations - * + * * @return the instantiated Drools Controller * @throws IllegalArgumentException with invalid parameters * @throws LinkageError Failure to link rules and models in Drools Libraries @@ -81,7 +79,7 @@ public interface DroolsControllerFactory { /** * Releases the Drools Controller from operation. - * + * * @param controller the Drools Controller to shut down */ public void shutdown(DroolsController controller); @@ -93,7 +91,7 @@ public interface DroolsControllerFactory { /** * Destroys and releases resources for a Drools Controller. - * + * * @param controller the Drools Controller to destroy */ public void destroy(DroolsController controller); @@ -105,11 +103,11 @@ public interface DroolsControllerFactory { /** * Gets the Drools Controller associated with the maven group and artifact id. - * + * * @param groupId maven group id of drools artifact * @param artifactId maven artifact id of drools artifact * @param version maven version id of drools artifact - * + * * @return the Drools Controller * @throws IllegalArgumentException with invalid parameters */ @@ -117,7 +115,7 @@ public interface DroolsControllerFactory { /** * returns the current inventory of Drools Controllers. - * + * * @return a list of Drools Controllers */ public List<DroolsController> inventory(); @@ -208,7 +206,7 @@ class IndexedDroolsControllerFactory implements DroolsControllerFactory { /* * The Null Drools Controller for no maven coordinates is always here so when no * coordinates present, this is the return point - * + * * assert (controllerCopy instanceof NullDroolsController) */ if (droolsControllers.containsKey(controllerId)) { @@ -245,7 +243,7 @@ class IndexedDroolsControllerFactory implements DroolsControllerFactory { /** * find out decoder classes and filters. - * + * * @param properties properties with information about decoders * @param topicEntities topic sources * @return list of topics, each with associated decoder classes, each with a list of associated @@ -313,7 +311,7 @@ class IndexedDroolsControllerFactory implements DroolsControllerFactory { // 3. second the list of classes associated with each topic String eventClasses = properties - .getProperty(propertyTopicEntityPrefix + firstTopic + .getProperty(propertyTopicEntityPrefix + firstTopic + PolicyEndPointProperties.PROPERTY_TOPIC_EVENTS_SUFFIX); if (eventClasses == null || eventClasses.isEmpty()) { @@ -328,54 +326,14 @@ class IndexedDroolsControllerFactory implements DroolsControllerFactory { for (String theClass : topicClasses) { - // 4. third, for each coder class, get the list of field filters + // 4. third, for each coder class, get the filter expression String filter = properties - .getProperty(propertyTopicEntityPrefix + firstTopic + .getProperty(propertyTopicEntityPrefix + firstTopic + PolicyEndPointProperties.PROPERTY_TOPIC_EVENTS_SUFFIX + "." + theClass + PolicyEndPointProperties.PROPERTY_TOPIC_EVENTS_FILTER_SUFFIX); - List<Pair<String, String>> filters = new ArrayList<>(); - - if (filter == null || filter.isEmpty()) { - // 4. topic -> class -> with no filters - - JsonProtocolFilter protocolFilter = JsonProtocolFilter.fromRawFilters(filters); - PotentialCoderFilter class2Filters = new PotentialCoderFilter(theClass, protocolFilter); - classes2Filters.add(class2Filters); - continue; - } - - // There are filters associated with the applicability of - // this class for decoding. - List<String> listOfFilters = new ArrayList<>(Arrays.asList(filter.split("\\s*,\\s*"))); - - for (String nameValue : listOfFilters) { - String fieldName; - String regexValue; - - String[] nameValueSplit = nameValue.split("\\s*=\\s*"); - if (nameValueSplit.length <= 0 || nameValueSplit.length > 2) { - // TODO warn - // skip - continue; - } - - if (nameValueSplit.length == 2) { - fieldName = nameValueSplit[0]; - regexValue = nameValueSplit[1]; - } else if (nameValueSplit.length == 1) { - fieldName = nameValueSplit[0]; - regexValue = null; - } else { - // unreachable - continue; - } - - filters.add(new Pair<String, String>(fieldName, regexValue)); - } - - JsonProtocolFilter protocolFilter = JsonProtocolFilter.fromRawFilters(filters); + JsonProtocolFilter protocolFilter = new JsonProtocolFilter(filter); PotentialCoderFilter class2Filters = new PotentialCoderFilter(theClass, protocolFilter); classes2Filters.add(class2Filters); } @@ -408,7 +366,7 @@ class IndexedDroolsControllerFactory implements DroolsControllerFactory { /** * unmanage the drools controller. - * + * * @param controller the controller */ protected void unmanage(DroolsController controller) { diff --git a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/JsonProtocolFilter.java b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/JsonProtocolFilter.java index f65efaed..2ccc010f 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/JsonProtocolFilter.java +++ b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/JsonProtocolFilter.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,378 +20,120 @@ package org.onap.policy.drools.protocol.coders; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.Option; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; -import org.onap.policy.drools.utils.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * JSON Protocol Filter. - */ +/** JSON Protocol Filter. */ public class JsonProtocolFilter { - private static final String MISSING_RULE_NAME = "no rule name provided"; - /** - * Logger. - */ - private static final Logger logger = LoggerFactory.getLogger(JsonProtocolFilter.class); - - /** - * Helper class to collect Filter information. - */ - public static class FilterRule { - /** - * Field name. - */ - private String name; - - /** - * Field Value regex. - */ - private String regex; - - /** - * Filter Constructor. - * - * @param name field name - * @param regex field regex value - */ - public FilterRule(String name, String regex) { - this.setName(name); - this.setRegex(regex); - } - - /** - * Default constructor (for serialization only). - */ - public FilterRule() { - super(); - } - - /** - * gets name. - * - * @return name - */ - public String getName() { - return name; - } - - /** - * gets regex. - * - * @return regular expression string - */ - public String getRegex() { - return regex; - } - - /** - * Sets field name. - * - * @param name field name - */ - public void setName(String name) { - if (name == null || name.isEmpty()) { - throw new IllegalArgumentException("filter field name must be provided"); - } - - this.name = name; - } - - /** - * sets regex name. - * - * @param regex expression - */ - public void setRegex(String regex) { - if (regex == null || regex.isEmpty()) { - this.regex = ".*"; - } - - this.regex = regex; - } + /** Default filter to match anything. */ + public static final String MATCH_ANY = "[?($ =~ /.*/)]"; - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("Filter [name=").append(name).append(", regex=").append(regex).append("]"); - return builder.toString(); - } - } + /** Logger. */ + private static final Logger logger = LoggerFactory.getLogger(JsonProtocolFilter.class); - /** - * all the filters to be applied. - */ - protected List<FilterRule> rules = new CopyOnWriteArrayList<>(); + /** A rule based on a JsonPath expression that is used for filtering. */ + private String rule; /** - * Create a Protocol Filter. - * - * @throws IllegalArgumentException an invalid input has been provided + * Default constructor (for serialization only). */ public JsonProtocolFilter() { super(); + this.setRule(null); } /** * Constructor. - * - * @param filters filter list - * - * @throws IllegalArgumentException an invalid input has been provided - */ - public JsonProtocolFilter(List<FilterRule> filters) { - List<FilterRule> temp = new ArrayList<>(); - for (FilterRule rule : filters) { - if (rule.getName() == null || rule.getName().isEmpty()) { - continue; - } - - if (rule.getRegex() == null || rule.getRegex().isEmpty()) { - rule.setRegex(".*"); - } - - temp.add(rule); - } - - this.rules.addAll(temp); - } - - /** - * From raw filters. - * - * @param rawFilters raw filter initialization - * + * + * @param rule the JsonPath expression used for the filter rule * @throws IllegalArgumentException an invalid input has been provided */ - public static JsonProtocolFilter fromRawFilters(List<Pair<String, String>> rawFilters) { - - if (rawFilters == null) { - throw new IllegalArgumentException("No raw filters provided"); - } - - List<FilterRule> filters = new ArrayList<>(); - for (Pair<String, String> filterPair: rawFilters) { - if (filterPair.first() == null || filterPair.first().isEmpty()) { - continue; - } - - filters.add(new FilterRule(filterPair.first(), filterPair.second())); - } - return new JsonProtocolFilter(filters); + public JsonProtocolFilter(String rule) { + this.setRule(rule); } /** - * are there any filters. - * - * @return true if there are filters, false otherwise + * Gets the filter expression rule. + * + * @return the filter expression associated with this JsonProtocolFilter */ - public boolean isRules() { - return !this.rules.isEmpty(); + public String getRule() { + return this.rule; } /** - * accept a JSON string as conformant it if passes all filters. - * - * @param json json is a JSON object - * @return true if json string is conformant - * - * @throws IllegalArgumentException an invalid input has been provided + * Sets the filter expression rule. + * + * @param rule the JsonPath expression rule */ - public boolean accept(JsonElement json) { - if (json == null) { - throw new IllegalArgumentException("no JSON provided"); - } - - if (!json.isJsonObject()) { - return false; - } - - if (rules.isEmpty()) { - return true; - } - - try { - JsonObject event = json.getAsJsonObject(); - for (FilterRule filter: rules) { - if (filter.getRegex() == null - || filter.getRegex().isEmpty() - || ".*".equals(filter.getRegex())) { - - // Only check for presence - if (!event.has(filter.getName())) { - return false; - } - } else { - JsonElement field = event.get(filter.getName()); - if (field == null) { - return false; - } - - String fieldValue = field.getAsString(); - if (!fieldValue.matches(filter.getRegex())) { - return false; - } - } - } - return true; - } catch (Exception e) { - throw new IllegalArgumentException(e); + public void setRule(String rule) { + String ruleExpression = rule; + if (rule == null || rule.isEmpty()) { + ruleExpression = MATCH_ANY; } + this.rule = ruleExpression; } /** - * Accept a JSON string as conformant it if passes all filters. - * - * @param json json string - * @return true if json string is conformant - * - * @throws IllegalArgumentException an invalid input has been provided + * Accepts a JSON message if there is a match on the filter expression. + * + * @return true if a match is found or the rule uses the match any policy, false otherwise */ public boolean accept(String json) { - if (json == null || json.isEmpty()) { - throw new IllegalArgumentException("no JSON provided"); - } - - if (rules.isEmpty()) { + if (MATCH_ANY.equals(this.rule)) { return true; } - - try { - JsonElement element = new JsonParser().parse(json); - if (element == null || !element.isJsonObject()) { - return false; - } - - return this.accept(element.getAsJsonObject()); - } catch (IllegalArgumentException ile) { - throw ile; - } catch (Exception e) { - logger.info("{}: cannot accept {} because of {}", - this, json, e.getMessage(), e); - throw new IllegalArgumentException(e); - } - } - - public List<FilterRule> getRules() { - return new ArrayList<>(this.rules); + return !filter(json).isEmpty(); } /** - * Get rules. - * - * @param name name - * @return list of filter rules + * Finds a field based on a path or a subset of the JSON if using an expression. + * + * @param json the JSON string to be parsed + * @return a list of strings that match the expression */ - public List<FilterRule> getRules(String name) { - if (name == null || name.isEmpty()) { - throw new IllegalArgumentException(MISSING_RULE_NAME); - } - - ArrayList<FilterRule> temp = new ArrayList<>(); - for (FilterRule rule : this.rules) { - if (rule.getName().equals(name)) { - temp.add(rule); - } - } - return temp; + public List<String> filter(String json) { + return filter(json, this.rule); } /** - * Set Rules. - * - * @param rulesFilters filters + * Finds all occurrences of a field in a JSON document based on the JsonPath + * expression. + * + * @param json the JSON string to be parsed + * @param expression the JsonPath expression + * @return a list of matches from the JSON document */ - public void setRules(List<FilterRule> rulesFilters) { - if (rulesFilters == null) { - throw new IllegalArgumentException("no rules provided"); - } - - this.rules.clear(); - this.rules.addAll(rulesFilters); - } - - /** - * Delete rules. - * - * @param name name - */ - public void deleteRules(String name) { - if (name == null || name.isEmpty()) { - throw new IllegalArgumentException(MISSING_RULE_NAME); - } - - List<FilterRule> temp = new ArrayList<>(); - for (FilterRule rule : this.rules) { - if (rule.name.equals(name)) { - temp.add(rule); - } - } - this.rules.removeAll(temp); - } - - /** - * Delete rule. - * - * @param name name - * @param regex regex - */ - public void deleteRule(String name, String regex) { - if (name == null || name.isEmpty()) { - throw new IllegalArgumentException(MISSING_RULE_NAME); - } - - String nonNullRegex = regex; - if (regex == null || regex.isEmpty()) { - nonNullRegex = ".*"; + public static List<String> filter(String json, String expression) { + if (json == null || json.isEmpty()) { + throw new IllegalArgumentException("a json string must be provided"); } - List<FilterRule> temp = new ArrayList<>(); - for (FilterRule rule : this.rules) { - if (rule.name.equals(name) && rule.getRegex().equals(nonNullRegex)) { - temp.add(rule); - } + if (expression == null || expression.isEmpty()) { + throw new IllegalArgumentException("an expression must be provided"); } - this.rules.removeAll(temp); - } - - /** - * Add rule. - * - * @param name name - * @param regex regex - */ - public void addRule(String name, String regex) { - if (name == null || name.isEmpty()) { - throw new IllegalArgumentException(MISSING_RULE_NAME); - } + Configuration conf = Configuration.defaultConfiguration().addOptions(Option.ALWAYS_RETURN_LIST); + DocumentContext document = JsonPath.using(conf).parse(json); - String nonNullRegex = regex; - if (regex == null || regex.isEmpty()) { - nonNullRegex = ".*"; + List<String> matches = new ArrayList<>(); + try { + matches = document.read(expression); + } catch (Exception e) { + logger.error("JsonPath couldn't read {} because of {}", expression, e.getMessage(), e); } - for (FilterRule rule : this.rules) { - if (rule.getName().equals(name) && rule.getRegex().equals(regex)) { - return; - } + if (matches.isEmpty()) { + logger.warn("Could not find any matches for rule {} in json {}", expression, json); } - this.rules.add(new FilterRule(name, nonNullRegex)); + return matches; } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("JsonProtocolFilter [rules=").append(rules).append("]"); - return builder.toString(); - } - } diff --git a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolset.java b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolset.java index f125c134..394e73af 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolset.java +++ b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/ProtocolCoderToolset.java @@ -31,7 +31,6 @@ import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; - import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; @@ -168,7 +167,7 @@ public abstract class ProtocolCoderToolset { /** * remove coder. - * + * * @param eventClass event class */ public void removeCoders(String eventClass) { @@ -206,7 +205,7 @@ public abstract class ProtocolCoderToolset { /** * Get group id. - * + * * @return the groupId */ public String getGroupId() { @@ -215,7 +214,7 @@ public abstract class ProtocolCoderToolset { /** * Get artifact id. - * + * * @return the artifactId */ public String getArtifactId() { @@ -224,7 +223,7 @@ public abstract class ProtocolCoderToolset { /** * Get custom coder. - * + * * @return the customCoder */ public CustomCoder getCustomCoder() { @@ -233,7 +232,7 @@ public abstract class ProtocolCoderToolset { /** * Set custom coder. - * + * * @param customCoder the customCoder to set. */ public void setCustomCoder(CustomCoder customCoder) { @@ -262,28 +261,14 @@ public abstract class ProtocolCoderToolset { throw new IllegalStateException("No coders available"); } - if (this.coders.size() == 1) { - final JsonProtocolFilter filter = this.coders.get(0).getFilter(); - if (!filter.isRules()) { - return this.coders.get(0); - } - } - - JsonElement event; - try { - event = this.filteringParser.parse(json); - } catch (final Exception e) { - throw new UnsupportedOperationException(e); - } - for (final CoderFilters decoder : this.coders) { try { - final boolean accepted = decoder.getFilter().accept(event); + boolean accepted = decoder.getFilter().accept(json); if (accepted) { return decoder; } } catch (final Exception e) { - logger.info("{}: unexpected failure accepting {} because of {}", this, event, + logger.info("{}: unexpected failure accepting {} because of {}", this, json, e.getMessage(), e); // continue } @@ -325,8 +310,6 @@ public abstract class ProtocolCoderToolset { } } - - /** * Tools used for encoding/decoding using GSON. */ diff --git a/policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java b/policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java index 64fd6823..cbe2b339 100644 --- a/policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java +++ b/policy-management/src/main/java/org/onap/policy/drools/server/restful/RestManager.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * policy-management * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,8 +36,6 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.UUID; -import java.util.regex.Pattern; - import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; @@ -51,7 +49,6 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; - import org.onap.policy.common.endpoints.event.comm.TopicEndpoint; import org.onap.policy.common.endpoints.event.comm.TopicSink; import org.onap.policy.common.endpoints.event.comm.TopicSource; @@ -67,7 +64,6 @@ import org.onap.policy.drools.properties.DroolsProperties; import org.onap.policy.drools.protocol.coders.EventProtocolCoder; import org.onap.policy.drools.protocol.coders.EventProtocolCoder.CoderFilters; import org.onap.policy.drools.protocol.coders.JsonProtocolFilter; -import org.onap.policy.drools.protocol.coders.JsonProtocolFilter.FilterRule; import org.onap.policy.drools.protocol.coders.ProtocolCoderToolset; import org.onap.policy.drools.protocol.configuration.ControllerConfiguration; import org.onap.policy.drools.protocol.configuration.PdpdConfiguration; @@ -77,7 +73,6 @@ import org.onap.policy.drools.utils.logging.LoggerUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - /** * Telemetry JAX-RS Interface to the PDP-D. */ @@ -98,7 +93,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -111,7 +106,7 @@ public class RestManager { /** * DELETE. - * + * * @return response object */ @DELETE @@ -132,7 +127,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -154,7 +149,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -175,7 +170,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -187,7 +182,7 @@ public class RestManager { /** * POST. - * + * * @return response object */ @POST @@ -216,7 +211,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -229,7 +224,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -242,7 +237,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -257,7 +252,7 @@ public class RestManager { /** * PUT. - * + * * @return response object */ @PUT @@ -274,7 +269,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -287,7 +282,7 @@ public class RestManager { /** * PUT. - * + * * @return response object */ @PUT @@ -315,7 +310,7 @@ public class RestManager { /** * DELETE. - * + * * @return response object */ @DELETE @@ -343,7 +338,7 @@ public class RestManager { /** * PUT. - * + * * @return response object */ @PUT @@ -364,7 +359,7 @@ public class RestManager { /** * DELETE. - * + * * @return response object */ @DELETE @@ -385,7 +380,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -398,7 +393,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -411,7 +406,7 @@ public class RestManager { /** * POST. - * + * * @return response object */ @POST @@ -479,7 +474,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -492,7 +487,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -506,7 +501,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -528,7 +523,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -557,7 +552,7 @@ public class RestManager { /** * DELETE. - * + * * @return response object */ @DELETE @@ -604,7 +599,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -632,7 +627,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -644,7 +639,7 @@ public class RestManager { /** * POST. - * + * * @return response object */ @POST @@ -688,7 +683,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -701,7 +696,7 @@ public class RestManager { /** * PUT. - * + * * @return response object */ @PUT @@ -724,7 +719,7 @@ public class RestManager { /** * DELETE. - * + * * @return response object */ @DELETE @@ -747,7 +742,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -775,7 +770,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -807,7 +802,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -836,7 +831,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -875,7 +870,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -928,7 +923,7 @@ public class RestManager { /** * POST. - * + * * @return response object */ @POST @@ -985,7 +980,7 @@ public class RestManager { /** * DELETE. - * + * * @return response object */ @DELETE @@ -1027,7 +1022,7 @@ public class RestManager { /** * DELETE. - * + * * @return response object */ @DELETE @@ -1085,29 +1080,21 @@ public class RestManager { /** * POST. - * + * * @return response object */ @POST - @Path("engine/controllers/tools/coders/decoders/filters/rules/{ruleName}") + @Path("engine/controllers/tools/coders/decoders/filters/rule") @ApiOperation(value = "Produces a Decoder Rule Filter in a format that the Policy Controller can understand", notes = "The result can be used with other APIs to attach a filter to a decoder") public Response rules( - @ApiParam(value = "Negate regex?", - required = true) @DefaultValue("false") @QueryParam("negate") boolean negate, - @ApiParam(value = "Rule Name", required = true) @PathParam("ruleName") String name, - @ApiParam(value = "Regex expression", required = true) String regex) { - String literalRegex = Pattern.quote(regex); - if (negate) { - literalRegex = "^(?!" + literalRegex + "$).*"; - } - - return Response.status(Status.OK).entity(new JsonProtocolFilter.FilterRule(name, literalRegex)).build(); + @ApiParam(value = "JsonPath expression", required = true) String expression) { + return Response.status(Status.OK).entity(new JsonProtocolFilter(expression)).build(); } /** * GET. - * + * * @return response object */ @GET @@ -1142,7 +1129,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1178,7 +1165,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1215,7 +1202,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1258,7 +1245,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1303,7 +1290,7 @@ public class RestManager { /** * PUT. - * + * * @return response object */ @PUT @@ -1359,17 +1346,16 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET - @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rules") - @ApiOperation(value = "Gets the filter rules attached to a topic decoder of a controller", + @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rule") + @ApiOperation(value = "Gets the filter rule attached to a topic decoder of a controller", notes = "Decoders are associated with networked topics. A Policy Controller manages " + "multiple topics and therefore its attached decoders. " + "A Policy Controller uses filters to further specify the fact mapping. " - + "Filters are applied on a per fact type and are composed of field matching rules. ", - responseContainer = "List", response = FilterRule.class) + + "Filters are applied on a per fact type using a jsonpath expression rule. ") @ApiResponses(value = {@ApiResponse(code = 404, message = "The controller, topic, or fact type cannot be found"), @ApiResponse(code = 406, message = "The system is an administrative state that prevents " + "this request to be fulfilled")}) @@ -1394,7 +1380,7 @@ public class RestManager { .entity(new Error(controllerName + ":" + topic + ":" + factClass + " no filters")).build(); } - return Response.status(Response.Status.OK).entity(filter.getRules()).build(); + return Response.status(Response.Status.OK).entity(filter.getRule()).build(); } catch (final IllegalArgumentException e) { logger.debug("{}: cannot get decoder filters for policy-controller {} topic {} type {} because of {}", this, controllerName, topic, factClass, e.getMessage(), e); @@ -1409,86 +1395,25 @@ public class RestManager { } /** - * GET. - * - * @return response object - */ - @GET - @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rules/{ruleName}") - @ApiOperation(value = "Gets a filter rule by name attached to a topic decoder of a controller", - notes = "Decoders are associated with networked topics. A Policy Controller manages " - + "multiple topics and therefore its attached decoders. " - + "A Policy Controller uses filters to further specify the fact mapping. " - + "Filters are applied on a per fact type and are composed of field matching rules. ", - responseContainer = "List", response = FilterRule.class) - @ApiResponses(value = { - @ApiResponse(code = 404, message = "The controller, topic, fact type, or rule name cannot be found"), - @ApiResponse(code = 406, - message = "The system is an administrative state that prevents " + "this request to be fulfilled")}) - public Response decoderFilterRules( - @ApiParam(value = "Policy Controller Name", required = true) @PathParam("controller") String controllerName, - @ApiParam(value = "Topic Name", required = true) @PathParam("topic") String topic, - @ApiParam(value = "Fact Type", required = true) @PathParam("factType") String factClass, - @ApiParam(value = "Rule Name", required = true) @PathParam("ruleName") String ruleName) { - try { - final DroolsController drools = this.getDroolsController(controllerName); - final ProtocolCoderToolset decoder = - EventProtocolCoder.manager.getDecoders(drools.getGroupId(), drools.getArtifactId(), topic); - - final CoderFilters filters = decoder.getCoder(factClass); - if (filters == null) { - return Response.status(Response.Status.BAD_REQUEST) - .entity(new Error(controllerName + ":" + topic + ":" + factClass + " does not exist")).build(); - } - - final JsonProtocolFilter filter = filters.getFilter(); - if (filter == null) { - return Response.status(Response.Status.BAD_REQUEST) - .entity(new Error(controllerName + ":" + topic + ":" + factClass + " no filters")).build(); - } - - return Response.status(Response.Status.OK).entity(filter.getRules(ruleName)).build(); - } catch (final IllegalArgumentException e) { - logger.debug( - "{}: cannot get decoder filters for policy-controller {} topic {} type {} rule {} because of {}", - this, controllerName, topic, factClass, ruleName, e.getMessage(), e); - return Response.status(Response.Status.NOT_FOUND) - .entity(new Error(controllerName + ":" + topic + ":" + factClass + ": " + ruleName + " not found")) - .build(); - } catch (final IllegalStateException e) { - logger.debug( - "{}: cannot get decoder filters for policy-controller {} topic {} type {} rule {} because of {}", - this, controllerName, topic, factClass, ruleName, e.getMessage(), e); - return Response.status(Response.Status.NOT_ACCEPTABLE) - .entity(new Error( - controllerName + ":" + topic + ":" + factClass + ":" + ruleName + " not acceptable")) - .build(); - } - } - - /** * DELETE. - * + * * @return response object */ @DELETE - @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rules/{ruleName}") - @ApiOperation(value = "Deletes a filter rule by name attached to a topic decoder of a controller", + @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rule") + @ApiOperation(value = "Deletes the filter rule attached to a topic decoder of a controller", notes = "Decoders are associated with networked topics. A Policy Controller manages " + "multiple topics and therefore its attached decoders. " + "A Policy Controller uses filters to further specify the fact mapping. " - + "Filters are applied on a per fact type and are composed of field matching rules. ", - responseContainer = "List", response = FilterRule.class) + + "Filters are applied on a per fact type using a jsonpath expression rule. ") @ApiResponses(value = { - @ApiResponse(code = 404, message = "The controller, topic, fact type, or rule name cannot be found"), + @ApiResponse(code = 404, message = "The controller, topic, or fact type cannot be found"), @ApiResponse(code = 406, message = "The system is an administrative state that prevents " + "this request to be fulfilled")}) public Response decoderFilterRuleDelete( @ApiParam(value = "Policy Controller Name", required = true) @PathParam("controller") String controllerName, @ApiParam(value = "Topic Name", required = true) @PathParam("topic") String topic, - @ApiParam(value = "Fact Type", required = true) @PathParam("factType") String factClass, - @ApiParam(value = "Rule Name", required = true) @PathParam("ruleName") String ruleName, - @ApiParam(value = "Filter Rule", required = true) FilterRule rule) { + @ApiParam(value = "Fact Type", required = true) @PathParam("factType") String factClass) { try { final DroolsController drools = this.getDroolsController(controllerName); @@ -1507,50 +1432,38 @@ public class RestManager { .entity(new Error(controllerName + ":" + topic + ":" + factClass + " no filters")).build(); } - if (rule == null) { - filter.deleteRules(ruleName); - return Response.status(Response.Status.OK).entity(filter.getRules()).build(); - } - - if (rule.getName() == null || !rule.getName().equals(ruleName)) { - return Response.status(Response.Status.BAD_REQUEST).entity(new Error(controllerName + ":" + topic + ":" - + factClass + ":" + ruleName + " rule name request inconsistencies (" + rule.getName() + ")")) - .build(); - } - - filter.deleteRule(ruleName, rule.getRegex()); - return Response.status(Response.Status.OK).entity(filter.getRules()).build(); + filter.setRule(null); + return Response.status(Response.Status.OK).entity(filter.getRule()).build(); } catch (final IllegalArgumentException e) { logger.debug( - "{}: cannot get decoder filters for policy-controller {} topic {} type {} rule {} because of {}", - this, controllerName, topic, factClass, ruleName, e.getMessage(), e); + "{}: cannot get decoder filters for policy-controller {} topic {} type {} because of {}", + this, controllerName, topic, factClass, e.getMessage(), e); return Response.status(Response.Status.NOT_FOUND) - .entity(new Error(controllerName + ":" + topic + ":" + factClass + ": " + ruleName + " not found")) + .entity(new Error(controllerName + ":" + topic + ":" + factClass + " not found")) .build(); } catch (final IllegalStateException e) { logger.debug( - "{}: cannot get decoder filters for policy-controller {} topic {} type {} rule {} because of {}", - this, controllerName, topic, factClass, ruleName, e.getMessage(), e); + "{}: cannot get decoder filters for policy-controller {} topic {} type {} because of {}", + this, controllerName, topic, factClass, e.getMessage(), e); return Response.status(Response.Status.NOT_ACCEPTABLE) .entity(new Error( - controllerName + ":" + topic + ":" + factClass + ":" + ruleName + " not acceptable")) + controllerName + ":" + topic + ":" + factClass + " not acceptable")) .build(); } } /** * PUT. - * + * * @return response object */ @PUT - @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rules") + @Path("engine/controllers/{controller}/decoders/{topic}/filters/{factType}/rule") @ApiOperation(value = "Places a new filter rule in a topic decoder", notes = "Decoders are associated with networked topics. A Policy Controller manages " + "multiple topics and therefore its attached decoders. " + "A Policy Controller uses filters to further specify the fact mapping. " - + "Filters are applied on a per fact type and are composed of field matching rules. ", - responseContainer = "List", response = FilterRule.class) + + "Filters are applied on a per fact type using a jsonpath expression rule. ") @ApiResponses(value = {@ApiResponse(code = 404, message = "The controller, topic, or fact type cannot be found"), @ApiResponse(code = 406, message = "The system is an administrative state that prevents " + "this request to be fulfilled")}) @@ -1558,8 +1471,7 @@ public class RestManager { @ApiParam(value = "Policy Controller Name", required = true) @PathParam("controller") String controllerName, @ApiParam(value = "Topic Name", required = true) @PathParam("topic") String topic, @ApiParam(value = "Fact Type", required = true) @PathParam("factType") String factClass, - @ApiParam(value = "Rule Name", required = true) @PathParam("ruleName") String ruleName, - @ApiParam(value = "Filter Rule", required = true) FilterRule rule) { + @ApiParam(value = "JsonPath filter expression", required = true) String rule) { try { final DroolsController drools = this.getDroolsController(controllerName); @@ -1578,25 +1490,25 @@ public class RestManager { .entity(new Error(controllerName + ":" + topic + ":" + factClass + " no filters")).build(); } - if (rule.getName() == null) { + if (rule == null || rule.isEmpty()) { return Response.status(Response.Status.BAD_REQUEST).entity(new Error(controllerName + ":" + topic + ":" - + factClass + " rule name request inconsistencies (" + rule.getName() + ")")).build(); + + factClass + " no filter rule provided")).build(); } - filter.addRule(rule.getName(), rule.getRegex()); - return Response.status(Response.Status.OK).entity(filter.getRules()).build(); + filter.setRule(rule); + return Response.status(Response.Status.OK).entity(filter.getRule()).build(); } catch (final IllegalArgumentException e) { logger.debug( "{}: cannot access decoder filter rules for policy-controller {} " - + "topic {} type {} rule {} because of {}", - this, controllerName, topic, factClass, ruleName, e.getMessage(), e); + + "topic {} type {} because of {}", + this, controllerName, topic, factClass, e.getMessage(), e); return Response.status(Response.Status.NOT_FOUND) - .entity(new Error(controllerName + ":" + topic + ":" + factClass + " not found")).build(); + .entity(new Error(controllerName + ":" + topic + " not found")).build(); } catch (final IllegalStateException e) { logger.debug( "{}: cannot access decoder filter rules for policy-controller {} " - + "topic {} type {} rule {} because of {}", - this, controllerName, topic, factClass, ruleName, e.getMessage(), e); + + "topic {} type {} because of {}", + this, controllerName, topic, factClass, e.getMessage(), e); return Response.status(Response.Status.NOT_ACCEPTABLE) .entity(new Error(controllerName + ":" + topic + ":" + factClass + " not acceptable")).build(); } @@ -1604,7 +1516,7 @@ public class RestManager { /** * POST. - * + * * @return response object */ @POST @@ -1665,7 +1577,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1715,7 +1627,7 @@ public class RestManager { /** * PUT. - * + * * @return response object */ @PUT @@ -1735,7 +1647,7 @@ public class RestManager { /** * DELETE. - * + * * @return response object */ @DELETE @@ -1755,7 +1667,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1768,7 +1680,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1781,7 +1693,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1794,7 +1706,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1807,7 +1719,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1820,7 +1732,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1833,7 +1745,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1847,7 +1759,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1861,7 +1773,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1876,7 +1788,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1890,7 +1802,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1905,7 +1817,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1920,7 +1832,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1936,7 +1848,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1951,7 +1863,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1964,7 +1876,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1977,7 +1889,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -1991,7 +1903,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -2004,7 +1916,7 @@ public class RestManager { /** * PUT. - * + * * @return response object */ @PUT @@ -2024,7 +1936,7 @@ public class RestManager { /** * DELETE. - * + * * @return response object */ @DELETE @@ -2048,7 +1960,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -2061,7 +1973,7 @@ public class RestManager { /** * PUT. - * + * * @return response object */ @PUT @@ -2081,7 +1993,7 @@ public class RestManager { /** * DELETE. - * + * * @return response object */ @DELETE @@ -2102,7 +2014,7 @@ public class RestManager { /** * PUT. - * + * * @return response object */ @PUT @@ -2146,7 +2058,7 @@ public class RestManager { /** * PUT. - * + * * @return response object */ @PUT @@ -2190,7 +2102,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -2203,7 +2115,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -2227,7 +2139,7 @@ public class RestManager { /** * GET. - * + * * @return response object */ @GET @@ -2255,7 +2167,7 @@ public class RestManager { /** * PUT. - * + * * @return response object */ @PUT |