changeset 824:28ec5d69ea33

Global configuration in progress
author Devel 2
date Thu, 18 Jan 2018 13:21:36 +0100
parents f85afb8f6d54
children a8fbdb409d7c
files stress-tester/src/main/java/com/passus/st/client/http/filter/HttpFiltersNodeDefinitionCreator.java stress-tester/src/main/java/com/passus/st/emitter/Emitter.java stress-tester/src/main/java/com/passus/st/emitter/RuleBasedSessionMapper.java stress-tester/src/main/java/com/passus/st/emitter/RuleBasedSessionMapperValueTransformer.java stress-tester/src/main/java/com/passus/st/emitter/RuleSessionMapperValueTransformer.java stress-tester/src/main/java/com/passus/st/emitter/SessionMapperNodeDefinitionCreator.java stress-tester/src/main/java/com/passus/st/emitter/nio/NioEmitter.java stress-tester/src/main/java/com/passus/st/plugin/PluginConstants.java stress-tester/src/test/java/com/passus/st/emitter/SessionMapperNodeDefinitionCreatorTest.java
diffstat 9 files changed, 216 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpFiltersNodeDefinitionCreator.java	Thu Jan 18 11:51:18 2018 +0100
+++ b/stress-tester/src/main/java/com/passus/st/client/http/filter/HttpFiltersNodeDefinitionCreator.java	Thu Jan 18 13:21:36 2018 +0100
@@ -4,6 +4,7 @@
 import com.passus.config.schema.DynaKeyValueVaryListNodeDefinition;
 import com.passus.config.schema.NodeDefinition;
 import com.passus.config.schema.NodeDefinitionCreator;
+import static com.passus.config.schema.ConfigurationSchemaBuilder.*;
 
 /**
  *
@@ -25,4 +26,5 @@
         return mapDef(tupleDef("filters", createFiltersList()));
     }
 
+
 }
--- a/stress-tester/src/main/java/com/passus/st/emitter/Emitter.java	Thu Jan 18 11:51:18 2018 +0100
+++ b/stress-tester/src/main/java/com/passus/st/emitter/Emitter.java	Thu Jan 18 13:21:36 2018 +0100
@@ -2,6 +2,11 @@
 
 import com.passus.commons.service.Service;
 import com.passus.config.Configurable;
+import com.passus.config.Configuration;
+import static com.passus.config.schema.ConfigurationSchemaBuilder.mapDef;
+import static com.passus.config.schema.ConfigurationSchemaBuilder.tupleDef;
+import com.passus.config.schema.MapNodeDefinition;
+import com.passus.config.schema.NodeDefinitionCreator;
 import com.passus.st.metric.MetricSource;
 import java.io.IOException;
 
@@ -11,10 +16,27 @@
  */
 public interface Emitter extends Service, MetricSource, Configurable {
 
+    public static final SessionMapper DEFAULT_SESSION_MAPPER = new PassThroughSessionMapper();
+
     public void setSessionMapper(SessionMapper mapper);
 
     public SessionMapper getSessionMapper();
 
     public void connect(SessionInfo session, EmitterHandler handler, int workerIndex) throws IOException;
 
+    @Override
+    public default void configure(Configuration config) {
+        setSessionMapper((SessionMapper) config.get("sessionMapper", DEFAULT_SESSION_MAPPER));
+    }
+
+    public static abstract class EmitterNodeDefCreator implements NodeDefinitionCreator {
+
+        @Override
+        public MapNodeDefinition create() {
+            return mapDef(
+                    tupleDef("sessionMapper", SessionMapperNodeDefinitionCreator.createDef()).setRequired(false)
+            );
+        }
+
+    }
 }
--- a/stress-tester/src/main/java/com/passus/st/emitter/RuleBasedSessionMapper.java	Thu Jan 18 11:51:18 2018 +0100
+++ b/stress-tester/src/main/java/com/passus/st/emitter/RuleBasedSessionMapper.java	Thu Jan 18 13:21:36 2018 +0100
@@ -17,6 +17,7 @@
 import java.net.UnknownHostException;
 import java.text.ParseException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -38,6 +39,17 @@
 
     private final Map<SessionInfo, ConnectionParams> map = new HashMap<>(DEFAULT_SESSIONS_CAPACITY);
 
+    public List<Rule> getRules() {
+        return Collections.unmodifiableList(rules);
+    }
+
+    public void addRule(Rule rule) throws ParseException {
+        Assert.notNull(rule, "rule");
+        synchronized (this) {
+            rules.add(rule);
+        }
+    }
+
     public void addRule(String rule) throws ParseException {
         addRule(rule, HostResolver.DEFAULT);
     }
@@ -220,4 +232,5 @@
         }
 
     }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/emitter/RuleBasedSessionMapperValueTransformer.java	Thu Jan 18 13:21:36 2018 +0100
