changeset 1015:518e5e10d714

Filters generalization in progress
author Devel 2
date Wed, 25 Mar 2020 11:32:36 +0100
parents 6be220a546db
children d25e9c9f0e28
files stress-tester/src/main/java/com/passus/st/client/filter/FilterDirection.java stress-tester/src/main/java/com/passus/st/client/filter/MatchFilter.java stress-tester/src/main/java/com/passus/st/client/filter/MvelFilter.java stress-tester/src/main/java/com/passus/st/client/http/filter/HttpFilterDirection.java stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMatchFilter.java stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessageModificationFilter.java stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMvelFilter.java stress-tester/src/main/java/com/passus/st/client/http/filter/HttpScopeModificationFilter.java stress-tester/src/test/java/com/passus/st/ConverterHttpClientTest.java stress-tester/src/test/java/com/passus/st/client/filter/CounterFilterTest.java stress-tester/src/test/java/com/passus/st/client/filter/FilterTestUtils.java stress-tester/src/test/java/com/passus/st/client/filter/MatchFilterTest.java stress-tester/src/test/java/com/passus/st/client/filter/MvelFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpBasicAuthLoginFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpCsrfFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpCsrfFormFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpDigestAuthLoginFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpFilterTestUtils.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpFormLoginFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpLogoutFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMatchFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTransformerTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMvelFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpScopeModificationFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpSequenceFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpSessionBlockerFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpSessionCookieFilterTest.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpZoneFilterTest.java stress-tester/src/test/java/com/passus/st/utils/Assert.java
diffstat 30 files changed, 691 insertions(+), 614 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/client/filter/FilterDirection.java	Wed Mar 25 11:32:36 2020 +0100
@@ -0,0 +1,11 @@
+package com.passus.st.client.filter;
+
+/**
+ *
+ * @author Mirosław Hawrot
+ */
+public enum FilterDirection {
+
+    IN, OUT, BOTH
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/client/filter/MatchFilter.java	Wed Mar 25 11:32:36 2020 +0100
@@ -0,0 +1,94 @@
+package com.passus.st.client.filter;
+
+import com.passus.commons.Assert;
+import com.passus.commons.annotations.Plugin;
+import com.passus.config.Configuration;
+import com.passus.config.ConfigurationContext;
+import com.passus.config.annotations.NodeDefinitionCreate;
+import com.passus.config.schema.NodeDefinition;
+import com.passus.config.schema.NodeDefinitionCreator;
+import com.passus.st.client.FlowContext;
+import com.passus.st.plugin.PluginConstants;
+
+import static com.passus.config.schema.ConfigurationSchemaBuilder.*;
+
+/**
+ * @author Mirosław Hawrot
+ */
+@NodeDefinitionCreate(MatchFilter.MatchFilterNodeDefCreator.class)
+@Plugin(name = MatchFilter.TYPE, category = PluginConstants.CATEGORY_FLOW_FILTER)
+public class MatchFilter implements FlowFilter {
+
+    public static final String TYPE = "matcher";
+
+    private MessagePredicate predicate;
+
+    private boolean acceptOnMatch = true;
+
+    private final FlowFilterFactory filterFactory;
+
+    public MatchFilter() {
+        this(FlowFilterFactory.DEFAULT_FACTORY);
+    }
+
+    public MatchFilter(FlowFilterFactory filterFactory) {
+        Assert.notNull(filterFactory, "filterFactory");
+        this.filterFactory = filterFactory;
+    }
+
+    public MessagePredicate getPredicate() {
+        return predicate;
+    }
+
+    public void setPredicate(MessagePredicate predicate) {
+        this.predicate = predicate;
+    }
+
+    public boolean isAcceptOnMatch() {
+        return acceptOnMatch;
+    }
+
+    public void setAcceptOnMatch(boolean acceptOnMatch) {
+        this.acceptOnMatch = acceptOnMatch;
+    }
+
+    @Override
+    public void configure(Configuration config, ConfigurationContext context) {
+        predicate = (MessagePredicate) config.get("matches");
+        acceptOnMatch = config.getBoolean("acceptOnMatch", true);
+    }
+
+    @Override
+    public int filterOutbound(Object request, Object resp, FlowContext context) {
+        if (predicate == null) {
+            return DUNNO;
+        }
+
+        boolean match = predicate.test(filterFactory.createWrapper(request, resp, context));
+        if (!match) {
+            return DUNNO;
+        }
+
+        return acceptOnMatch ? ACCEPT : DENY;
+    }
+
+    @Override
+    public MatchFilter instanceForWorker(int index) {
+        MatchFilter filter = new MatchFilter();
+        filter.acceptOnMatch = acceptOnMatch;
+        filter.predicate = predicate;
+        return filter;
+    }
+
+    public static class MatchFilterNodeDefCreator implements NodeDefinitionCreator {
+
+        @Override
+        public NodeDefinition create() {
+            return mapDef(
+                    tupleDef("acceptOnMatch", valueDefBool()).setRequired(false),
+                    tupleDef("matches", new MessagePredicateNodeDefinition())
+            );
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/client/filter/MvelFilter.java	Wed Mar 25 11:32:36 2020 +0100
@@ -0,0 +1,163 @@
+package com.passus.st.client.filter;
+
+import com.passus.commons.Assert;
+import com.passus.commons.annotations.Plugin;
+import com.passus.config.Configuration;
+import com.passus.config.ConfigurationContext;
+import com.passus.config.annotations.NodeDefinitionCreate;
+import com.passus.config.schema.NodeDefinition;
+import com.passus.config.schema.NodeDefinitionCreator;
+import com.passus.net.http.HttpRequest;
+import com.passus.st.client.FlowContext;
+import com.passus.st.client.http.HttpScopes;
+import com.passus.st.client.http.filter.HttpFilter;
+import com.passus.st.config.StringSourceNodeDefinition;
+import com.passus.st.config.StringToExecutableStatementValueTransformer;
+import com.passus.st.plugin.PluginConstants;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.mvel2.compiler.ExecutableStatement;
+import org.mvel2.integration.VariableResolverFactory;
+import org.mvel2.integration.impl.CachingMapVariableResolverFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.passus.config.schema.ConfigurationSchemaBuilder.*;
+import static com.passus.st.client.http.filter.HttpFlowUtils.extractHttpContext;
+
+/**
+ * @author Mirosław Hawrot
+ */
+@NodeDefinitionCreate(MvelFilter.MvelFilterNodeDefCreator.class)
+@Plugin(name = MvelFilter.TYPE, category = PluginConstants.CATEGORY_FLOW_FILTER)
+public class MvelFilter implements FlowFilter {
+
+    public static final String TYPE = "mvel";
+
+    private static final Logger LOGGER = LogManager.getLogger(MvelFilter.class);
+
+    private VariableResolverFactory globalFactory;
+
+    private ExecutableStatement statement;
+
+    private FilterDirection direction = FilterDirection.OUT;
+
+    public MvelFilter() {
+    }
+
+    public MvelFilter(ExecutableStatement statement, FilterDirection direction) {
+        Assert.notNull(statement, "statement");
+        Assert.notNull(direction, "direction");
+        this.statement = statement;
+        this.direction = direction;
+    }
+
+    public VariableResolverFactory getGlobalFactory() {
+        return globalFactory;
+    }
+
+    public void setGlobalFactory(VariableResolverFactory globalFactory) {
+        this.globalFactory = globalFactory;
+    }
+
+    public FilterDirection getDirection() {
+        return direction;
+    }
+
+    public void setDirection(FilterDirection direction) {
+        Assert.notNull(direction, "direction");
+        this.direction = direction;
+    }
+
+    public ExecutableStatement getStatement() {
+        return statement;
+    }
+
+    public void setStatement(ExecutableStatement statement) {
+        this.statement = statement;
+    }
+
+    @Override
+    public void configure(Configuration config, ConfigurationContext context) {
+        direction = config.get("dir", FilterDirection.OUT);
+        statement = (ExecutableStatement) config.get("script");
+    }
+
+    private int filter(Object req, Object resp, FlowContext context) {
+        if (statement == null) {
+            return DUNNO;
+        }
+
+        Map<String, Object> vars = new HashMap<>(3);
+        vars.put("$req", req);
+        vars.put("$resp", resp);
+        vars.put("$context", context);
+        if (context != null && req instanceof HttpRequest) {
+            HttpRequest httpReq = (HttpRequest) req;
+            HttpScopes scopes = extractHttpContext(context).scopes();
+            vars.put("$extractHttpContext", scopes);
+            vars.put("$httpSession", scopes.getSession(httpReq));
+        }
+
+        CachingMapVariableResolverFactory factory = new CachingMapVariableResolverFactory(vars);
+        if (globalFactory != null) {
+            factory.setNextFactory(globalFactory);
+        }
+
+        try {
+            Object out = statement.getValue(null, factory);
+            if (out instanceof Integer) {
+                int value = (Integer) out;
+                if (value < 0) {
+                    return DENY;
+                } else if (value > 0) {
+                    return ACCEPT;
+                }
+
+                return DUNNO;
+            }
+        } catch (Throwable th) {
+            LOGGER.trace(th);
+        }
+
+        return DUNNO;
+    }
+
+    @Override
+    public int filterOutbound(Object req, Object resp, FlowContext context) {
+        if (direction == FilterDirection.BOTH || direction == FilterDirection.OUT) {
+            return filter(req, resp, context);
+        }
+
+        return DUNNO;
+    }
+
+    @Override
+    public int filterInbound(Object req, Object resp, FlowContext context) {
+        if (direction == FilterDirection.BOTH || direction == FilterDirection.IN) {
+            return filter(req, resp, context);
+        }
+
+        return DUNNO;
+    }
+
+    @Override
+    public FlowFilter instanceForWorker(int index) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public static final class MvelFilterNodeDefCreator implements NodeDefinitionCreator {
+
+        @Override
+        public NodeDefinition create() {
+            return mapDef(
+                    tupleDef("dir", enumDef(FilterDirection.class)).setRequired(false),
+                    tupleDef("script", new StringSourceNodeDefinition()
+                            .setTransformer(new StringToExecutableStatementValueTransformer())
+                    )
+            );
+        }
+
+    }
+}
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpFilterDirection.java	Wed Mar 25 11:02:10 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-package com.passus.st.client.http.filter;
-
-/**
- *
- * @author Mirosław Hawrot
- */
-public enum HttpFilterDirection {
-
-    IN, OUT, BOTH
-
-}
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMatchFilter.java	Wed Mar 25 11:02:10 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-package com.passus.st.client.http.filter;
-
-import com.passus.commons.Assert;
-import com.passus.commons.annotations.Plugin;
-import com.passus.config.Configuration;
-import com.passus.config.ConfigurationContext;
-import com.passus.config.annotations.NodeDefinitionCreate;
-import com.passus.config.schema.NodeDefinition;
-import com.passus.config.schema.NodeDefinitionCreator;
-import com.passus.net.http.HttpRequest;
-import com.passus.net.http.HttpResponse;
-import com.passus.st.client.FlowContext;
-import com.passus.st.client.filter.FlowFilterFactory;
-import com.passus.st.client.filter.MessagePredicate;
-import com.passus.st.client.filter.MessagePredicateNodeDefinition;
-import com.passus.st.plugin.PluginConstants;
-
-import static com.passus.config.schema.ConfigurationSchemaBuilder.*;
-
-/**
- * @author Mirosław Hawrot
- */
-@NodeDefinitionCreate(HttpMatchFilter.HttpMatchFilterNodeDefCreator.class)
-@Plugin(name = HttpMatchFilter.TYPE, category = PluginConstants.CATEGORY_FLOW_FILTER)
-public class HttpMatchFilter extends HttpFilter {
-
-    public static final String TYPE = "matcher";
-
-    private MessagePredicate predicate;
-
-    private boolean acceptOnMatch = true;
-
-    private final FlowFilterFactory filterFactory;
-
-    public HttpMatchFilter() {
-        this(FlowFilterFactory.DEFAULT_FACTORY);
-    }
-
-    public HttpMatchFilter(FlowFilterFactory filterFactory) {
-        Assert.notNull(filterFactory, "filterFactory");
-        this.filterFactory = filterFactory;
-    }
-
-    public MessagePredicate getPredicate() {
-        return predicate;
-    }
-
-    public void setPredicate(MessagePredicate predicate) {
-        this.predicate = predicate;
-    }
-
-    public boolean isAcceptOnMatch() {
-        return acceptOnMatch;
-    }
-
-    public void setAcceptOnMatch(boolean acceptOnMatch) {
-        this.acceptOnMatch = acceptOnMatch;
-    }
-
-    @Override
-    public void configure(Configuration config, ConfigurationContext context) {
-        predicate = (MessagePredicate) config.get("matches");
-        acceptOnMatch = config.getBoolean("acceptOnMatch", true);
-    }
-
-    @Override
-    public int filterOutbound(HttpRequest request, HttpResponse resp, FlowContext context) {
-        if (predicate == null) {
-            return DUNNO;
-        }
-
-        boolean match = predicate.test(filterFactory.createWrapper(request, resp, context));
-
-        if (!match) {
-            return DUNNO;
-        }
-
-        return acceptOnMatch ? ACCEPT : DENY;
-    }
-
-    @Override
-    public HttpMatchFilter instanceForWorker(int index) {
-        HttpMatchFilter filter = new HttpMatchFilter();
-        filter.acceptOnMatch = acceptOnMatch;
-        filter.predicate = predicate;
-        return filter;
-    }
-
-    public static class HttpMatchFilterNodeDefCreator implements NodeDefinitionCreator {
-
-        @Override
-        public NodeDefinition create() {
-            return mapDef(
-                    tupleDef("acceptOnMatch", valueDefBool()),
-                    tupleDef("matches", new MessagePredicateNodeDefinition())
-            );
-        }
-
-    }
-}
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessageModificationFilter.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMessageModificationFilter.java	Wed Mar 25 11:32:36 2020 +0100
@@ -11,10 +11,7 @@
 import com.passus.net.http.HttpRequest;
 import com.passus.net.http.HttpResponse;
 import com.passus.st.client.FlowContext;
-import com.passus.st.client.filter.FlowFilterFactory;
-import com.passus.st.client.filter.MessagePredicate;
-import com.passus.st.client.filter.MessagePredicateNodeDefinition;
-import com.passus.st.client.filter.MessageWrapper;
+import com.passus.st.client.filter.*;
 import com.passus.st.client.http.filter.HttpMessageModificationOperations.Operation;
 import com.passus.st.config.FieldValueExtractorTransformerNodeDefCreator;
 import com.passus.st.config.HeaderOperationNodeDefinition;
@@ -46,7 +43,7 @@
 
     private final FlowFilterFactory filterFactory;
 
-    private HttpFilterDirection direction = HttpFilterDirection.OUT;
+    private FilterDirection direction = FilterDirection.OUT;
 
     public HttpMessageModificationFilter() {
         this(FlowFilterFactory.DEFAULT_FACTORY);
@@ -64,11 +61,11 @@
         this.predicate = predicate;
     }
 
-    public HttpFilterDirection getDirection() {
+    public FilterDirection getDirection() {
         return direction;
     }
 
-    public void setDirection(HttpFilterDirection direction) {
+    public void setDirection(FilterDirection direction) {
         Assert.notNull(direction, "direction");
         this.direction = direction;
     }
@@ -90,7 +87,7 @@
             }
         }
 
-        direction = config.get("dir", HttpFilterDirection.OUT);
+        direction = config.get("dir", FilterDirection.OUT);
         predicate = config.get("applyIf", null);
     }
 
@@ -116,7 +113,7 @@
 
     @Override
     public int filterOutbound(HttpRequest req, HttpResponse resp, FlowContext context) {
-        if (direction == HttpFilterDirection.BOTH || direction == HttpFilterDirection.OUT) {
+        if (direction == FilterDirection.BOTH || direction == FilterDirection.OUT) {
             filter(req, resp, context);
         }
 
@@ -125,7 +122,7 @@
 
     @Override
     public int filterInbound(HttpRequest req, HttpResponse resp, FlowContext context) {
-        if (direction == HttpFilterDirection.BOTH || direction == HttpFilterDirection.IN) {
+        if (direction == FilterDirection.BOTH || direction == FilterDirection.IN) {
             filter(req, resp, context);
         }
 
@@ -186,7 +183,7 @@
             return mapDef(
                     tupleDef("operations", operationsDef),
                     tupleDef("applyIf", new MessagePredicateNodeDefinition()).setRequired(false),
-                    tupleDef("dir", enumDef(HttpFilterDirection.class)).setRequired(false)
+                    tupleDef("dir", enumDef(FilterDirection.class)).setRequired(false)
             );
         }
 
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpMvelFilter.java	Wed Mar 25 11:02:10 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-package com.passus.st.client.http.filter;
-
-import com.passus.commons.Assert;
-import com.passus.commons.annotations.Plugin;
-import com.passus.config.Configuration;
-import com.passus.config.ConfigurationContext;
-import com.passus.config.annotations.NodeDefinitionCreate;
-import com.passus.config.schema.NodeDefinition;
-import com.passus.config.schema.NodeDefinitionCreator;
-import com.passus.net.http.HttpRequest;
-import com.passus.net.http.HttpResponse;
-import com.passus.st.client.FlowContext;
-import com.passus.st.client.http.HttpScopes;
-import com.passus.st.config.StringSourceNodeDefinition;
-import com.passus.st.config.StringToExecutableStatementValueTransformer;
-import com.passus.st.plugin.PluginConstants;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.mvel2.compiler.ExecutableStatement;
-import org.mvel2.integration.VariableResolverFactory;
-import org.mvel2.integration.impl.CachingMapVariableResolverFactory;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static com.passus.config.schema.ConfigurationSchemaBuilder.*;
-import static com.passus.st.client.http.filter.HttpFlowUtils.extractHttpContext;
-
-/**
- * @author Mirosław Hawrot
- */
-@NodeDefinitionCreate(HttpMvelFilter.HttpMvelFilterNodeDefCreator.class)
-@Plugin(name = HttpMvelFilter.TYPE, category = PluginConstants.CATEGORY_FLOW_FILTER)
-public class HttpMvelFilter extends HttpFilter {
-
-    public static final String TYPE = "mvel";
-
-    private static final Logger LOGGER = LogManager.getLogger(HttpMvelFilter.class);
-
-    private VariableResolverFactory globalFactory;
-
-    private ExecutableStatement statement;
-
-    private HttpFilterDirection direction = HttpFilterDirection.OUT;
-
-    public HttpMvelFilter() {
-    }
-
-    public HttpMvelFilter(ExecutableStatement statement, HttpFilterDirection direction) {
-        Assert.notNull(statement, "statement");
-        Assert.notNull(direction, "direction");
-        this.statement = statement;
-        this.direction = direction;
-    }
-
-    public VariableResolverFactory getGlobalFactory() {
-        return globalFactory;
-    }
-
-    public void setGlobalFactory(VariableResolverFactory globalFactory) {
-        this.globalFactory = globalFactory;
-    }
-
-    public HttpFilterDirection getDirection() {
-        return direction;
-    }
-
-    public void setDirection(HttpFilterDirection direction) {
-        Assert.notNull(direction, "direction");
-        this.direction = direction;
-    }
-
-    public ExecutableStatement getStatement() {
-        return statement;
-    }
-
-    public void setStatement(ExecutableStatement statement) {
-        this.statement = statement;
-    }
-
-    @Override
-    public void configure(Configuration config, ConfigurationContext context) {
-        direction = config.get("dir", HttpFilterDirection.OUT);
-        statement = (ExecutableStatement) config.get("script");
-    }
-
-    private int filter(HttpRequest req, HttpResponse resp, FlowContext context) {
-        if (statement == null) {
-            return DUNNO;
-        }
-
-        Map<String, Object> vars = new HashMap<>(3);
-        vars.put("$req", req);
-        vars.put("$resp", resp);
-        vars.put("$context", context);
-        if (context != null) {
-            HttpScopes scopes = extractHttpContext(context).scopes();
-            vars.put("$extractHttpContext", scopes);
-            vars.put("$httpSession", scopes.getSession(req));
-        }
-
-        CachingMapVariableResolverFactory factory = new CachingMapVariableResolverFactory(vars);
-        if (globalFactory != null) {
-            factory.setNextFactory(globalFactory);
-        }
-
-        try {
-            Object out = statement.getValue(null, factory);
-            if (out instanceof Integer) {
-                int value = (Integer) out;
-                if (value < 0) {
-                    return DENY;
-                } else if (value > 0) {
-                    return ACCEPT;
-                }
-
-                return DUNNO;
-            }
-        } catch (Throwable th) {
-            LOGGER.trace(th);
-        }
-
-        return DUNNO;
-    }
-
-    @Override
-    public int filterOutbound(HttpRequest req, HttpResponse resp, FlowContext context) {
-        if (direction == HttpFilterDirection.BOTH || direction == HttpFilterDirection.OUT) {
-            return filter(req, resp, context);
-        }
-
-        return DUNNO;
-    }
-
-    @Override
-    public int filterInbound(HttpRequest req, HttpResponse resp, FlowContext context) {
-        if (direction == HttpFilterDirection.BOTH || direction == HttpFilterDirection.IN) {
-            return filter(req, resp, context);
-        }
-
-        return DUNNO;
-    }
-
-    @Override
-    public HttpFilter instanceForWorker(int index) {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public static final class HttpMvelFilterNodeDefCreator implements NodeDefinitionCreator {
-
-        @Override
-        public NodeDefinition create() {
-            return mapDef(
-                    tupleDef("dir", enumDef(HttpFilterDirection.class)).setRequired(false),
-                    tupleDef("script", new StringSourceNodeDefinition()
-                            .setTransformer(new StringToExecutableStatementValueTransformer())
-                    )
-            );
-        }
-
-    }
-}
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpScopeModificationFilter.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpScopeModificationFilter.java	Wed Mar 25 11:32:36 2020 +0100
@@ -13,10 +13,7 @@
 import com.passus.net.http.HttpResponse;
 import com.passus.st.ParametersBag;
 import com.passus.st.client.FlowContext;
-import com.passus.st.client.filter.FlowFilterFactory;
-import com.passus.st.client.filter.MessagePredicate;
-import com.passus.st.client.filter.MessagePredicateNodeDefinition;
-import com.passus.st.client.filter.MessageWrapper;
+import com.passus.st.client.filter.*;
 import com.passus.st.config.FieldValueExtractorTransformerNodeDefCreator;
 import com.passus.st.config.HeaderOperationNodeDefinition;
 import com.passus.st.plugin.PluginConstants;
@@ -180,7 +177,7 @@
 
     private MessagePredicate predicate;
 
-    private HttpFilterDirection direction = HttpFilterDirection.OUT;
+    private FilterDirection direction = FilterDirection.OUT;
 
     private final FlowFilterFactory filterFactory;
 
@@ -201,11 +198,11 @@
         this.predicate = predicate;
     }
 
-    public HttpFilterDirection getDirection() {
+    public FilterDirection getDirection() {
         return direction;
     }
 
-    public void setDirection(HttpFilterDirection direction) {
+    public void setDirection(FilterDirection direction) {
         Assert.notNull(direction, "direction");
         this.direction = direction;
     }
@@ -239,7 +236,7 @@
             }
         }
 
-        direction = config.get("dir", HttpFilterDirection.OUT);
+        direction = config.get("dir", FilterDirection.OUT);
         predicate = config.get("applyIf", null);
     }
 
@@ -261,7 +258,7 @@
 
     @Override
     public int filterOutbound(HttpRequest req, HttpResponse resp, FlowContext context) {
-        if (direction == HttpFilterDirection.BOTH || direction == HttpFilterDirection.OUT) {
+        if (direction == FilterDirection.BOTH || direction == FilterDirection.OUT) {
             filter(req, resp, context);
         }
 
@@ -270,7 +267,7 @@
 
     @Override
     public int filterInbound(HttpRequest req, HttpResponse resp, FlowContext context) {
-        if (direction == HttpFilterDirection.BOTH || direction == HttpFilterDirection.IN) {
+        if (direction == FilterDirection.BOTH || direction == FilterDirection.IN) {
             filter(req, resp, context);
         }
 
@@ -314,7 +311,7 @@
             return mapDef(
                     tupleDef("operations", operationsDef),
                     tupleDef("applyIf", new MessagePredicateNodeDefinition()).setRequired(false),
-                    tupleDef("dir", enumDef(HttpFilterDirection.class)).setRequired(false)
+                    tupleDef("dir", enumDef(FilterDirection.class)).setRequired(false)
             );
         }
     }
--- a/stress-tester/src/test/java/com/passus/st/ConverterHttpClientTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/ConverterHttpClientTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -4,7 +4,7 @@
 import com.passus.st.client.SessionPayloadEvent;
 import com.passus.st.client.credentials.Credentials;
 import com.passus.st.client.credentials.CredentialsProvider;
-import com.passus.st.client.filter.MessagePredicate;
+import com.passus.st.client.filter.*;
 import com.passus.st.client.http.filter.*;
 import com.passus.st.client.http.filter.HttpMessageModificationOperations.PostDataSetParamOperation;
 import com.passus.st.client.http.filter.HttpMessageModificationOperations.SetCookieOperation;
@@ -55,9 +55,9 @@
         return new SessionPayloadEvent(SI, req, resp, HTTP, "test");
     }
 
-    static ConverterHttpClient client(HttpFilter... filters) {
+    static ConverterHttpClient client(FlowFilter... filters) {
         ConverterHttpClient client = new ConverterHttpClient(DST);
-        for (HttpFilter filter : filters) {
+        for (FlowFilter filter : filters) {
             client.addFilter(filter);
         }
         client.start();
@@ -144,8 +144,8 @@
         HttpResponse resp2 = HttpResponseBuilder.status(HttpStatus.NO_CONTENT).build();
 
         ArrayListEventDestination dst = new ArrayListEventDestination();
-        MessagePredicate predicate = HttpFilterTestUtils.createPredicate("{'@req.url': {$contains: test2}}");
-        HttpMatchFilter f = new HttpMatchFilter();
+        MessagePredicate predicate = FilterTestUtils.createPredicate("{'@req.url': {$contains: test2}}");
+        MatchFilter f = new MatchFilter();
         f.setPredicate(predicate);
         f.setAcceptOnMatch(false);
 
@@ -244,7 +244,7 @@
     public void testZone_() {
         HttpRequest req = HttpRequestBuilder.get("http://test.com/test").build();
         HttpResponse resp = HttpResponseBuilder.ok().build();
-        MessagePredicate predicate = HttpFilterTestUtils.createPredicate("{\"@req.url\": {$contains: test}}");
+        MessagePredicate predicate = FilterTestUtils.createPredicate("{\"@req.url\": {$contains: test}}");
 
         HttpZoneFilter f = new HttpZoneFilter();
         f.addRule(new HttpZoneFilter.Rule("testZone", predicate));
@@ -263,9 +263,9 @@
         String expression = "$req.setMethod(com.passus.net.http.HttpMethod.HEAD);"
                 + "$req.getUri().toString().equals(\"/index.html\") ? 1 : 0";
 
-        HttpMvelFilter f = new HttpMvelFilter();
-        f.setStatement(HttpMvelFilterTest.es(expression));
-        f.setDirection(HttpFilterDirection.OUT);
+        MvelFilter f = new MvelFilter();
+        f.setStatement(MvelFilterTest.es(expression));
+        f.setDirection(FilterDirection.OUT);
         ConverterHttpClient client = client(f);
 
         client.handle(ev(req, null));
@@ -277,7 +277,7 @@
     public void testMarker_() {
         HttpRequest req = HttpRequestBuilder.get("http://test/test").build();
 
-        MessagePredicate predicate = HttpFilterTestUtils.createPredicate("{\"@req.url\": {$contains: test}}");
+        MessagePredicate predicate = FilterTestUtils.createPredicate("{\"@req.url\": {$contains: test}}");
         HttpMarkFilter f = new HttpMarkFilter();
         f.addRule(new HttpMarkFilter.MarkerRule("category1", predicate));
         ConverterHttpClient client = client(f);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/test/java/com/passus/st/client/filter/CounterFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -0,0 +1,76 @@
+package com.passus.st.client.filter;
+
+import com.passus.config.validation.Errors;
+import com.passus.filter.AndPredicate;
+import com.passus.filter.ComparisonOperator;
+import com.passus.filter.ComparisonPredicate;
+import com.passus.net.http.*;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+
+public class CounterFilterTest {
+
+    @Test
+    public void testFilterInbound() {
+        HttpRequest req = HttpRequestBuilder.get("http://example.com").build();
+        HttpResponse resp = HttpResponseBuilder.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
+
+        TestListener listener = new TestListener();
+
+        MessagePredicate predicate = FilterTestUtils.createPredicate("{'@resp.status.code': 500}");
+        CounterFilter filter = new CounterFilter();
+        filter.setLimit(2);
+        filter.setName("filter status code 500");
+        filter.setPredicate(predicate);
+        filter.setListener(listener);
+
+        filter.filterInbound(req, resp, null);
+        assertEquals(0, listener.events.size());
+        filter.filterInbound(req, resp, null);
+        assertEquals(1, listener.events.size());
+    }
+
+    @Test
+    public void testConfigure() throws Exception {
+        String filterConfig = "filters:\n"
+                + "    - type: counter\n"
+                + "      name: 'filter x'\n"
+                + "      limit: 3\n"
+                + "      applyIf: {'@resp.status.code': 404}\n";
+
+        Errors errors = new Errors();
+        List<FlowFilter> filters = FlowFiltersConfigurator.getFilters(filterConfig, errors, null);
+        FilterTestUtils.printErrors(errors);
+
+        assertEquals(0, errors.getErrorCount());
+        assertEquals(1, filters.size());
+        assertTrue(filters.get(0) instanceof CounterFilter);
+
+        CounterFilter filter = (CounterFilter) filters.get(0);
+        assertEquals(3, filter.getLimit());
+        assertEquals("filter x", filter.getName());
+
+        AndPredicate<? extends Object> andPredicate = (AndPredicate) filter.getPredicate().getPredicate();
+        assertEquals(1, andPredicate.getSubPredicates().size());
+        ComparisonPredicate predicate = (ComparisonPredicate) andPredicate.getSubPredicates().get(0);
+        assertEquals("resp.status.code", predicate.getFieldName());
+        assertEquals(ComparisonOperator.EQUAL, predicate.getOperator());
+    }
+
+    private static class TestListener implements CounterListener {
+
+        private final ArrayList<Event> events = new ArrayList<>();
+
+        @Override
+        public void limitReached(Event event) {
+            events.add(event);
+        }
+
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/test/java/com/passus/st/client/filter/FilterTestUtils.java	Wed Mar 25 11:32:36 2020 +0100
@@ -0,0 +1,82 @@
+package com.passus.st.client.filter;
+
+import com.passus.commons.utils.ReflectionUtils;
+import com.passus.config.validation.Errors;
+import com.passus.config.validation.ObjectError;
+import com.passus.filter.config.PredicateNodeTransformer;
+import com.passus.net.http.HttpMessage;
+import com.passus.st.ParametersBag;
+import static com.passus.st.client.http.HttpConsts.TAG_SESSION_ID;
+import static com.passus.st.client.http.HttpConsts.ZONE_DEFAULT;
+
+import com.passus.st.client.FlowContext;
+import com.passus.st.client.filter.MessagePredicate;
+import com.passus.st.client.http.HttpFlowConst;
+import com.passus.st.client.http.HttpFlowContext;
+import com.passus.st.client.http.HttpScopes;
+import com.passus.st.filter.Transformers;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ *
+ * @author mikolaj.podbielski
+ */
+public class FilterTestUtils {
+
+    private static final boolean DEFAULT_USE_ACCELERATED_EXTRACTORS = true;
+
+    public static FlowContext createMockContext() {
+        return createMockContext(new HttpScopes());
+    }
+
+    public static FlowContext createMockContext(HttpScopes scopes) {
+        FlowContext mockContext = mock(FlowContext.class);
+        HttpFlowContext mockHttpContext = mock(HttpFlowContext.class);
+        when(mockContext.getParamValue(HttpFlowConst.PARAM_HTTP_CONTEXT)).thenReturn(mockHttpContext);
+        when(mockHttpContext.scopes()).thenReturn(scopes);
+        return mockContext;
+    }
+
+    public static MessagePredicate createPredicate(String config) {
+        return createPredicate(config, DEFAULT_USE_ACCELERATED_EXTRACTORS);
+    }
+
+    public static MessagePredicate createPredicate(String config, boolean useAcceleratedExtractor) {
+        try {
+            PredicateNodeTransformer transformer = useAcceleratedExtractor
+                    ? Transformers.PREDICATE : PredicateNodeTransformer.DEFAULT;
+            Predicate predicate = transformer.transform(config);
+            return new MessagePredicate(predicate);
+        } catch (Exception e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    public static void tagMessages(HttpMessage... messages) {
+        for (HttpMessage message : messages) {
+            message.setTag(TAG_SESSION_ID, "sid1");
+        }
+    }
+
+    public static void printErrors(Errors errors) {
+        List<ObjectError> allErrors = errors.getAllErrors();
+        if (allErrors.size() > 0) {
+            System.out.println("ERRORS:");
+            for (ObjectError error : allErrors) {
+                System.out.println(error);
+            }
+        }
+    }
+
+    public static Map<String, ParametersBag> getSessions(HttpScopes scopes) {
+        Map<String, Map<String, ParametersBag>> zonesSessions = ReflectionUtils.<Map>getField(scopes, "zonesSessions");
+        Map<String, ParametersBag> defaultZone = zonesSessions.get(ZONE_DEFAULT);
+        System.out.println(defaultZone);
+        return defaultZone;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/test/java/com/passus/st/client/filter/MatchFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -0,0 +1,118 @@
+package com.passus.st.client.filter;
+
+import com.passus.config.validation.Errors;
+import com.passus.net.http.*;
+import com.passus.st.AppUtils;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static com.passus.st.utils.Assert.assertNoError;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+
+/**
+ * @author Mirosław Hawrot
+ */
+public class MatchFilterTest {
+
+    private final List<HttpRequest> httpRequests = Arrays.asList(
+            HttpRequestBuilder.get("http://test.com/test").header("Header", "TheValue").build(),
+            HttpRequestBuilder.get("http://test2.com/test2").build()
+    );
+
+    private final List<HttpResponse> httpResponses = Arrays.asList(
+            HttpResponseBuilder.ok().build(),
+            HttpResponseBuilder.status(HttpStatus.CREATED).build(),
+            HttpResponseBuilder.status(HttpStatus.ACCEPTED).build()
+    );
+
+    private <T> List<T> filter(List<T> messages, String config) {
+        MessagePredicate predicate = FilterTestUtils.createPredicate(config);
+        return filter(messages, predicate);
+    }
+
+    private <T> List<T> filter(List<T> messages, MessagePredicate predicate) {
+        List<T> out = new ArrayList<>(messages.size());
+        for (T message : messages) {
+            if (predicate.test(message)) {
+                out.add(message);
+            }
+        }
+
+        return out;
+    }
+
+    @BeforeClass
+    public static void beforeClass() {
+        AppUtils.registerAll();
+    }
+
+    @AfterClass
+    public static void afterClass() {
+        AppUtils.unregisterAll();
+    }
+
+    @Test
+    public void testHttpFilterOutbound() {
+        List<HttpRequest> reqs;
+        reqs = filter(httpRequests, "{'@req.url': {$contains: \"test2\"}}");
+        assertEquals(1, reqs.size());
+        assertEquals("/test2", reqs.get(0).getUri().toString());
+
+        reqs = filter(httpRequests, "{'@req.uri': {$contains: \"test2\"}}");
+        assertEquals(1, reqs.size());
+        assertEquals("/test2", reqs.get(0).getUri().toString());
+
+        reqs = filter(httpRequests, "{\"@req.getHeader('Header')\": {$contains: \"Val\"}}");
+        assertEquals(1, reqs.size());
+        assertEquals("/test", reqs.get(0).getUri().toString());
+
+        List<HttpResponse> resps;
+        resps = filter(httpResponses, "{'@resp.status.code': 200}");
+        assertEquals(1, resps.size());
+
+        resps = filter(httpResponses, "{'@resp.status.code': '200'}");
+        assertEquals(1, resps.size());
+
+        resps = filter(httpResponses, "{'@resp.status.code': {$gt: 200}}");
+        assertEquals(2, resps.size());
+
+        MessagePredicate predicate = FilterTestUtils.createPredicate(
+                "{'@resp.status.code': {$gt: 200}}", false);
+        resps = filter(httpResponses, predicate);
+        assertEquals(2, resps.size());
+    }
+
+    @Test
+    public void testHttpConfigureAndFilterOutbound() throws Exception {
+        String filterConfig = "filters:\n"
+                + "    - type: matcher\n"
+                + "      matches:\n"
+                + "          '@req.uri': {$contains: 'test'}\n"
+                + "          '@resp.status.code': 200\n";
+
+        Errors errors = new Errors();
+        List<FlowFilter> filters = FlowFiltersConfigurator.getFilters(filterConfig, errors, null);
+
+        assertNoError(errors);
+        assertEquals(1, filters.size());
+        assertTrue(filters.get(0) instanceof MatchFilter);
+
+        MatchFilter filter = (MatchFilter) filters.get(0);
+        MessagePredicate predicate = filter.getPredicate();
+
+        List<HttpRequest> res = filter(httpRequests, "{'@req.url': {$contains: \"test2\"}}");
+        assertEquals(1, res.size());
+        assertEquals("/test2", res.get(0).getUri().toString());
+
+        res = filter(httpRequests, "{'@req.uri': {$contains: \"test2\"}}");
+        assertEquals(1, res.size());
+        assertEquals("/test2", res.get(0).getUri().toString());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/test/java/com/passus/st/client/filter/MvelFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -0,0 +1,63 @@
+package com.passus.st.client.filter;
+
+import com.passus.commons.utils.ResourceUtils;
+import com.passus.config.validation.Errors;
+import com.passus.net.http.HttpMethod;
+import com.passus.net.http.HttpRequest;
+import com.passus.net.http.HttpRequestBuilder;
+import java.io.File;
+import java.util.List;
+
+import org.mvel2.MVEL;
+import org.mvel2.compiler.ExecutableStatement;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author mikolaj.podbielski
+ */
+public class MvelFilterTest {
+
+    @Test
+    public void testFilterOutbound() {
+        HttpRequest req = HttpRequestBuilder.get("http://example.com/index.html").build();
+
+        String expression = "$req.setMethod(com.passus.net.http.HttpMethod.HEAD);"
+                + "$req.getUri().toString().equals(\"/index.html\") ? 1 : 0";
+
+        MvelFilter filter = new MvelFilter();
+        filter.setStatement(es(expression));
+
+        int result = filter.filterOutbound(req, null, null);
+
+        assertEquals(1, result);
+        assertEquals(HttpMethod.HEAD, req.getMethod());
+    }
+
+    @Test
+    public void testConfigure() throws Exception {
+        File file = ResourceUtils.getFile("mvel/return1.mvel");
+
+        String filterConfig = "filters:\n"
+                + "  - type: mvel\n"
+                + "    dir: out\n"
+                + "    script: return -1\n";
+
+        Errors errors = new Errors();
+        List<FlowFilter> filters = FlowFiltersConfigurator.getFilters(filterConfig, errors, null);
+        FilterTestUtils.printErrors(errors);
+
+        assertEquals(0, errors.getErrorCount());
+        assertEquals(1, filters.size());
+        assertTrue(filters.get(0) instanceof MvelFilter);
+
+        MvelFilter filter = (MvelFilter) filters.get(0);
+        assertEquals(-1, filter.filterOutbound(null, null, null));
+        assertEquals(0, filter.filterInbound(null, null, null));
+    }
+
+    public static ExecutableStatement es(String expression) {
+        return (ExecutableStatement) MVEL.compileExpression(expression);
+    }
+}
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpBasicAuthLoginFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpBasicAuthLoginFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -11,6 +11,7 @@
 import com.passus.net.http.HttpResponseBuilder;
 import com.passus.st.AppUtils;
 import com.passus.st.client.FlowContext;
+import com.passus.st.client.filter.FilterTestUtils;
 import com.passus.st.client.filter.FlowFilter;
 import com.passus.st.client.filter.FlowFiltersConfigurator;
 import com.passus.st.client.credentials.Credentials;
@@ -66,7 +67,7 @@
         HttpResponse response = HttpResponseBuilder.ok().build();
         request.setTag(TAG_SESSION_ID, "sid1");
         HttpBasicAuthLoginFilter filter = createFilter(provider(new Credentials("test", "test")));
-        FlowContext context = HttpFilterTestUtils.createMockContext();
+        FlowContext context = FilterTestUtils.createMockContext();
 
         filter.filterOutbound(request, null, context);
         assertEquals(request.getHeaders().get(HttpHeaders.AUTHORIZATION).toString(), "Basic dGVzdDp0ZXN0");
@@ -82,7 +83,7 @@
         HttpResponse response = HttpResponseBuilder.ok().build();
         request.setTag(TAG_SESSION_ID, "sid1");
         HttpBasicAuthLoginFilter filter = createFilter(provider(null));
-        FlowContext context = HttpFilterTestUtils.createMockContext();
+        FlowContext context = FilterTestUtils.createMockContext();
 
         filter.filterOutbound(request, null, context);
         assertEquals(request.getHeaders().get(HttpHeaders.AUTHORIZATION).toString(), "Basic dXNlcjpwYXNzd29yZA==");
@@ -98,7 +99,7 @@
         HttpResponse response = HttpResponseBuilder.ok().build();
         request.setTag(TAG_SESSION_ID, "sid1");
         HttpBasicAuthLoginFilter filter = createFilter(null);
-        FlowContext context = HttpFilterTestUtils.createMockContext();
+        FlowContext context = FilterTestUtils.createMockContext();
 
         filter.filterOutbound(request, null, context);
         assertEquals(request.getHeaders().get(HttpHeaders.AUTHORIZATION).toString(), "Basic dXNlcjpwYXNzd29yZA==");
@@ -140,7 +141,7 @@
 
         Errors errors = new Errors();
         List<FlowFilter> filters = FlowFiltersConfigurator.getFilters(filterConfig, errors, ConfigurationContext.create());
-        HttpFilterTestUtils.printErrors(errors);
+        FilterTestUtils.printErrors(errors);
 
         assertEquals(errors.getErrorCount(), 0);
         assertEquals(filters.size(), 1);
@@ -166,7 +167,7 @@
                 .header(HttpHeaders.AUTHORIZATION, "Basic dXNlcjpwYXNzd29yZA==")
                 .build();
 
-         FlowContext context = HttpFilterTestUtils.createMockContext();
+         FlowContext context = FilterTestUtils.createMockContext();
 
         filter.filterOutbound(req, null, context);
         assertEquals("Basic dXNlcjpwYXNzd29yZA==", req.getHeaders().get(HttpHeaders.AUTHORIZATION).toString());
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpCsrfFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpCsrfFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -8,6 +8,7 @@
 import com.passus.net.http.HttpResponseBuilder;
 import com.passus.st.ParametersBag;
 import com.passus.st.client.FlowContext;
+import com.passus.st.client.filter.FilterTestUtils;
 import com.passus.st.client.filter.FlowFilter;
 import com.passus.st.client.filter.FlowFiltersConfigurator;
 import com.passus.st.client.http.HttpScopes;
@@ -113,7 +114,7 @@
                 .header("x-csrf-token", "token1")
                 .build();
 
-        HttpFilterTestUtils.tagMessages(req1, resp1, req2);
+        FilterTestUtils.tagMessages(req1, resp1, req2);
 
         SessionInfo session = new SessionInfo("1.1.1.1:5000", "2.2.2.2:80");
         HttpScopes scopes = new HttpScopes();
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpCsrfFormFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpCsrfFormFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -13,12 +13,13 @@
 import java.io.IOException;
 import java.util.List;
 
-import static com.passus.st.client.http.filter.HttpFilterTestUtils.createMockContext;
+import static com.passus.st.client.filter.FilterTestUtils.createMockContext;
 import static com.passus.st.client.http.filter.HttpFlowUtils.extractHttpContext;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.testng.AssertJUnit.*;
 
+import com.passus.st.client.filter.FilterTestUtils;
 import com.passus.st.client.filter.FlowFilter;
 import com.passus.st.client.filter.FlowFiltersConfigurator;
 import org.testng.annotations.Test;
@@ -40,7 +41,7 @@
                 .header("Content-Type", "text/html").build();
         HttpRequest req2 = HttpRequestBuilder.post("example.com/save").content(post("oldToken"))
                 .header("Content-Type", "application/x-www-form-urlencoded").build();
-        HttpFilterTestUtils.tagMessages(req1, resp1Orig, resp1Live, req2);
+        FilterTestUtils.tagMessages(req1, resp1Orig, resp1Live, req2);
 
         HttpCsrfFormFilter filter = new HttpCsrfFormFilter();
         filter.setInputName("_token");
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpDigestAuthLoginFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpDigestAuthLoginFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -15,7 +15,7 @@
 
 import static com.passus.st.client.http.HttpConsts.PARAM_USERNAME;
 import static com.passus.st.client.http.HttpConsts.TAG_SESSION_ID;
-import static com.passus.st.client.http.filter.HttpFilterTestUtils.createMockContext;
+import static com.passus.st.client.filter.FilterTestUtils.createMockContext;
 import static com.passus.st.client.http.filter.HttpFlowUtils.extractHttpContext;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertEquals;
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpFilterTestUtils.java	Wed Mar 25 11:02:10 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-package com.passus.st.client.http.filter;
-
-import com.passus.commons.utils.ReflectionUtils;
-import com.passus.config.validation.Errors;
-import com.passus.config.validation.ObjectError;
-import com.passus.filter.config.PredicateNodeTransformer;
-import com.passus.net.http.HttpMessage;
-import com.passus.st.ParametersBag;
-import static com.passus.st.client.http.HttpConsts.TAG_SESSION_ID;
-import static com.passus.st.client.http.HttpConsts.ZONE_DEFAULT;
-
-import com.passus.st.client.FlowContext;
-import com.passus.st.client.filter.MessagePredicate;
-import com.passus.st.client.http.HttpFlowConst;
-import com.passus.st.client.http.HttpFlowContext;
-import com.passus.st.client.http.HttpScopes;
-import com.passus.st.filter.Transformers;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Predicate;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-/**
- *
- * @author mikolaj.podbielski
- */
-public class HttpFilterTestUtils {
-
-    private static final boolean DEFAULT_USE_ACCELERATED_EXTRACTORS = true;
-
-    public static FlowContext createMockContext() {
-        return createMockContext(new HttpScopes());
-    }
-
-    public static FlowContext createMockContext(HttpScopes scopes) {
-        FlowContext mockContext = mock(FlowContext.class);
-        HttpFlowContext mockHttpContext = mock(HttpFlowContext.class);
-        when(mockContext.getParamValue(HttpFlowConst.PARAM_HTTP_CONTEXT)).thenReturn(mockHttpContext);
-        when(mockHttpContext.scopes()).thenReturn(scopes);
-        return mockContext;
-    }
-
-    public static MessagePredicate createPredicate(String config) {
-        return createPredicate(config, DEFAULT_USE_ACCELERATED_EXTRACTORS);
-    }
-
-    public static MessagePredicate createPredicate(String config, boolean useAcceleratedExtractor) {
-        try {
-            PredicateNodeTransformer transformer = useAcceleratedExtractor
-                    ? Transformers.PREDICATE : PredicateNodeTransformer.DEFAULT;
-            Predicate predicate = transformer.transform(config);
-            return new MessagePredicate(predicate);
-        } catch (Exception e) {
-            throw new RuntimeException(e.getMessage(), e);
-        }
-    }
-
-    public static void tagMessages(HttpMessage... messages) {
-        for (HttpMessage message : messages) {
-            message.setTag(TAG_SESSION_ID, "sid1");
-        }
-    }
-
-    public static void printErrors(Errors errors) {
-        List<ObjectError> allErrors = errors.getAllErrors();
-        if (allErrors.size() > 0) {
-            System.out.println("ERRORS:");
-            for (ObjectError error : allErrors) {
-                System.out.println(error);
-            }
-        }
-    }
-
-    public static Map<String, ParametersBag> getSessions(HttpScopes scopes) {
-        Map<String, Map<String, ParametersBag>> zonesSessions = ReflectionUtils.<Map>getField(scopes, "zonesSessions");
-        Map<String, ParametersBag> defaultZone = zonesSessions.get(ZONE_DEFAULT);
-        System.out.println(defaultZone);
-        return defaultZone;
-    }
-
-}
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpFormLoginFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpFormLoginFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -13,13 +13,12 @@
 import static com.passus.st.client.http.HttpConsts.TAG_SESSION_ID;
 
 import com.passus.st.client.filter.MessagePredicate;
-import com.passus.st.client.http.HttpFlowContext;
 import com.passus.st.client.http.HttpScopes;
 import com.passus.st.utils.TestHttpUtils;
 import java.io.IOException;
 import java.util.function.Predicate;
 
-import static com.passus.st.client.http.filter.HttpFilterTestUtils.createMockContext;
+import static com.passus.st.client.filter.FilterTestUtils.createMockContext;
 import static com.passus.st.client.http.filter.HttpFlowUtils.extractHttpContext;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpLogoutFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpLogoutFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -7,6 +7,7 @@
 import com.passus.net.http.HttpResponseBuilder;
 import com.passus.st.AppUtils;
 import com.passus.st.client.FlowContext;
+import com.passus.st.client.filter.FilterTestUtils;
 import com.passus.st.client.filter.FlowFilter;
 import com.passus.st.client.filter.FlowFiltersConfigurator;
 import com.passus.st.client.filter.MessagePredicate;
@@ -19,7 +20,7 @@
 
 import static com.passus.st.client.http.HttpConsts.PARAM_USERNAME;
 import static com.passus.st.client.http.HttpConsts.TAG_SESSION_ID;
-import static com.passus.st.client.http.filter.HttpFilterTestUtils.createMockContext;
+import static com.passus.st.client.filter.FilterTestUtils.createMockContext;
 import static org.testng.AssertJUnit.*;
 
 /**
@@ -39,7 +40,7 @@
 
     @Test
     public void testFilter_InvalidateSession() {
-        MessagePredicate predicate = HttpFilterTestUtils.createPredicate("{'@req.uri': \"/logout\"}");
+        MessagePredicate predicate = FilterTestUtils.createPredicate("{'@req.uri': \"/logout\"}");
         HttpRequest req = HttpRequestBuilder.get("http://test.com/logout").build();
         HttpResponse resp = HttpResponseBuilder.ok().build();
         HttpScopes scopes = new HttpScopes();
@@ -60,7 +61,7 @@
 
     @Test
     public void testFilter_NotInvalidateSession() {
-        MessagePredicate predicate = HttpFilterTestUtils.createPredicate("{'@req.uri': \"/logout\"}");
+        MessagePredicate predicate = FilterTestUtils.createPredicate("{'@req.uri': \"/logout\"}");
         HttpRequest req = HttpRequestBuilder.get("http://test.com/logout").build();
         HttpResponse resp = HttpResponseBuilder.ok().build();
         HttpScopes scopes = new HttpScopes();
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMatchFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-package com.passus.st.client.http.filter;
-
-import com.passus.config.validation.Errors;
-import com.passus.net.http.HttpMessage;
-import com.passus.net.http.HttpRequest;
-import com.passus.net.http.HttpRequestBuilder;
-import com.passus.net.http.HttpResponse;
-import com.passus.net.http.HttpResponseBuilder;
-import com.passus.net.http.HttpStatus;
-import com.passus.st.AppUtils;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertTrue;
-
-import com.passus.st.client.filter.FlowFilter;
-import com.passus.st.client.filter.FlowFiltersConfigurator;
-import com.passus.st.client.filter.MessagePredicate;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-/**
- *
- * @author Mirosław Hawrot
- */
-public class HttpMatchFilterTest {
-
-    private final List<HttpRequest> requests = Arrays.asList(
-            HttpRequestBuilder.get("http://test.com/test").header("Header", "TheValue").build(),
-            HttpRequestBuilder.get("http://test2.com/test2").build()
-    );
-
-    private final List<HttpResponse> responses = Arrays.asList(
-            HttpResponseBuilder.ok().build(),
-            HttpResponseBuilder.status(HttpStatus.CREATED).build(),
-            HttpResponseBuilder.status(HttpStatus.ACCEPTED).build()
-    );
-
-    private <T extends HttpMessage> List<T> filter(List<T> messages, String config) {
-        MessagePredicate predicate = HttpFilterTestUtils.createPredicate(config);
-        return filter(messages, predicate);
-    }
-
-    private <T extends HttpMessage> List<T> filter(List<T> messages, MessagePredicate predicate) {
-        List<T> out = new ArrayList<>(messages.size());
-        for (T message : messages) {
-            if (predicate.test(message)) {
-                out.add(message);
-            }
-        }
-
-        return out;
-    }
-
-    @BeforeClass
-    public static void beforeClass() {
-        AppUtils.registerAll();
-    }
-
-    @AfterClass
-    public static void afterClass() {
-        AppUtils.unregisterAll();
-    }
-
-    @Test
-    public void testFilterOutbound() {
-        List<HttpRequest> reqs;
-        reqs = filter(requests, "{'@req.url': {$contains: \"test2\"}}");
-        assertEquals(1, reqs.size());
-        assertEquals("/test2", reqs.get(0).getUri().toString());
-
-        reqs = filter(requests, "{'@req.uri': {$contains: \"test2\"}}");
-        assertEquals(1, reqs.size());
-        assertEquals("/test2", reqs.get(0).getUri().toString());
-
-        reqs = filter(requests, "{\"@req.getHeader('Header')\": {$contains: \"Val\"}}");
-        assertEquals(1, reqs.size());
-        assertEquals("/test", reqs.get(0).getUri().toString());
-
-        List<HttpResponse> resps;
-        resps = filter(responses, "{'@resp.status.code': 200}");
-        assertEquals(1, resps.size());
-
-        resps = filter(responses, "{'@resp.status.code': '200'}");
-        assertEquals(1, resps.size());
-
-        resps = filter(responses, "{'@resp.status.code': {$gt: 200}}");
-        assertEquals(2, resps.size());
-
-        MessagePredicate predicate = HttpFilterTestUtils.createPredicate(
-                "{'@resp.status.code': {$gt: 200}}", false);
-        resps = filter(responses, predicate);
-        assertEquals(2, resps.size());
-    }
-
-    @Test
-    public void testConfigureAndFilterOutbound() throws Exception {
-        String filterConfig = "filters:\n"
-                + "    - type: matcher\n"
-                + "      matches:\n"
-                + "          '@req.uri': {$contains: 'test'}\n"
-                + "          '@resp.status.code': 200\n";
-
-        Errors errors = new Errors();
-        List<FlowFilter> filters = FlowFiltersConfigurator.getFilters(filterConfig, errors, null);
-
-        assertEquals(0, errors.getErrorCount());
-        assertEquals(1, filters.size());
-        assertTrue(filters.get(0) instanceof HttpMatchFilter);
-
-        HttpMatchFilter filter = (HttpMatchFilter) filters.get(0);
-        MessagePredicate predicate = filter.getPredicate();
-
-        List<HttpRequest> res = filter(requests, "{'@req.url': {$contains: \"test2\"}}");
-        assertEquals(1, res.size());
-        assertEquals("/test2", res.get(0).getUri().toString());
-
-        res = filter(requests, "{'@req.uri': {$contains: \"test2\"}}");
-        assertEquals(1, res.size());
-        assertEquals("/test2", res.get(0).getUri().toString());
-    }
-
-}
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -7,8 +7,10 @@
 import com.passus.net.http.*;
 import com.passus.st.AppUtils;
 import com.passus.st.client.FlowContext;
+import com.passus.st.client.filter.FilterTestUtils;
 import com.passus.st.client.filter.FlowFilter;
 import com.passus.st.client.filter.FlowFiltersConfigurator;
+import com.passus.st.client.filter.FilterDirection;
 import com.passus.st.extractor.ContentExtractorUtils;
 import com.passus.st.client.http.filter.HttpMessageModificationOperations.*;
 import com.passus.st.utils.ConfigurationContextConsts;
@@ -150,9 +152,9 @@
 
     @Test
     public void testDirection() {
-        HttpMessageModificationFilter filterIn = createFilter("in", HttpFilterDirection.IN);
-        HttpMessageModificationFilter filterOut = createFilter("out", HttpFilterDirection.OUT);
-        HttpMessageModificationFilter filterBoth = createFilter("both", HttpFilterDirection.BOTH);
+        HttpMessageModificationFilter filterIn = createFilter("in", FilterDirection.IN);
+        HttpMessageModificationFilter filterOut = createFilter("out", FilterDirection.OUT);
+        HttpMessageModificationFilter filterBoth = createFilter("both", FilterDirection.BOTH);
         List<HttpMessageModificationFilter> filters = Arrays.asList(filterIn, filterOut, filterBoth);
 
         HttpRequest req1 = HttpRequestBuilder.get("http://example.com").build();
@@ -164,7 +166,7 @@
         assertEquals("?in=in&both=both", req2.getUri().toString());
     }
 
-    private HttpMessageModificationFilter createFilter(String param, HttpFilterDirection dir) {
+    private HttpMessageModificationFilter createFilter(String param, FilterDirection dir) {
         HttpMessageModificationFilter filter = new HttpMessageModificationFilter();
         filter.addOperation(new SetQueryParameterOperation(param, param));
         filter.setDirection(dir);
@@ -208,7 +210,7 @@
                 .build();
 
         HttpMessageModificationFilter filter = (HttpMessageModificationFilter) filters.get(0);
-        FlowContext mockContext = HttpFilterTestUtils.createMockContext();
+        FlowContext mockContext = FilterTestUtils.createMockContext();
         extractHttpContext(mockContext).scopes().createSession("testId").set("testParam", "exprValue");
         extractHttpContext(mockContext).scopes().createSession("sessionId").set("testParam", "sessionValue");
         filter.filterOutbound(req, null, mockContext);
@@ -318,10 +320,10 @@
         Errors errors = new Errors();
         ConfigurationContextImpl emptyContext = new ConfigurationContextImpl();
         List<FlowFilter> filters = FlowFiltersConfigurator.getFilters(filterConfig, errors, emptyContext);
-        HttpFilterTestUtils.printErrors(errors);
+        FilterTestUtils.printErrors(errors);
 
         HttpMessageModificationFilter filter = (HttpMessageModificationFilter) filters.get(0);
-        FlowContext mockContext = HttpFilterTestUtils.createMockContext();
+        FlowContext mockContext = FilterTestUtils.createMockContext();
         extractHttpContext(mockContext).scopes().createSession("sessionId").set("testParam", "sessionValue");
         filter.filterOutbound(req, null, mockContext);
         assertEquals("/path/test?v1=aaa&v2=sessionValue", req.getUri().toString());
@@ -345,7 +347,7 @@
         Errors errors = new Errors();
         ConfigurationContextImpl emptyContext = new ConfigurationContextImpl();
         List<FlowFilter> filters = FlowFiltersConfigurator.getFilters(filterConfig, errors, emptyContext);
-        HttpFilterTestUtils.printErrors(errors);
+        FilterTestUtils.printErrors(errors);
 
         assertEquals(0, errors.getErrorCount());
         assertEquals(1, filters.size());
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTransformerTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMessageModificationFilterTransformerTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -8,6 +8,7 @@
 import com.passus.lookup.Lookup;
 import com.passus.lookup.LookupList;
 import com.passus.lookup.filter.LookupValueExtractor;
+import com.passus.st.client.filter.FilterTestUtils;
 import com.passus.st.client.http.filter.HttpMessageModificationOperations.*;
 import com.passus.st.generator.GeneratorValueExtractor;
 import com.passus.st.utils.ConfigurationContextConsts;
@@ -143,7 +144,7 @@
         Errors errors = new Errors();
         ConfigurationContextImpl emptyContext = new ConfigurationContextImpl();
         CValueNode value = transformer.transform(node.getNode(), errors, emptyContext);
-        HttpFilterTestUtils.printErrors(errors);
+        FilterTestUtils.printErrors(errors);
         List<Operation> operations = (List) value.getValue();
 
         assertEquals(0, errors.getErrorCount());
@@ -185,7 +186,7 @@
         Errors errors = new Errors();
         ConfigurationContextImpl emptyContext = new ConfigurationContextImpl();
         CValueNode value = transformer.transform(node.getNode(), errors, emptyContext);
-        HttpFilterTestUtils.printErrors(errors);
+        FilterTestUtils.printErrors(errors);
         List<Operation> operations = (List) value.getValue();
 
         assertEquals(0, errors.getErrorCount());
@@ -243,7 +244,7 @@
         Errors errors = new Errors();
         ConfigurationContextImpl emptyContext = new ConfigurationContextImpl();
         CValueNode value = transformer.transform(node.getNode(), errors, emptyContext);
-        HttpFilterTestUtils.printErrors(errors);
+        FilterTestUtils.printErrors(errors);
         List<Operation> operations = (List) value.getValue();
 
         assertEquals(0, errors.getErrorCount());
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpMvelFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-package com.passus.st.client.http.filter;
-
-import com.passus.commons.utils.ResourceUtils;
-import com.passus.config.validation.Errors;
-import com.passus.net.http.HttpMethod;
-import com.passus.net.http.HttpRequest;
-import com.passus.net.http.HttpRequestBuilder;
-import java.io.File;
-import java.util.List;
-
-import com.passus.st.client.filter.FlowFilter;
-import com.passus.st.client.filter.FlowFiltersConfigurator;
-import org.mvel2.MVEL;
-import org.mvel2.compiler.ExecutableStatement;
-import static org.testng.AssertJUnit.*;
-import org.testng.annotations.Test;
-
-/**
- *
- * @author mikolaj.podbielski
- */
-public class HttpMvelFilterTest {
-
-    @Test
-    public void testFilterOutbound() {
-        HttpRequest req = HttpRequestBuilder.get("http://example.com/index.html").build();
-
-        String expression = "$req.setMethod(com.passus.net.http.HttpMethod.HEAD);"
-                + "$req.getUri().toString().equals(\"/index.html\") ? 1 : 0";
-
-        HttpMvelFilter filter = new HttpMvelFilter();
-        filter.setStatement(es(expression));
-
-        int result = filter.filterOutbound(req, null, null);
-
-        assertEquals(1, result);
-        assertEquals(HttpMethod.HEAD, req.getMethod());
-    }
-
-    @Test
-    public void testConfigure() throws Exception {
-        File file = ResourceUtils.getFile("mvel/return1.mvel");
-
-        String filterConfig = "filters:\n"
-                + "  - type: mvel\n"
-                + "    dir: out\n"
-                + "    script: return -1\n";
-
-        Errors errors = new Errors();
-        List<FlowFilter> filters = FlowFiltersConfigurator.getFilters(filterConfig, errors, null);
-        HttpFilterTestUtils.printErrors(errors);
-
-        assertEquals(0, errors.getErrorCount());
-        assertEquals(1, filters.size());
-        assertTrue(filters.get(0) instanceof HttpMvelFilter);
-
-        HttpMvelFilter filter = (HttpMvelFilter) filters.get(0);
-        assertEquals(-1, filter.filterOutbound(null, null, null));
-        assertEquals(0, filter.filterInbound(null, null, null));
-    }
-
-    public static ExecutableStatement es(String expression) {
-        return (ExecutableStatement) MVEL.compileExpression(expression);
-    }
-}
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpScopeModificationFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpScopeModificationFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -10,6 +10,7 @@
 import com.passus.st.client.FlowContext;
 import com.passus.st.client.filter.FlowFilter;
 import com.passus.st.client.filter.FlowFiltersConfigurator;
+import com.passus.st.client.filter.FilterDirection;
 import com.passus.st.client.http.HttpConsts;
 import com.passus.st.client.http.HttpScopes;
 import com.passus.st.client.http.filter.HttpScopeModificationFilter.*;
@@ -20,7 +21,7 @@
 import java.util.Arrays;
 import java.util.List;
 
-import static com.passus.st.client.http.filter.HttpFilterTestUtils.createMockContext;
+import static com.passus.st.client.filter.FilterTestUtils.createMockContext;
 import static com.passus.st.client.http.filter.HttpFlowUtils.extractHttpContext;
 import static org.testng.AssertJUnit.*;
 
@@ -168,9 +169,9 @@
         HttpScopes scopes = extractHttpContext(mockContext).scopes();
         HttpRequest req = createRequest();
 
-        HttpScopeModificationFilter filterIn = createFilter("in", HttpFilterDirection.IN);
-        HttpScopeModificationFilter filterOut = createFilter("out", HttpFilterDirection.OUT);
-        HttpScopeModificationFilter filterBoth = createFilter("both", HttpFilterDirection.BOTH);
+        HttpScopeModificationFilter filterIn = createFilter("in", FilterDirection.IN);
+        HttpScopeModificationFilter filterOut = createFilter("out", FilterDirection.OUT);
+        HttpScopeModificationFilter filterBoth = createFilter("both", FilterDirection.BOTH);
         List<HttpScopeModificationFilter> filters = Arrays.asList(filterIn, filterOut, filterBoth);
 
         filters.forEach((HttpScopeModificationFilter f) -> f.filterOutbound(req, null, mockContext));
@@ -185,7 +186,7 @@
         assertNotNull(scopes.getGlobal().get("both"));
     }
 
-    private HttpScopeModificationFilter createFilter(String paramName, HttpFilterDirection dir) {
+    private HttpScopeModificationFilter createFilter(String paramName, FilterDirection dir) {
         HttpScopeModificationFilter filter = new HttpScopeModificationFilter();
         filter.addOperation(new SetGlobalParamOperation(paramName, oldValue, false));
         filter.setDirection(dir);
@@ -289,7 +290,7 @@
                 + "           NewGlobalParam2: NewGlobalParamValue2\n";
 
         HttpScopeModificationFilter filter = processConfig(filterConfig);
-        assertEquals(HttpFilterDirection.BOTH, filter.getDirection());
+        assertEquals(FilterDirection.BOTH, filter.getDirection());
         List<Operation> operations = filter.getOperations();
         assertOperations(operations);
     }
@@ -314,7 +315,7 @@
                 + "           NewGlobalParam2: {$expr: 'return \"NewGlobalParamValue2\"'}\n";
 
         HttpScopeModificationFilter filter = processConfig(filterConfig);
-        assertEquals(HttpFilterDirection.BOTH, filter.getDirection());
+        assertEquals(FilterDirection.BOTH, filter.getDirection());
         List<Operation> operations = filter.getOperations();
         assertOperations(operations);
     }
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpSequenceFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpSequenceFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -16,6 +16,7 @@
 import com.passus.net.http.HttpResponse;
 import com.passus.net.http.HttpResponseBuilder;
 import com.passus.st.AppUtils;
+import com.passus.st.client.filter.FilterTestUtils;
 import com.passus.st.client.filter.FlowFilter;
 import com.passus.st.client.filter.FlowFiltersConfigurator;
 import com.passus.st.client.http.filter.HttpSequenceFilter.SequenceItem;
@@ -115,7 +116,7 @@
 
         Errors errors = new Errors();
         List<FlowFilter> filters = FlowFiltersConfigurator.getFilters(filterConfig, errors, null);
-        HttpFilterTestUtils.printErrors(errors);
+        FilterTestUtils.printErrors(errors);
 
         assertEquals(0, errors.getErrorCount());
         assertEquals(1, filters.size());
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpSessionBlockerFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpSessionBlockerFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -6,7 +6,7 @@
 
 import static com.passus.net.http.HttpRequestBuilder.get;
 import static com.passus.st.client.http.HttpConsts.TAG_SESSION_ID;
-import static com.passus.st.client.http.filter.HttpFilterTestUtils.createMockContext;
+import static com.passus.st.client.filter.FilterTestUtils.createMockContext;
 import static com.passus.st.client.http.filter.HttpFlowUtils.extractHttpContext;
 import static org.testng.AssertJUnit.assertEquals;
 
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpSessionCookieFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpSessionCookieFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -11,7 +11,7 @@
 
 import com.passus.st.client.FlowContext;
 
-import static com.passus.st.client.http.filter.HttpFilterTestUtils.createMockContext;
+import static com.passus.st.client.filter.FilterTestUtils.createMockContext;
 import static com.passus.st.client.http.filter.HttpFlowUtils.extractHttpContext;
 import static com.passus.st.utils.TestHttpUtils.*;
 import java.util.Arrays;
@@ -20,6 +20,7 @@
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.*;
 
+import com.passus.st.client.filter.FilterTestUtils;
 import com.passus.st.client.filter.FlowFilter;
 import com.passus.st.client.filter.FlowFiltersConfigurator;
 import org.testng.annotations.Test;
@@ -264,7 +265,7 @@
 
         Errors errors = new Errors();
         List<FlowFilter> filters = FlowFiltersConfigurator.getFilters(filterConfig, errors, null);
-        HttpFilterTestUtils.printErrors(errors);
+        FilterTestUtils.printErrors(errors);
 
         assertEquals(0, errors.getErrorCount());
         assertEquals(1, filters.size());
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpZoneFilterTest.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpZoneFilterTest.java	Wed Mar 25 11:32:36 2020 +0100
@@ -8,6 +8,7 @@
 import com.passus.st.AppUtils;
 import static com.passus.st.client.http.HttpConsts.TAG_ZONE;
 
+import com.passus.st.client.filter.FilterTestUtils;
 import com.passus.st.client.filter.FlowFilter;
 import com.passus.st.client.filter.FlowFiltersConfigurator;
 import com.passus.st.client.http.filter.HttpZoneFilter.Rule;
@@ -41,7 +42,7 @@
         HttpResponse respIn = HttpResponseBuilder.ok().build();
 
         HttpZoneFilter filter = new HttpZoneFilter();
-        filter.addRule(new Rule("testZone", HttpFilterTestUtils.createPredicate("{'@req.url': {$contains: 'test'}}")));
+        filter.addRule(new Rule("testZone", FilterTestUtils.createPredicate("{'@req.url': {$contains: 'test'}}")));
 
         filter.filterOutbound(req, respOut, null);
         filter.filterInbound(req, respIn, null);
--- a/stress-tester/src/test/java/com/passus/st/utils/Assert.java	Wed Mar 25 11:02:10 2020 +0100
+++ b/stress-tester/src/test/java/com/passus/st/utils/Assert.java	Wed Mar 25 11:32:36 2020 +0100
@@ -1,5 +1,6 @@
 package com.passus.st.utils;
 
+import com.passus.config.validation.Errors;
 import com.passus.data.ByteString;
 import com.passus.data.ByteStringImpl;
 import com.passus.data.SliceByteString;
@@ -75,4 +76,14 @@
         }
     }
 
+    public static void assertNoError(Errors errors) {
+        if (errors.hasError()) {
+            StringBuilder sb = new StringBuilder();
+            errors.getAllErrors().forEach((e) -> {
+                sb.append(e.getMessage()).append("\n");
+            });
+
+            fail(sb.toString());
+        }
+    }
 }