changeset 640:513143f046c8

HttpMarkFilter
author Devel 2
date Tue, 07 Nov 2017 11:37:34 +0100
parents ed03df7b7bef
children 5d0230a77b38
files stress-tester/src/main/java/com/passus/st/client/http/HttpConsts.java stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMarkFilter.java stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessagePredicate.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMarkFilterTest.java
diffstat 4 files changed, 317 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/stress-tester/src/main/java/com/passus/st/client/http/HttpConsts.java	Mon Nov 06 10:53:32 2017 +0100
+++ b/stress-tester/src/main/java/com/passus/st/client/http/HttpConsts.java	Tue Nov 07 11:37:34 2017 +0100
@@ -13,6 +13,7 @@
     public static final String TAG_ORIG_SESSION_ID = "origSessionId";
     public static final String TAG_SESSION_ID = "sessionId";
     public static final String TAG_ZONE = "zone";
+    public static final String TAG_MARKER = "marker";
     public static final String TAG_HEADER_SIZE = "messageHeaderSize";
     public static final String TAG_CONTENT_SIZE = "messageContentSize";
     public static final String TAG_TIME_START = "timeStart";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMarkFilter.java	Tue Nov 07 11:37:34 2017 +0100
@@ -0,0 +1,232 @@
+package com.passus.st.client.http.filter;
+
+import com.passus.commons.Assert;
+import com.passus.commons.annotations.Plugin;
+import com.passus.config.CMapNode;
+import com.passus.config.CNode;
+import com.passus.config.CTupleNode;
+import com.passus.config.CValueNode;
+import com.passus.config.Configuration;
+import com.passus.config.ConfigurationUtils;
+import com.passus.config.annotations.NodeDefinitionCreate;
+import static com.passus.config.schema.ConfigurationSchemaBuilder.listDef;
+import static com.passus.config.schema.ConfigurationSchemaBuilder.mapDef;
+import static com.passus.config.schema.ConfigurationSchemaBuilder.tupleDef;
+import static com.passus.config.schema.ConfigurationSchemaBuilder.valueDef;
+import com.passus.config.schema.MapNodeDefinition;
+import com.passus.config.schema.NodeDefinition;
+import com.passus.config.schema.NodeDefinitionCreator;
+import com.passus.config.schema.NodeTransformer;
+import com.passus.config.validation.Errors;
+import com.passus.filter.config.PredicateNodeTransformer;
+import com.passus.net.http.HttpRequest;
+import com.passus.net.http.HttpResponse;
+import static com.passus.st.client.http.HttpConsts.TAG_MARKER;
+import com.passus.st.client.http.HttpFlowContext;
+import com.passus.st.filter.Transformers;
+import com.passus.st.plugin.PluginConstants;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Predicate;
+
+/**
+ *
+ * @author Mirosław Hawrot
+ */
+@NodeDefinitionCreate(HttpMarkFilter.HttpMarkFilterNodeDefCreator.class)
+@Plugin(name = HttpMarkFilter.TYPE, category = PluginConstants.CATEGORY_HTTP_FILTER)
+public class HttpMarkFilter extends HttpFilter {
+
+    public static final String TYPE = "marker";
+
+    private static final int DEFAULT_MARKERS_CAPACITY = 2;
+
+    private final List<MarkerRule> markRules;
+
+    public HttpMarkFilter() {
+        this.markRules = new ArrayList<>();
+    }
+
+    public HttpMarkFilter(List<MarkerRule> markRules) {
+        Assert.notContainsNull(markRules, "markRules");
+        this.markRules = new ArrayList<>(markRules);
+    }
+
+    public List<MarkerRule> getRules() {
+        return Collections.unmodifiableList(markRules);
+    }
+
+    public void addRule(MarkerRule rule) {
+        Assert.notNull(rule, "rule");
+        markRules.add(rule);
+    }
+
+    public boolean removeRule(MarkerRule rule) {
+        Assert.notNull(rule, "rule");
+        return markRules.remove(rule);
+    }
+
+    @Override
+    public HttpFilter instanceForWorker(int index) {
+        return new HttpMarkFilter(this.markRules);
+    }
+
+    @Override
+    public void configure(Configuration config) {
+        this.markRules.addAll((Collection<? extends MarkerRule>) config.get("rules", Collections.EMPTY_LIST));
+    }
+
+    @Override
+    public int filterInbound(HttpRequest req, HttpResponse resp, HttpFlowContext context) {
+        if (!markRules.isEmpty()) {
+            HttpMessageWrapper wrapper = new HttpMessageWrapper(req, resp, context);
+            for (MarkerRule rule : markRules) {
+                if (rule.predicate.test(wrapper)) {
+                    List<Marker> markers = (List<Marker>) req.getTag(TAG_MARKER);
+                    if (markers == null) {
+                        markers = new ArrayList<>(DEFAULT_MARKERS_CAPACITY);
+                        req.setTag(TAG_MARKER, markers);
+                    }
+
+                    markers.add(rule.getMarker());
+                }
+            }
+        }
+
+        return DUNNO;
+    }
+
+    public static class Marker {
+
+        private final String category;
+
+        private final String message;
+
+        public Marker(String category) {
+            this(category, null);
+        }
+
+        public Marker(String category, String message) {
+            Assert.notNull(category, "category");
+            this.category = category;
+            this.message = message;
+        }
+
+        public String getCategory() {
+            return category;
+        }
+
+        public String getMessage() {
+            return message;
+        }
+
+    }
+
+    public static class MarkerRule {
+
+        private final Marker marker;
+
+        private final HttpMessagePredicate predicate;
+
+        public MarkerRule(String category, HttpMessagePredicate predicate) {
+            this(new Marker(category), predicate);
+        }
+
+        public MarkerRule(String category, HttpMessagePredicate predicate, String message) {
+            this(new Marker(category, message), predicate);
+        }
+
+        public MarkerRule(Marker tag, HttpMessagePredicate predicate) {
+            Assert.notNull(tag, "tag");
+            Assert.notNull(predicate, "predicate");
+            this.marker = tag;
+            this.predicate = predicate;
+        }
+
+        public Marker getMarker() {
+            return marker;
+        }
+
+        public HttpMessagePredicate getPredicate() {
+            return predicate;
+        }
+
+    }
+
+    public static class HttpMarkFilterNodeDefCreator implements NodeDefinitionCreator {
+
+        @Override
+        public NodeDefinition create() {
+            MapNodeDefinition markerRuleNodeDef = mapDef(
+                    tupleDef("category", valueDef()),
+                    tupleDef("message", valueDef().setRequired(false)),
+                    tupleDef("applyIf", new HttpFilterMessagePredicateNodeDefinition())
+            ).setTransformer(new MarkerRuleNodeTransformer());
+
+            return mapDef(
+                    tupleDef("rules",
+                            listDef(markerRuleNodeDef)
+                    )
+            );
+        }
+
+    }
+
+    public static class MarkerRuleNodeTransformer implements NodeTransformer<CNode> {
+
+        private static final PredicateNodeTransformer PREDICATE_TRANS = Transformers.PREDICATE;
+
+        @Override
+        public CNode transform(CNode node, Errors errors) {
+            CMapNode mapNode = (CMapNode) node;
+            MarkerRule rule = null;
+            List<CTupleNode> tuples = mapNode.getChildren();
+            if (tuples.isEmpty()) {
+                return new CValueNode(null);
+            }
+
+            String category = null;
+            String message = null;
+            HttpMessagePredicate applyIf = null;
+
+            for (CTupleNode tuple : tuples) {
+                String opName = tuple.getName();
+                try {
+                    errors.pushNestedPath(opName);
+                    try {
+                        switch (opName.toLowerCase()) {
+                            case "category":
+                                category = ConfigurationUtils.extractString(tuple);
+                                break;
+                            case "message":
+                                message = ConfigurationUtils.extractString(tuple);
+                                break;
+                            case "applyif":
+                                Predicate predicate = PREDICATE_TRANS.transform(tuple.getNode());
+                                applyIf = new HttpMessagePredicate(predicate);
+                                break;
+                            default:
+                                throw new IllegalArgumentException("Unknwon parameter '" + opName + "'.");
+                        }
+                    } catch (Exception ex) {
+                        throw new IllegalArgumentException(ex.getMessage(), ex);
+                    }
+
+                } finally {
+                    errors.popNestedPath();
+                }
+            }
+
+            rule = new MarkerRule(category, applyIf, message);
+            return new CValueNode(rule);
+        }
+
+        @Override
+        public CNode reverseTransform(CNode node, Errors errors) {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+    }
+}
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessagePredicate.java	Mon Nov 06 10:53:32 2017 +0100
+++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessagePredicate.java	Tue Nov 07 11:37:34 2017 +0100
@@ -1,10 +1,14 @@
 package com.passus.st.client.http.filter;
 
 import com.passus.commons.Assert;
+import com.passus.commons.ConversionException;
+import com.passus.config.NodeException;
 import com.passus.net.http.HttpMessage;
 import com.passus.net.http.HttpRequest;
 import com.passus.net.http.HttpResponse;
 import com.passus.st.client.http.HttpFlowContext;
+import com.passus.st.filter.Transformers;
+import java.io.IOException;
 import java.util.function.Predicate;
 
 /**
@@ -48,4 +52,10 @@
     public String toString() {
         return predicate.toString();
     }
+
+    public static HttpMessagePredicate parse(String content) throws ConversionException, IOException, NodeException {
+        Predicate predicate = Transformers.PREDICATE.transform(content);
+        return new HttpMessagePredicate(predicate);
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMarkFilterTest.java	Tue Nov 07 11:37:34 2017 +0100
@@ -0,0 +1,74 @@
+package com.passus.st.client.http.filter;
+
+import com.passus.config.validation.Errors;
+import com.passus.net.http.HttpRequest;
+import com.passus.net.http.HttpRequestBuilder;
+import com.passus.st.AppUtils;
+import static com.passus.st.client.http.HttpConsts.TAG_MARKER;
+import com.passus.st.client.http.filter.HttpMarkFilter.Marker;
+import com.passus.st.client.http.filter.HttpMarkFilter.MarkerRule;
+import java.util.List;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Mirosław Hawrot
+ */
+public class HttpMarkFilterTest {
+
+    @BeforeClass
+    public static void beforeClass() {
+        AppUtils.registerAll();
+    }
+
+    @AfterClass
+    public static void afterClass() {
+        AppUtils.unregisterAll();
+    }
+
+    @Test
+    public void testFilterInbound() throws Exception {
+        HttpMessagePredicate predicate = HttpMessagePredicate.parse("{req.url: {$contains: test}}");
+        HttpMarkFilter filter = new HttpMarkFilter();
+        filter.addRule(new MarkerRule("category1", predicate));
+
+        HttpRequest req = HttpRequestBuilder.get("http://test/test").build();
+        filter.filterInbound(req, null, null);
+
+        List<Marker> markers = (List<Marker>) req.getTag(TAG_MARKER);
+        assertFalse(markers == null);
+        assertFalse(markers.isEmpty());
+        Marker marker = markers.get(0);
+
+        assertEquals("category1", marker.getCategory());
+    }
+
+    @Test
+    public void testConfigure() throws Exception {
+        String filterConfig = "filters:\n"
+                + "    - type: marker\n"
+                + "      rules:\n"
+                + "        - category: category1\n"
+                + "          message: message1\n"
+                + "          applyIf: {req.url: {$contains: test}}\n";
+
+        Errors errors = new Errors();
+        List<HttpFilter> filters = HttpFiltersConfigurator.getFilters(filterConfig, errors);
+
+        assertEquals(0, errors.getErrorCount());
+        assertEquals(1, filters.size());
+        assertTrue(filters.get(0) instanceof HttpMarkFilter);
+
+        HttpMarkFilter filter = (HttpMarkFilter) filters.get(0);
+        List<MarkerRule> rules = filter.getRules();
+        assertEquals(1, rules.size());
+
+        MarkerRule rule = rules.get(0);
+        assertEquals("category1", rule.getMarker().getCategory());
+        assertEquals("message1", rule.getMarker().getMessage());
+        assertFalse(rule.getPredicate() == null);
+    }
+}