changeset 1137:49969086dded

HttpUrlStatsMetric
author Devel 1
date Tue, 09 Jun 2020 12:00:22 +0200
parents 8e488159250f
children 730898c04e80
files stress-tester/src/main/java/com/passus/st/scanner/HttpUrlStatsMetric.java stress-tester/src/test/java/com/passus/st/scanner/HttpUrlStatsMetricTest.java
diffstat 2 files changed, 134 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/stress-tester/src/main/java/com/passus/st/scanner/HttpUrlStatsMetric.java	Tue Jun 09 08:34:36 2020 +0200
+++ b/stress-tester/src/main/java/com/passus/st/scanner/HttpUrlStatsMetric.java	Tue Jun 09 12:00:22 2020 +0200
@@ -1,10 +1,17 @@
 package com.passus.st.scanner;
 
 import com.passus.commons.metric.Metric;
+import com.passus.data.ByteString;
+import static com.passus.data.DataDecoder.RES_ERROR;
+import com.passus.data.GenericPair;
+import com.passus.net.http.HttpParameters;
+import com.passus.net.http.HttpParametersDecoder;
 import com.passus.st.client.GenericMetric;
+import java.util.ArrayList;
 import org.apache.commons.lang3.mutable.MutableInt;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 public class HttpUrlStatsMetric extends GenericMetric {
@@ -21,7 +28,11 @@
 
     private final HashMap<String, MutableInt> cleaned = new HashMap<>();
 
-    private final HashMap<String, MutableInt> urls = new HashMap<>();
+//    private final HashMap<String, MutableInt> urls = new HashMap<>();
+    private final HashMap<String, MutableInt> paths = new HashMap<>();
+    private final HashMap<String, MutableInt> pathsKeys = new HashMap<>();
+    private final HashMap<String, MutableInt> keys = new HashMap<>();
+    private final HashMap<String, MutableInt> keysValues = new HashMap<>();
 
     {
         for (String clean : CLEAN_RULES_ARR) {
@@ -31,7 +42,11 @@
 
     public HttpUrlStatsMetric(String name) {
         super(name);
-        attrs.put("urls", urls);
+//        attrs.put("urls", urls);
+        attrs.put("paths", paths);
+        attrs.put("pathsKeys", pathsKeys);
+        attrs.put("keys", keys);
+        attrs.put("keysValues", keysValues);
         attrs.put("cleaned", cleaned);
     }
 
@@ -40,47 +55,102 @@
     }
 
     public void addUrl(String url) {
-        boolean ignored = false;
+        url = url.toLowerCase().trim();
+
         for (Map.Entry<String, MutableInt> e : cleaned.entrySet()) {
             if (url.contains(e.getKey())) {
                 e.getValue().increment();
-                ignored = true;
-                break;
+                return;
             }
         }
-        if (!ignored) {
-            Metric.incrementCountMap(url, urls);
-            String path;
-            String query;
-            int qidx = url.indexOf('?');
-            if (qidx < 0) {
-                path = url;
-                query = "";
-            } else {
-                path = url.substring(0, qidx);
-                if (qidx < url.length()) {
-                    query = url.substring(qidx + 1);
-                } else {
-                    query = "";
+
+//        Metric.incrementCountMap(url, urls);
+        String path;
+        String pathWithKeys = null;
+        int qidx = url.indexOf('?');
+        if (qidx < 0) {
+            path = url;
+        } else {
+            path = url.substring(0, qidx).trim();
+            if (qidx < url.length()) {
+                String queryStr = url.substring(qidx + 1).trim();
+                HttpParameters query = decodeQuery(queryStr);
+                if (query != null) {
+                    ArrayList<String> queryKeys = keys(query);
+                    for (String queryKey : queryKeys) {
+                        Metric.incrementCountMap(queryKey, keys);
+                    }
+                    pathWithKeys = join(path, queryKeys);
+                    ArrayList<String> queryKeyValues = keyValues(query);
+                    for (String queryKeyValue : queryKeyValues) {
+                        Metric.incrementCountMap(queryKeyValue, keysValues);
+                    }
                 }
             }
-            
-            path = path.toLowerCase().trim();
-            query = query.toLowerCase().trim();
-//            method = 
         }
+        if (pathWithKeys == null) {
+            pathWithKeys = path;
+        }
+        Metric.incrementCountMap(path, paths);
+        Metric.incrementCountMap(pathWithKeys, pathsKeys);
+    }
+
+    private static HttpParameters decodeQuery(String query) {
+        synchronized (HttpParametersDecoder.STRICT) {
+            int decode = HttpParametersDecoder.STRICT.decode(query);
+            if (decode != RES_ERROR) {
+                return HttpParametersDecoder.STRICT.getResult();
+            }
+            return null;
+        }
+    }
+
+    private static String join(String path, ArrayList<String> keys) {
+        StringBuilder sb = new StringBuilder(path);
+        for (String key : keys) {
+            sb.append('|').append(key);
+        }
+        return sb.toString();
+    }
+
+    private static ArrayList<String> keys(HttpParameters query) {
+        List<GenericPair<ByteString, ByteString>> pairs = query.getAll();
+        ArrayList<String> result = new ArrayList<>(pairs.size());
+        for (GenericPair<ByteString, ByteString> pair : pairs) {
+            result.add(pair.getLeft().toString());
+        }
+        result.sort(null);
+        return result;
+    }
+    
+    private static ArrayList<String> keyValues(HttpParameters query) {
+        List<GenericPair<ByteString, ByteString>> pairs = query.getAll();
+        ArrayList<String> result = new ArrayList<>(pairs.size());
+        for (GenericPair<ByteString, ByteString> pair : pairs) {
+            result.add(pair.getLeft().toString() + "=" + pair.getRight().toString());
+        }
+        result.sort(null);
+        return result;
     }
 
     @Override
     public void update(Metric metric) {
         HttpUrlStatsMetric m = (HttpUrlStatsMetric) metric;
-        Metric.updateCountMap(urls, m.urls);
+//        Metric.updateCountMap(urls, m.urls);
+        Metric.updateCountMap(paths, m.paths);
+        Metric.updateCountMap(pathsKeys, m.pathsKeys);
+        Metric.updateCountMap(keys, m.keys);
+        Metric.updateCountMap(keysValues, m.keysValues);
         Metric.updateCountMap(cleaned, m.cleaned);
     }
 
     @Override
     public void reset() {
-        urls.clear();
+//        urls.clear();
+        paths.clear();
+        pathsKeys.clear();
+        keys.clear();
+        keysValues.clear();
         cleaned.clear();
     }
 }
--- a/stress-tester/src/test/java/com/passus/st/scanner/HttpUrlStatsMetricTest.java	Tue Jun 09 08:34:36 2020 +0200
+++ b/stress-tester/src/test/java/com/passus/st/scanner/HttpUrlStatsMetricTest.java	Tue Jun 09 12:00:22 2020 +0200
@@ -6,9 +6,11 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStreamReader;
-import java.io.Serializable;
 import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import org.apache.commons.lang3.mutable.MutableInt;
 import static org.testng.AssertJUnit.*;
@@ -38,9 +40,30 @@
         assertEquals(155, cleaned.get(".css").intValue());
         assertEquals(613, sumValues(cleaned));
 
-        HashMap<String, MutableInt> urls = (HashMap<String, MutableInt>) instance.getAttributeValue("urls");
-        assertEquals(9387, sumValues(urls));
+//        HashMap<String, MutableInt> urls = (HashMap<String, MutableInt>) instance.getAttributeValue("urls");
+//        assertEquals(9387, sumValues(urls));
 
+        HashMap<String, MutableInt> paths = (HashMap<String, MutableInt>) instance.getAttributeValue("paths");
+        assertEquals(4091, paths.get("/ably").intValue());
+        assertEquals(24, paths.get("/users/sign_in").intValue());
+        assertEquals(9387, sumValues(paths));
+
+        HashMap<String, MutableInt> pathsWithKeys = (HashMap<String, MutableInt>) instance.getAttributeValue("pathsKeys");
+        assertEquals(2213, pathsWithKeys.get("/pt/ably|clientid|rnd").intValue());
+        assertEquals(1764, pathsWithKeys.get("/okcomputer").intValue());
+        assertEquals(645, pathsWithKeys.get("/ably|access_code|capability|clientid").intValue());
+        assertEquals(563, pathsWithKeys.get("/ably|rnd").intValue());
+        assertEquals(9387, sumValues(pathsWithKeys));
+
+        HashMap<String, MutableInt> keys = (HashMap<String, MutableInt>) instance.getAttributeValue("keys");
+        assertEquals(5723, keys.get("clientid").intValue());
+        assertEquals(5547, keys.get("rnd").intValue());
+        assertEquals(102, keys.get("timestamp").intValue());
+
+        HashMap<String, MutableInt> keysValues = (HashMap<String, MutableInt>) instance.getAttributeValue("keysValues");
+        assertEquals(858, keysValues.get("clientid=production_au.client/2689116").intValue());
+        assertEquals(854, keysValues.get("clientid=production_au.provider/3231350").intValue());
+        assertEquals(102, keysValues.get("capability={\"*\":[\"*\"]}").intValue());
         System.out.println("");
     }
 
@@ -52,14 +75,24 @@
         return sum;
     }
 
-    @Test
+    static final Comparator<Map.Entry<String, MutableInt>> BY_VALUE_DESC = (o1, o2) -> o2.getValue().intValue() - o1.getValue().intValue();
+
+    static LinkedHashMap<String, MutableInt> sortByValue(Map<String, MutableInt> m) {
+        ArrayList<Map.Entry<String, MutableInt>> values = new ArrayList<>(m.entrySet());
+        values.sort(BY_VALUE_DESC);
+        LinkedHashMap<String, MutableInt> result = new LinkedHashMap<>(values.size());
+        for (Map.Entry<String, MutableInt> value : values) {
+            result.put(value.getKey(), value.getValue());
+        }
+        return result;
+    }
+
+//    @Test
     public void testUpdate() {
-        System.out.println("update");
         Metric metric = null;
         HttpUrlStatsMetric instance = new HttpUrlStatsMetric();
         instance.update(metric);
         instance.reset();
-        // TODO review the generated test code and remove the default call to fail.
         fail("The test case is a prototype.");
     }