changeset 752:ca40a354ee98

CliHelper, CliOptions
author Devel 2
date Wed, 13 Dec 2017 12:33:49 +0100
parents da1ac89b3029
children a4952d5ec439
files stress-tester/src/main/java/com/passus/st/CliHelper.java stress-tester/src/main/java/com/passus/st/CliOptions.java stress-tester/src/main/java/com/passus/st/ConverterMain.java stress-tester/src/main/java/com/passus/st/Main.java stress-tester/src/main/java/com/passus/st/Main2.java stress-tester/src/main/java/com/passus/st/ReaderMain.java stress-tester/src/main/java/com/passus/st/client/http/filter/HttpFiltersConfigurator.java stress-tester/src/test/java/com/passus/st/client/http/filter/HttpFiltersConfiguratorTest.java
diffstat 8 files changed, 311 insertions(+), 306 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/CliHelper.java	Wed Dec 13 12:33:49 2017 +0100
@@ -0,0 +1,151 @@
+package com.passus.st;
+
+import com.passus.commons.Assert;
+import com.passus.config.Configuration;
+import com.passus.config.YamlConfigurationReader;
+import com.passus.config.validation.Errors;
+import static com.passus.config.validation.ErrorsUtils.objectErrorToString;
+import com.passus.config.validation.ObjectError;
+import com.passus.net.PortRangeSet;
+import com.passus.st.client.http.filter.HttpFilter;
+import com.passus.st.client.http.filter.HttpFiltersConfigurator;
+import com.passus.st.emitter.PassThroughSessionMapper;
+import com.passus.st.emitter.RuleBasedSessionMapper;
+import com.passus.st.emitter.SessionMapper;
+import com.passus.st.reader.nc.NcHeader;
+import com.passus.st.reader.pcap.PcapFileHeader;
+import com.passus.st.source.EventSource;
+import com.passus.st.source.NcEventSource;
+import com.passus.st.source.PcapSessionEventSource;
+import java.io.File;
+import java.io.InputStream;
+import java.util.List;
+import org.apache.commons.cli.CommandLine;
+import static org.apache.commons.io.FileUtils.openInputStream;
+import org.apache.commons.io.IOUtils;
+
+/**
+ *
+ * @author Mirosław Hawrot
+ */
+public class CliHelper {
+
+    private CliOptions optons;
+
+    public CliOptions options() {
+        if (optons == null) {
+            optons = new CliOptions();
+        }
+
+        return optons;
+    }
+
+    public void printError(String msg) {
+        printError(msg, true);
+    }
+
+    public void printError(String msg, boolean exit) {
+        System.err.print(msg);
+        if (exit) {
+            System.exit(1);
+        }
+    }
+
+    public void configureLogger(CommandLine cl) {
+        String logLevel = "error";
+        if (cl.hasOption("l")) {
+            logLevel = cl.getOptionValue("l");
+        }
+        if (!logLevel.equals("default")) {
+            Log4jConfigurationFactory.enableFactory(logLevel);
+        }
+    }
+
+    public SessionMapper createDefaultMapper() {
+        return new PassThroughSessionMapper();
+    }
+
+    public RuleBasedSessionMapper createRuleBasedMapper(String[] rules) {
+        Assert.notNull(rules, "rules");
+        RuleBasedSessionMapper mapper = new RuleBasedSessionMapper();
+
+        for (String rule : rules) {
+            try {
+                mapper.addRule(rule);
+            } catch (Exception e) {
+                printError("Invalid mapper rule '" + rule + "'.");
+            }
+        }
+
+        return mapper;
+    }
+
+    public SessionMapper createMapper(CommandLine cl) {
+        if (cl.hasOption("mr")) {
+            String[] rules = cl.getOptionValues("mr");
+            return createRuleBasedMapper(rules);
+        } else {
+            return createDefaultMapper();
+        }
+    }
+
+    public PcapSessionEventSource createPcapEventSource(String fileName, CommandLine cl) throws Exception {
+        PcapSessionEventSource eventSrc = new PcapSessionEventSource();
+        eventSrc.setPcapFile(fileName);
+        eventSrc.setAllowPartialSession(cl.hasOption("ps"));
+        eventSrc.setCollectMetrics(true);
+
+        if (cl.hasOption("hp")) {
+            PortRangeSet portsRanges = eventSrc.getPortsRange();
+            portsRanges.clear();
+
+            String[] ports = cl.getOptionValues("hp");
+            for (String port : ports) {
+                portsRanges.add(port);
+            }
+        }
+
+        return eventSrc;
+    }
+
+    public EventSource createEventSource(String fileName, CommandLine cl) throws Exception {
+        byte[] preambule = null;
+        InputStream in = null;
+        try {
+            in = openInputStream(new File(fileName));
+            preambule = IOUtils.toByteArray(in, 20);
+        } finally {
+            IOUtils.closeQuietly(in);
+        }
+
+        if (NcHeader.isPreambule(preambule, 0)) {
+            return new NcEventSource(fileName);
+        } else if (PcapFileHeader.isFormatSupported(preambule)) {
+            return createPcapEventSource(fileName, cl);
+        } else {
+            printError("Not supported file format '" + fileName + "'.");
+            return null;
+        }
+    }
+
+    public List<HttpFilter> readHttpFilters(CommandLine cl) throws Exception {
+        if (cl.hasOption("ff")) {
+            File filtersFile = new File(cl.getOptionValue("ff"));
+            Configuration config = YamlConfigurationReader.readFromFile(filtersFile);
+            HttpFiltersConfigurator configurator = new HttpFiltersConfigurator();
+            Errors errors = new Errors();
+            configurator.configure(config, errors, null);
+            if (errors.getErrorCount() != 0) {
+                printError("Error in file '" + filtersFile.getAbsolutePath() + "'.", false);
+                for (ObjectError error : errors.getAllErrors()) {
+                    printError("\t" + objectErrorToString(error), false);
+                }
+                System.exit(1);
+            }
+
+            return configurator.getFilters();
+        }
+
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/CliOptions.java	Wed Dec 13 12:33:49 2017 +0100
@@ -0,0 +1,82 @@
+package com.passus.st;
+
+import static com.passus.st.utils.CliUtils.option;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+/**
+ *
+ * @author Mirosław Hawrot
+ */
+public class CliOptions extends Options {
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    public CliOptions addOption(Option opt) {
+        return (CliOptions) super.addOption(opt);
+    }
+
+    @Override
+    public CliOptions addOption(String opt, String longOpt, boolean hasArg, String description) {
+        return (CliOptions) super.addOption(opt, longOpt, hasArg, description);
+    }
+
+    @Override
+    public CliOptions addOption(String opt, boolean hasArg, String description) {
+        return (CliOptions) super.addOption(opt, hasArg, description);
+    }
+
+    @Override
+    public CliOptions addOption(String opt, String description) {
+        return (CliOptions) super.addOption(opt, description);
+    }
+
+    @Override
+    public CliOptions addOptionGroup(OptionGroup group) {
+        return (CliOptions) super.addOptionGroup(group);
+    }
+
+    public CliOptions addLogLevelOption() {
+        return addOption(option("l", "logLevel").desc("Log level.")
+                .hasArg().argName("level")
+                .build()
+        );
+    }
+
+    public CliOptions addMapperRuleOption() {
+        return addOption(option("mr", "mapperRule").desc("Session mapper rule.")
+                .hasArg().argName("rule")
+                .build()
+        );
+    }
+
+    public CliOptions addAllowPartialSessionOption() {
+        return addOption(option("ps", "allowPartialSession").desc("Allow partial sessions.")
+                .hasArg(false)
+                .build()
+        );
+    }
+
+    public CliOptions addHttpFiltersFileOption() {
+        return addOption(option("ff", "filtersFile").desc("Filters file.")
+                .hasArg().argName("file")
+                .build()
+        );
+    }
+
+    public CliOptions addHttpPortsOption() {
+        return addOption(option("hp", "httpPorts").desc("Specify HTTP ports in input file (default: 80, 8080)")
+                .hasArg().argName("ports")
+                .build()
+        );
+    }
+
+    public CliOptions addHttpClientOptions() {
+        addHttpFiltersFileOption();
+        return addHttpPortsOption();
+    }
+    
+
+}
--- a/stress-tester/src/main/java/com/passus/st/ConverterMain.java	Wed Dec 13 11:49:31 2017 +0100
+++ b/stress-tester/src/main/java/com/passus/st/ConverterMain.java	Wed Dec 13 12:33:49 2017 +0100
@@ -6,12 +6,14 @@
 import static com.passus.config.validation.ErrorsUtils.objectErrorToString;
 import com.passus.config.validation.ObjectError;
 import com.passus.net.PortRangeSet;
+import com.passus.st.client.http.filter.HttpFilter;
 import com.passus.st.client.http.filter.HttpFiltersConfigurator;
 import com.passus.st.reader.nc.HttpWriteMode;
 import com.passus.st.source.NcEventDestination;
 import com.passus.st.source.PcapSessionEventSource;
 import static com.passus.st.utils.CliUtils.option;
 import java.io.File;
+import java.util.List;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.DefaultParser;
 import org.apache.commons.cli.HelpFormatter;
@@ -24,6 +26,8 @@
  */
 public class ConverterMain {
 
+    private final CliHelper cliHelper = new CliHelper();
+
     private static final String WRITE_MODES
             = "1|req|reqonly|req-only | "
             + "2|rrh|reqresphdr|req-resp-hdr | "
@@ -78,34 +82,19 @@
         formatter.printHelp("[options] <input pcap> <output nc>", "description", options, "");
     }
 
-    private static Options createOptions() {
-        final Options options = new Options();
+    private Options createOptions() {
+        final CliOptions options = cliHelper.options();
 
-        options.addOption(option("l", "logLevel").desc("Log level.")
-                .hasArg().argName("level")
-                .build()
-        );
+        options.addLogLevelOption();
+        options.addAllowPartialSessionOption();
+        options.addHttpFiltersFileOption();
+        options.addHttpPortsOption();
 
         options.addOption(option("do", "").desc("Destination override ([ask]|yes|no)")
                 .hasArg().argName("")
                 .build()
         );
 
-        options.addOption(option("ff", "filtersFile").desc("Filters file.")
-                .hasArg().argName("file")
-                .build()
-        );
-
-        options.addOption(option("ps", "allowPartialSession").desc("Allow partial sessions.")
-                .hasArg(false)
-                .build()
-        );
-
-        options.addOption(option("hp", "httpPorts").desc("Specify HTTP ports in input file (default: 80, 8080)")
-                .hasArg().argName("ports")
-                .build()
-        );
-
 //        options.addOption(option("wm", "writeMetrics").desc("Write metrics to file.")
 //                .hasArg().argName("file")
 //                .build()
@@ -134,13 +123,7 @@
             String output = clArgs[1];
             System.out.println("Converting " + input + " to " + output);
 
-            String logLevel = "error";
-            if (cl.hasOption("l")) {
-                logLevel = cl.getOptionValue("l");
-            }
-            if (!logLevel.equals("default")) {
-                Log4jConfigurationFactory.enableFactory(logLevel);
-            }
+            cliHelper.configureLogger(cl);
 
             boolean overwrite;
             String overwriteOption = cl.getOptionValue("do", "ask").toLowerCase();
@@ -164,38 +147,14 @@
 
             ConverterHttpClient client = new ConverterHttpClient(dst);
 
-            if (cl.hasOption("ff")) {
-                File filtersFile = new File(cl.getOptionValue("ff"));
-                Configuration config = YamlConfigurationReader.readFromFile(filtersFile);
-                HttpFiltersConfigurator configurator = new HttpFiltersConfigurator(client);
-                Errors errors = new Errors();
-                configurator.configure(config, errors, null);
-                if (errors.getErrorCount() != 0) {
-                    System.out.println("Error in file '" + filtersFile.getAbsolutePath() + "'.");
-                    for (ObjectError error : errors.getAllErrors()) {
-                        System.out.println("\t" + objectErrorToString(error));
-                    }
-                    System.exit(1);
-                }
+            List<HttpFilter> httpFilters = cliHelper.readHttpFilters(cl);
+            if (httpFilters != null) {
+                httpFilters.forEach((filter) -> client.addFilter(filter));
             }
 
             client.start();
 
-            PcapSessionEventSource eventSrc = new PcapSessionEventSource();
-            eventSrc.setPcapFile(input);
-            eventSrc.setAllowPartialSession(cl.hasOption("ps"));
-            eventSrc.setCollectMetrics(true);
-
-            if (cl.hasOption("hp")) {
-                PortRangeSet portsRanges = eventSrc.getPortsRange();
-                portsRanges.clear();
-
-                String[] ports = cl.getOptionValues("hp");
-                for (String port : ports) {
-                    portsRanges.add(port);
-                }
-            }
-
+            PcapSessionEventSource eventSrc = cliHelper.createPcapEventSource(input, cl);
             eventSrc.setHandler(client);
             eventSrc.start();
 
@@ -203,7 +162,6 @@
             client.join();
             eventSrc.stop();
             client.stop();
-
         } catch (ParseException e) {
             System.out.println(e.getMessage());
             printHelp(options);
--- a/stress-tester/src/main/java/com/passus/st/Main.java	Wed Dec 13 11:49:31 2017 +0100
+++ b/stress-tester/src/main/java/com/passus/st/Main.java	Wed Dec 13 12:33:49 2017 +0100
@@ -9,7 +9,6 @@
 import com.passus.config.validation.Errors;
 import static com.passus.config.validation.ErrorsUtils.objectErrorToString;
 import com.passus.config.validation.ObjectError;
-import com.passus.net.PortRangeSet;
 import com.passus.st.client.MemoryEventsCache;
 import com.passus.st.client.http.DumperHttpClientListener;
 import com.passus.st.client.http.HttpClient;
@@ -19,22 +18,17 @@
 import com.passus.st.client.http.ReporterFileDestination;
 import com.passus.st.client.http.SummaryHttpClientListener;
 import com.passus.st.client.http.WriterHttpClientListener;
+import com.passus.st.client.http.filter.HttpFilter;
 import com.passus.st.client.http.filter.HttpFiltersConfigurator;
-import com.passus.st.emitter.PassThroughSessionMapper;
-import com.passus.st.emitter.RuleBasedSessionMapper;
 import com.passus.st.emitter.SessionMapper;
 import com.passus.st.emitter.nio.NioEmitter;
 import com.passus.st.metric.FileMetricsCollectionAppender;
 import com.passus.st.metric.MetricSource;
 import com.passus.st.metric.ScheduledMetricsCollector;
 import com.passus.st.metric.SummrizeMetricsCollectionHandler;
-import com.passus.st.reader.nc.NcHeader;
-import com.passus.st.reader.pcap.PcapFileHeader;
 import com.passus.st.reporter.ReporterClient;
 import com.passus.st.reporter.trx.SocketReporterClient;
 import com.passus.st.source.EventSource;
-import com.passus.st.source.NcEventSource;
-import com.passus.st.source.PcapSessionEventSource;
 import com.passus.st.utils.PeriodFormatter;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -57,8 +51,6 @@
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.io.IOUtils;
 import static com.passus.st.utils.CliUtils.option;
-import java.io.InputStream;
-import static org.apache.commons.io.FileUtils.openInputStream;
 
 /**
  *
@@ -66,6 +58,8 @@
  */
 public class Main {
 
+    private final CliHelper cliHelper = new CliHelper();
+
     private final SummrizeMetricsCollectionHandler summMetricsHandler = new SummrizeMetricsCollectionHandler();
     private long startTime;
 
@@ -107,43 +101,13 @@
         }
     }
 
-    void printMetrics() {
-        List<Metric> metrics = summMetricsHandler.getMetrics();
-        printMetrics(metrics, startTime);
-    }
-
-    List<Metric> getMetrics() {
-        return summMetricsHandler.getMetrics();
-    }
-
-    void start(String... args) {
-        AppUtils.registerAll();
-        final Options options = new Options();
-
-        options.addOption(option("l", "logLevel").desc("Log level.")
-                .hasArg().argName("level")
-                .build()
-        );
+    private Options createOptions() {
+        CliOptions options = cliHelper.options();
 
-        options.addOption(option("ff", "filtersFile").desc("Filters file.")
-                .hasArg().argName("file")
-                .build()
-        );
-
-        options.addOption(option("mr", "mapperRule").desc("Session mapper rule.")
-                .hasArg().argName("rule")
-                .build()
-        );
-
-        options.addOption(option("ps", "allowPartialSession").desc("Allow partial sessions.")
-                .hasArg(false)
-                .build()
-        );
-
-        options.addOption(option("hp", "httpPorts").desc("Specify HTTP ports in input file (default: 80, 8080)")
-                .hasArg().argName("ports")
-                .build()
-        );
+        options.addLogLevelOption();
+        options.addMapperRuleOption();
+        options.addAllowPartialSessionOption();
+        options.addHttpClientOptions();
 
         options.addOption(option("rs", "replaySpeed").desc("Speedup factor (default 0 - top speed)")
                 .hasArg().argName("speed")
@@ -200,6 +164,22 @@
                 .build()
         );
 
+        return options;
+    }
+
+    void printMetrics() {
+        List<Metric> metrics = summMetricsHandler.getMetrics();
+        printMetrics(metrics, startTime);
+    }
+
+    List<Metric> getMetrics() {
+        return summMetricsHandler.getMetrics();
+    }
+
+    void start(String... args) {
+        AppUtils.registerAll();
+        Options options = createOptions();
+
         try {
             CommandLine cl = new DefaultParser().parse(options, args);
             String[] clArgs = cl.getArgs();
@@ -209,30 +189,8 @@
                 return;
             }
 
-            String logLevel = "error";
-            if (cl.hasOption("l")) {
-                logLevel = cl.getOptionValue("l");
-            }
-            if (!logLevel.equals("default")) {
-                Log4jConfigurationFactory.enableFactory(logLevel);
-            }
-
-            SessionMapper mapper;
-            if (cl.hasOption("mr")) {
-                RuleBasedSessionMapper constMapper = new RuleBasedSessionMapper();
-                String[] rules = cl.getOptionValues("mr");
-                for (String rule : rules) {
-                    try {
-                        constMapper.addRule(rule);
-                    } catch (Exception e) {
-                        printError("Invalid mapper rule '" + rule + "'.");
-                    }
-                }
-
-                mapper = constMapper;
-            } else {
-                mapper = new PassThroughSessionMapper();
-            }
+            cliHelper.configureLogger(cl);
+            SessionMapper mapper = cliHelper.createMapper(cl);
 
             NioEmitter emitter = new NioEmitter();
             emitter.setSessionMapper(mapper);
@@ -332,66 +290,16 @@
                 collector.addHandler(reporterDestination);
             }
 
-            if (cl.hasOption("ff")) {
-                File filtersFile = new File(cl.getOptionValue("ff"));
-                Configuration config = YamlConfigurationReader.readFromFile(filtersFile);
-                HttpFiltersConfigurator configurator = new HttpFiltersConfigurator(client);
-                Errors errors = new Errors();
-                configurator.configure(config, errors, null);
-                if (errors.getErrorCount() != 0) {
-                    System.out.println("Error in file '" + filtersFile.getAbsolutePath() + "'.");
-                    for (ObjectError error : errors.getAllErrors()) {
-                        System.out.println("\t" + objectErrorToString(error));
-                    }
-                    System.exit(1);
-                }
+            List<HttpFilter> httpFilters = cliHelper.readHttpFilters(cl);
+            if (httpFilters != null) {
+                httpFilters.forEach((filter) -> client.addFilter(filter));
             }
 
             client.start();
 
             EventSource[] eventSrcs = new EventSource[clArgs.length];
-
             for (int i = 0; i < clArgs.length; i++) {
-                String srcFile = clArgs[i];
-                byte[] preambule = null;
-                InputStream in = null;
-                try {
-                    in = openInputStream(new File(srcFile));
-                    preambule = IOUtils.toByteArray(in, 20);
-                } finally {
-                    IOUtils.closeQuietly(in);
-                }
-
-                if (NcHeader.isPreambule(preambule, 0)) {
-                    NcEventSource eventSrc = new NcEventSource(srcFile);
-                    eventSrcs[i] = eventSrc;
-                } else if (PcapFileHeader.isFormatSupported(preambule)) {
-                    PcapSessionEventSource eventSrc = new PcapSessionEventSource();
-                    eventSrc.setPcapFile(clArgs[i]);
-                    eventSrc.setAllowPartialSession(cl.hasOption("ps"));
-                    eventSrc.setCollectMetrics(true);
-                    eventSrcs[i] = eventSrc;
-                } else {
-                    printError("Not supported file format '" + srcFile + "'.");
-                }
-
-            }
-
-            if (cl.hasOption("hp")) {
-                for (int i = 0; i < clArgs.length; i++) {
-                    EventSource eventSrc = eventSrcs[i];
-                    //TODO rozszerzyc na NcEventSource
-                    if (eventSrc instanceof PcapSessionEventSource) {
-                        PcapSessionEventSource pcapSessionEventSource = (PcapSessionEventSource) eventSrc;
-                        PortRangeSet portsRanges = pcapSessionEventSource.getPortsRange();
-                        portsRanges.clear();
-
-                        String[] ports = cl.getOptionValues("hp");
-                        for (String port : ports) {
-                            portsRanges.add(port);
-                        }
-                    }
-                }
+                eventSrcs[i] = cliHelper.createEventSource(clArgs[i], cl);
             }
 
             int loops = Integer.parseInt(cl.getOptionValue("lp", "1"));
--- a/stress-tester/src/main/java/com/passus/st/Main2.java	Wed Dec 13 11:49:31 2017 +0100
+++ b/stress-tester/src/main/java/com/passus/st/Main2.java	Wed Dec 13 12:33:49 2017 +0100
@@ -19,6 +19,7 @@
 import com.passus.st.client.http.ReporterFileDestination;
 import com.passus.st.client.http.SummaryHttpClientListener;
 import com.passus.st.client.http.WriterHttpClientListener;
+import com.passus.st.client.http.filter.HttpFilter;
 import com.passus.st.client.http.filter.HttpFiltersConfigurator;
 import com.passus.st.emitter.PassThroughSessionMapper;
 import com.passus.st.emitter.RuleBasedSessionMapper;
@@ -60,6 +61,7 @@
  */
 public class Main2 {
 
+    private final CliHelper cliHelper = new CliHelper();
     private final SummrizeMetricsCollectionHandler summMetricsHandler = new SummrizeMetricsCollectionHandler();
     private long startTime;
 
@@ -68,11 +70,6 @@
         formatter.printHelp("[options] <pcap>", "description", options, "");
     }
 
-    static void printError(String msg) {
-        System.err.print(msg);
-        System.exit(1);
-    }
-
     static void printMetrics(List<Metric> metrics, long startTime) {
         if (startTime == 0) {
             return;
@@ -203,30 +200,8 @@
                 return;
             }
 
-            String logLevel = "error";
-            if (cl.hasOption("l")) {
-                logLevel = cl.getOptionValue("l");
-            }
-            if (!logLevel.equals("default")) {
-                Log4jConfigurationFactory.enableFactory(logLevel);
-            }
-
-            SessionMapper mapper;
-            if (cl.hasOption("mr")) {
-                RuleBasedSessionMapper constMapper = new RuleBasedSessionMapper();
-                String[] rules = cl.getOptionValues("mr");
-                for (String rule : rules) {
-                    try {
-                        constMapper.addRule(rule);
-                    } catch (Exception e) {
-                        printError("Invalid mapper rule '" + rule + "'.");
-                    }
-                }
-
-                mapper = constMapper;
-            } else {
-                mapper = new PassThroughSessionMapper();
-            }
+            cliHelper.configureLogger(cl);
+            SessionMapper mapper = cliHelper.createMapper(cl);
 
             NioEmitter emitter = new NioEmitter(NioEmitterWorker2.class);
             emitter.setSessionMapper(mapper);
@@ -326,19 +301,9 @@
                 collector.addHandler(reporterDestination);
             }
 
-            if (cl.hasOption("ff")) {
-                File filtersFile = new File(cl.getOptionValue("ff"));
-                Configuration config = YamlConfigurationReader.readFromFile(filtersFile);
-                HttpFiltersConfigurator configurator = new HttpFiltersConfigurator(client);
-                Errors errors = new Errors();
-                configurator.configure(config, errors, null);
-                if (errors.getErrorCount() != 0) {
-                    System.out.println("Error in file '" + filtersFile.getAbsolutePath() + "'.");
-                    for (ObjectError error : errors.getAllErrors()) {
-                        System.out.println("\t" + objectErrorToString(error));
-                    }
-                    System.exit(1);
-                }
+            List<HttpFilter> httpFilters = cliHelper.readHttpFilters(cl);
+            if (httpFilters != null) {
+                httpFilters.forEach((filter) -> client.addFilter(filter));
             }
 
             client.start();
@@ -374,7 +339,7 @@
             if (cl.hasOption("wm")) {
                 File metricsFile = new File(cl.getOptionValue("wm"));
                 if (!metricsFile.exists() && !metricsFile.createNewFile()) {
-                    printError("Unable to create metrics file '" + metricsFile + "'.");
+                    cliHelper.printError("Unable to create metrics file '" + metricsFile + "'.");
                 }
 
                 FileMetricsCollectionAppender fileAppender = new FileMetricsCollectionAppender();
--- a/stress-tester/src/main/java/com/passus/st/ReaderMain.java	Wed Dec 13 11:49:31 2017 +0100
+++ b/stress-tester/src/main/java/com/passus/st/ReaderMain.java	Wed Dec 13 12:33:49 2017 +0100
@@ -1,24 +1,16 @@
 package com.passus.st;
 
-import com.passus.net.PortRangeSet;
 import com.passus.st.client.Event;
 import com.passus.st.client.SessionStatusEvent;
 import com.passus.st.client.http.HttpSessionPayloadEvent;
 import com.passus.st.emitter.SessionInfo;
-import com.passus.st.reader.nc.NcHeader;
-import com.passus.st.reader.pcap.PcapFileHeader;
+import com.passus.st.source.EventSource;
 import com.passus.st.source.NcEventSource;
 import com.passus.st.source.PcapSessionEventSource;
-import static com.passus.st.utils.CliUtils.option;
-import java.io.File;
-import java.io.InputStream;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.DefaultParser;
 import org.apache.commons.cli.HelpFormatter;
 import org.apache.commons.cli.Options;
-import static org.apache.commons.io.FileUtils.openInputStream;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
 
 /**
  *
@@ -26,32 +18,23 @@
  */
 public class ReaderMain {
 
+    private final CliHelper cliHelper = new CliHelper();
+
     private void printHelp(Options options) {
         HelpFormatter formatter = new HelpFormatter();
         formatter.printHelp("[options] <file>", "description", options, "");
     }
 
     private Options createOptions() {
-        final Options options = new Options();
+        final CliOptions options = cliHelper.options();
 
-        options.addOption(option("ps", "allowPartialSession").desc("Allow partial sessions. Only pcap file.")
-                .hasArg(false)
-                .build()
-        );
-
-        options.addOption(option("hp", "httpPorts").desc("Specify HTTP ports in input file (default: 80, 8080). Only pcap file.")
-                .hasArg().argName("ports")
-                .build()
-        );
+        options.addLogLevelOption();
+        options.addAllowPartialSessionOption();
+        options.addHttpPortsOption();
 
         return options;
     }
 
-    private void printError(String msg) {
-        System.err.print(msg);
-        System.exit(1);
-    }
-
     private void printSessionInfo(SessionInfo session) {
         System.out.print("----- ");
         System.out.print(session);
@@ -80,8 +63,7 @@
         }
     }
 
-    private void readNcFile(String filename) throws Exception {
-        NcEventSource src = new NcEventSource(filename);
+    private void readNcFile(NcEventSource src) throws Exception {
         src.setHandler((event) -> printEvent(event));
 
         try {
@@ -92,22 +74,7 @@
         }
     }
 
-    private void readPcapFile(String filename, CommandLine cl) throws Exception {
-        PcapSessionEventSource eventSrc = new PcapSessionEventSource();
-        eventSrc.setPcapFile(filename);
-        eventSrc.setAllowPartialSession(cl.hasOption("ps"));
-        eventSrc.setCollectMetrics(true);
-
-        if (cl.hasOption("hp")) {
-            PortRangeSet portsRanges = eventSrc.getPortsRange();
-            portsRanges.clear();
-
-            String[] ports = cl.getOptionValues("hp");
-            for (String port : ports) {
-                portsRanges.add(port);
-            }
-        }
-
+    private void readPcapFile(PcapSessionEventSource eventSrc) throws Exception {
         eventSrc.setHandler((event) -> printEvent(event));
         try {
             eventSrc.start();
@@ -130,25 +97,14 @@
                 return;
             }
 
-            String filename = clArgs[0];
-            String ext = FilenameUtils.getExtension(filename);
-            File srcFile = new File(filename);
-            InputStream in = null;
-            
-            byte[] preambule = null;
-            try {
-                in = openInputStream(srcFile);
-                preambule = IOUtils.toByteArray(in, 20);
-            } finally {
-                IOUtils.closeQuietly(in);
-            }
-
-            if (NcHeader.isPreambule(preambule, 0)) {
-                readNcFile(filename);
-            } else if (PcapFileHeader.isFormatSupported(preambule)) {
-                readPcapFile(filename, cl);
+            cliHelper.configureLogger(cl);
+            EventSource eventSource = cliHelper.createEventSource(clArgs[0], cl);
+            if (eventSource instanceof NcEventSource) {
+                readNcFile((NcEventSource) eventSource);
+            } else if (eventSource instanceof PcapSessionEventSource) {
+                readPcapFile((PcapSessionEventSource) eventSource);
             } else {
-                printError("Not supported file extension '" + ext + "'.");
+                cliHelper.printError("Not supported event source type '" + eventSource.getType() + "'.");
             }
         } catch (Exception e) {
             e.printStackTrace(System.err);
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpFiltersConfigurator.java	Wed Dec 13 11:49:31 2017 +0100
+++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpFiltersConfigurator.java	Wed Dec 13 12:33:49 2017 +0100
@@ -1,6 +1,5 @@
 package com.passus.st.client.http.filter;
 
-import com.passus.commons.Assert;
 import com.passus.config.CListNode;
 import com.passus.config.CMapNode;
 import com.passus.config.CNode;
@@ -18,6 +17,7 @@
 import com.passus.config.YamlConfigurationReader;
 import java.io.File;
 import java.io.IOException;
+import java.util.Collections;
 
 /**
  *
@@ -27,11 +27,10 @@
 
     private static final ConfigurationSchema SCHEMA = new ConfigurationSchemaImpl(new HttpFiltersNodeDefinitionCreator().create());
 
-    private final HttpFilterAware client;
+    private final List<HttpFilter> filters = Collections.EMPTY_LIST;
 
-    public HttpFiltersConfigurator(HttpFilterAware client) {
-        Assert.notNull(client, "client");
-        this.client = client;
+    public List<HttpFilter> getFilters() {
+        return filters;
     }
 
     public static List<HttpFilter> getFilters(File configFile, Errors errors, ConfigurationContext context) throws IOException, NodeException {
@@ -79,11 +78,10 @@
 
     @Override
     public void configure(Configuration config, Errors errors, ConfigurationContext context) {
-        List<HttpFilter> filters = getFilters(config, errors, context);
+        List<HttpFilter> cfgFilters = getFilters(config, errors, context);
+        filters.clear();
         if (errors.getErrorCount() == 0) {
-            for (HttpFilter filter : filters) {
-                client.addFilter(filter);
-            }
+            filters.addAll(cfgFilters);
         }
     }
 
--- a/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpFiltersConfiguratorTest.java	Wed Dec 13 11:49:31 2017 +0100
+++ b/stress-tester/src/test/java/com/passus/st/client/http/filter/HttpFiltersConfiguratorTest.java	Wed Dec 13 12:33:49 2017 +0100
@@ -1,19 +1,14 @@
 package com.passus.st.client.http.filter;
 
 import com.passus.commons.utils.ResourceUtils;
-import com.passus.config.Configuration;
 import com.passus.config.ConfigurationContext;
-import com.passus.config.YamlConfigurationReader;
 import com.passus.config.validation.Errors;
 import com.passus.st.client.credentials.MultiCredentialsProvider;
 import com.passus.st.client.credentials.UsernamePasswordCredentialsProvider;
-import com.passus.st.client.http.HttpClient;
 import java.io.File;
 import java.util.List;
-import org.mockito.ArgumentCaptor;
 import static org.testng.AssertJUnit.*;
 import org.testng.annotations.Test;
-import static org.mockito.Mockito.*;
 
 /**
  *
@@ -24,19 +19,11 @@
     @Test
     public void testConfigure() throws Exception {
         File file = ResourceUtils.getFile("com/passus/st/client/http/filter/http_message_modify_filter.yml");
-        Configuration config = YamlConfigurationReader.readFromFile(file);
-
-        ArgumentCaptor<HttpFilter> captor = ArgumentCaptor.forClass(HttpFilter.class);
-        HttpClient client = mock(HttpClient.class);
 
-        HttpFiltersConfigurator configurator = new HttpFiltersConfigurator(client);
         Errors errors = new Errors();
-        configurator.configure(config, errors, ConfigurationContext.create());
+        List<HttpFilter> filters = HttpFiltersConfigurator.getFilters(file, errors, ConfigurationContext.create());
         assertEquals(0, errors.getErrorCount());
-        
-        verify(client, times(3)).addFilter(captor.capture());
 
-        List<HttpFilter> filters = captor.getAllValues();
         assertTrue(filters.get(0) instanceof HttpMessageModificationFilter);
         HttpMessageModificationFilter modFilter = (HttpMessageModificationFilter) filters.get(0);
         assertEquals(6, modFilter.getOperations().size());