@@ -0,0 +1,49 @@
+package com.passus.st.emitter;
+
+import com.passus.commons.ConversionException;
+import com.passus.config.ValueTransformer;
+import java.util.List;
+
+/**
+ *
+ * @author Mirosław Hawrot
+ */
+public class RuleBasedSessionMapperValueTransformer implements ValueTransformer {
+
+    public static final RuleBasedSessionMapperValueTransformer INSTANCE = new RuleBasedSessionMapperValueTransformer();
+
+    @Override
+    public Object transform(Object value) throws ConversionException {
+        if (value == null) {
+            return null;
+        }
+
+        RuleBasedSessionMapper mapper = new RuleBasedSessionMapper();
+        if (value instanceof List) {
+            List list = (List) value;
+            for (Object obj : list) {
+                String str = obj.toString();
+                try {
+                    mapper.addRule(str);
+                } catch (Exception e) {
+                    throw new ConversionException("Unable to convert '" + str + "' to session mapper rule. " + e.getMessage(), e);
+                }
+            }
+        } else {
+            String str = value.toString();
+            try {
+                mapper.addRule(str);
+            } catch (Exception e) {
+                throw new ConversionException("Unable to convert '" + str + "' to session mapper rule. " + e.getMessage(), e);
+            }
+        }
+
+        return mapper;
+    }
+
+    @Override
+    public Object reverseTransform(Object obj) throws ConversionException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+}
--- a/stress-tester/src/main/java/com/passus/st/emitter/RuleSessionMapperValueTransformer.java	Thu Jan 18 11:51:18 2018 +0100
+++ b/stress-tester/src/main/java/com/passus/st/emitter/RuleSessionMapperValueTransformer.java	Thu Jan 18 13:21:36 2018 +0100
@@ -10,7 +10,7 @@
 public class RuleSessionMapperValueTransformer implements ValueTransformer {
 
     public static final RuleSessionMapperValueTransformer INSTANCE = new RuleSessionMapperValueTransformer();
-    
+
     @Override
     public Object transform(Object value) throws ConversionException {
         if (value == null) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/emitter/SessionMapperNodeDefinitionCreator.java	Thu Jan 18 13:21:36 2018 +0100
@@ -0,0 +1,29 @@
+package com.passus.st.emitter;
+
+import com.passus.config.schema.NodeDefinition;
+import com.passus.config.schema.NodeDefinitionCreator;
+import static com.passus.config.schema.ConfigurationSchemaBuilder.*;
+
+/**
+ *
+ * @author Mirosław Hawrot
+ */
+public class SessionMapperNodeDefinitionCreator implements NodeDefinitionCreator {
+
+    public static NodeDefinition createDef() {
+        //TODO Dorobic forme
+        //    ruleBased: 
+        //        rules: ["1.1.1.1:80->2.2.2.2:90 bind 172.16.40.10:2001-6000"]
+
+        return mixedDef(
+                valueDef().setTransformer(RuleBasedSessionMapperValueTransformer.INSTANCE),
+                listDef().setTransformer(RuleBasedSessionMapperValueTransformer.INSTANCE)
+        );
+    }
+
+    @Override
+    public NodeDefinition create() {
+        return createDef();
+    }
+
+}
--- a/stress-tester/src/main/java/com/passus/st/emitter/nio/NioEmitter.java	Thu Jan 18 11:51:18 2018 +0100
+++ b/stress-tester/src/main/java/com/passus/st/emitter/nio/NioEmitter.java	Thu Jan 18 13:21:36 2018 +0100
@@ -1,14 +1,20 @@
 package com.passus.st.emitter.nio;
 
-import com.passus.st.emitter.PassThroughSessionMapper;
 import com.passus.st.emitter.SessionMapper;
 import com.passus.commons.Assert;
+import com.passus.commons.annotations.Plugin;
 import com.passus.commons.service.ServiceException;
 import com.passus.config.Configuration;
+import com.passus.config.annotations.NodeDefinitionCreate;
+import static com.passus.config.schema.ConfigurationSchemaBuilder.*;
+import com.passus.config.schema.MapNodeDefinition;
+import com.passus.config.validation.LongValidator;
 import com.passus.st.emitter.Emitter;
 import com.passus.st.emitter.EmitterHandler;
 import com.passus.st.emitter.SessionInfo;
 import com.passus.st.metric.MetricsContainer;
+import com.passus.st.plugin.PluginConstants;
+import com.passus.st.utils.PeriodValueTransformer;
 import java.io.IOException;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -17,23 +23,33 @@
  *
  * @author Mirosław Hawrot
  */
+@NodeDefinitionCreate(NioEmitter.NioEmitterNodeDefCreator.class)
+@Plugin(name = NioEmitter.TYPE, category = PluginConstants.CATEGORY_CLIENT)
 public class NioEmitter implements Emitter {
 
     private static final Logger LOGGER = LogManager.getLogger(NioEmitter.class);
 
+    public static final String TYPE = "nio";
+
+    private static final int DEFAULT_NUM_THREADS = 4;
+
+    private static final long DEFAULT_CONNECTION_TIMEOUT = 5_000;
+
+    private static final boolean DEFAULT_COLLECT_METRICS = false;
+
     private NioEmitterWorker[] workers;
 
-    private int maxThreads = 4;
+    private int maxThreads = DEFAULT_NUM_THREADS;
 
     private volatile boolean started = false;
 
     private NioWorkerDispatcher dispatcher = new NioModuloWorkerDispatcher();
 
-    private SessionMapper sessionMapper = new PassThroughSessionMapper();
+    private SessionMapper sessionMapper = Emitter.DEFAULT_SESSION_MAPPER;
 
-    private boolean collectMetrics = false;
+    private boolean collectMetrics = DEFAULT_COLLECT_METRICS;
 
-    private long connectionTimeout = 5_000;
+    private long connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
 
     private final Class<? extends NioEmitterWorker> workerClass;
 
@@ -115,9 +131,10 @@
 
     @Override
     public void configure(Configuration config) {
-        setMaxThreads(config.getInteger("threads", 4));
-        setConnectionTimeout(config.getInteger("connectionTimeout", 3));
-        setCollectMetrics(config.getBoolean("collectMetrics", true));
+        Emitter.super.configure(config);
+        setMaxThreads(config.getInteger("threads", DEFAULT_NUM_THREADS));
+        setConnectionTimeout(config.getLong("connectionTimeout", DEFAULT_CONNECTION_TIMEOUT));
+        setCollectMetrics(config.getBoolean("collectMetrics", DEFAULT_COLLECT_METRICS));
     }
 
     @Override
@@ -185,4 +202,26 @@
         workers[emitterWorkerIndex].connect(session, emitterHandler);
     }
 
+    public static class NioEmitterNodeDefCreator extends EmitterNodeDefCreator {
+
+        @Override
+        public MapNodeDefinition create() {
+            MapNodeDefinition def = super.create();
+            def.add("threads",
+                    valueDefInteger().addValidator(LongValidator.GREATER_ZERO)
+            ).setRequired(false);
+
+            def.add("connectionTimeout",
+                    valueDef().setTransformer(PeriodValueTransformer.INSTANCE)
+            ).setRequired(false);
+
+            def.add("collectMetrics",
+                    valueDefBool()
+            ).setRequired(false);
+
+            return def;
+        }
+
+    }
+
 }
--- a/stress-tester/src/main/java/com/passus/st/plugin/PluginConstants.java	Thu Jan 18 11:51:18 2018 +0100
+++ b/stress-tester/src/main/java/com/passus/st/plugin/PluginConstants.java	Thu Jan 18 13:21:36 2018 +0100
@@ -18,6 +18,8 @@
 
     public static final String CATEGORY_SESSION_MAPPER = "SessionMapper";
 
+    public static final String CATEGORY_EMITTER = "Emitter";
+
     public static final String CATEGORY_CLIENT = "Client";
 
     public static final String CATEGORY_HTTP_CLIENT_WORKER = "ClientWorker";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/test/java/com/passus/st/emitter/SessionMapperNodeDefinitionCreatorTest.java	Thu Jan 18 13:21:36 2018 +0100
@@ -0,0 +1,51 @@
+package com.passus.st.emitter;
+
+import com.passus.config.CMapNode;
+import com.passus.config.Configuration;
+import com.passus.config.ConfigurationContext;
+import com.passus.config.ConfigurationContextImpl;
+import com.passus.config.YamlConfigurationReader;
+import com.passus.config.schema.NodeDefinition;
+import com.passus.config.validation.Errors;
+import com.passus.net.SocketAddress;
+import static org.testng.Assert.*;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Mirosław Hawrot
+ */
+public class SessionMapperNodeDefinitionCreatorTest {
+    
+    private final SessionMapperNodeDefinitionCreator creator = new SessionMapperNodeDefinitionCreator();
+    
+    private final NodeDefinition nodeDef = creator.create();
+    
+    @DataProvider(name = "validRules")
+    public Object[][] validRules() {
+        return new Object[][]{
+            {"sessionMapper: 1.1.1.1:* -> 2.2.2.2:90", 1},
+            {"sessionMapper: ['1.1.1.1:* -> 2.2.2.2:90', '2.2.2.2:* -> 2.2.2.2:90']", 2}
+        };
+    }
+    
+    @Test(dataProvider = "validRules")
+    public void testTransform_RuleBasedSessionMapper(String configStr, int rulesNum) throws Exception {
+        Configuration config = YamlConfigurationReader.readFromString(configStr);
+        
+        CMapNode rootNode = (CMapNode) config.getRootNode();
+        Errors errors = new Errors();
+        ConfigurationContext context = new ConfigurationContextImpl();
+        Object res = nodeDef.transformToObject(rootNode.getNode("sessionMapper"), errors, context);
+        assertFalse(errors.hasError());
+        
+        assertTrue(res instanceof RuleBasedSessionMapper);
+        RuleBasedSessionMapper sessionMapper = (RuleBasedSessionMapper) res;
+        assertEquals(rulesNum, sessionMapper.getRules().size());
+        RuleBasedSessionMapper.Rule rule = sessionMapper.getRules().get(0);
+        assertEquals(new SocketAddress("2.2.2.2:90"), rule.getRemoteAddress());
+        assertEquals(SessionMapper.ANY_SOCKET, rule.getBindAddress());
+    }
+    
+}