You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sirona.apache.org by rm...@apache.org on 2014/02/10 07:53:14 UTC

svn commit: r1566522 - in /incubator/sirona/trunk: core/src/main/java/org/apache/sirona/counters/ server/ server/boomerang/ server/boomerang/src/ server/boomerang/src/main/ server/boomerang/src/main/java/ server/boomerang/src/main/java/org/ server/boom...

Author: rmannibucau
Date: Mon Feb 10 06:53:14 2014
New Revision: 1566522

URL: http://svn.apache.org/r1566522
Log:
SIRONA-11 basic boomerang integration, collector mode to enhance before releasing

Added:
    incubator/sirona/trunk/server/boomerang/
    incubator/sirona/trunk/server/boomerang/pom.xml
    incubator/sirona/trunk/server/boomerang/src/
    incubator/sirona/trunk/server/boomerang/src/main/
    incubator/sirona/trunk/server/boomerang/src/main/java/
    incubator/sirona/trunk/server/boomerang/src/main/java/org/
    incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/
    incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/
    incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/
    incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/BoomerangServlet.java
    incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/parser/
    incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/parser/BoomerangData.java
    incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/parser/QueryParser.java
    incubator/sirona/trunk/server/boomerang/src/main/resources/
    incubator/sirona/trunk/server/boomerang/src/test/
    incubator/sirona/trunk/server/boomerang/src/test/java/
Modified:
    incubator/sirona/trunk/core/src/main/java/org/apache/sirona/counters/OptimizedStatistics.java
    incubator/sirona/trunk/server/pom.xml

Modified: incubator/sirona/trunk/core/src/main/java/org/apache/sirona/counters/OptimizedStatistics.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/core/src/main/java/org/apache/sirona/counters/OptimizedStatistics.java?rev=1566522&r1=1566521&r2=1566522&view=diff
==============================================================================
--- incubator/sirona/trunk/core/src/main/java/org/apache/sirona/counters/OptimizedStatistics.java (original)
+++ incubator/sirona/trunk/core/src/main/java/org/apache/sirona/counters/OptimizedStatistics.java Mon Feb 10 06:53:14 2014
@@ -24,8 +24,6 @@ public class OptimizedStatistics {
 
     // first moment (mean)
     protected double m1 = Double.NaN;
-    protected double dev = Double.NaN;
-    protected double nDev = Double.NaN;
 
     // second moment
     protected double m2 = Double.NaN;
@@ -35,19 +33,16 @@ public class OptimizedStatistics {
     }
 
     public OptimizedStatistics(final long n, final double sum, final double min,
-                               final double max, final double m1, final double dev,
-                               final double nDev, final double m2) {
+                               final double max, final double m1, final double m2) {
         this.n = n;
         this.sum = sum;
         this.min = min;
         this.max = max;
         this.m1 = m1;
-        this.dev = dev;
-        this.nDev = nDev;
         this.m2 = m2;
     }
 
-    public void addValue(double value) {
+    public OptimizedStatistics addValue(double value) {
         if (n == 0) {
             m1 = 0.0;
             m2 = 0.0;
@@ -67,12 +62,14 @@ public class OptimizedStatistics {
         }
 
         // first moment
-        dev = value - m1;
-        nDev = dev / n;
+        final double dev = value - m1;
+        final double nDev = dev / n;
         m1 += nDev;
 
         // second moment
         m2 += dev * nDev * (n - 1);
+
+        return this;
     }
 
     public void clear() {
@@ -80,8 +77,6 @@ public class OptimizedStatistics {
         sum = 0;
         min = Double.NaN;
         max = Double.NaN;
-        dev = Double.NaN;
-        nDev = Double.NaN;
         m1 = Double.NaN;
         m2 = Double.NaN;
     }
@@ -129,6 +124,6 @@ public class OptimizedStatistics {
     }
 
     public OptimizedStatistics copy() {
-        return new OptimizedStatistics(n, sum, min, max, m1, dev, nDev, m2);
+        return new OptimizedStatistics(n, sum, min, max, m1, m2);
     }
 }

Added: incubator/sirona/trunk/server/boomerang/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/server/boomerang/pom.xml?rev=1566522&view=auto
==============================================================================
--- incubator/sirona/trunk/server/boomerang/pom.xml (added)
+++ incubator/sirona/trunk/server/boomerang/pom.xml Mon Feb 10 06:53:14 2014
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>sirona-server</artifactId>
+    <groupId>org.apache.sirona</groupId>
+    <version>0.2-incubating-SNAPSHOT</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>sirona-boomerang</artifactId>
+  <name>Apache Sirona Incubator :: Server :: Boomerang</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-servlet_3.0_spec</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sirona</groupId>
+      <artifactId>sirona-core</artifactId>
+    </dependency>
+  </dependencies>
+</project>

Added: incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/BoomerangServlet.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/BoomerangServlet.java?rev=1566522&view=auto
==============================================================================
--- incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/BoomerangServlet.java (added)
+++ incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/BoomerangServlet.java Mon Feb 10 06:53:14 2014
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sirona.boomerang;
+
+import org.apache.sirona.Role;
+import org.apache.sirona.SironaException;
+import org.apache.sirona.boomerang.parser.BoomerangData;
+import org.apache.sirona.configuration.ioc.IoCs;
+import org.apache.sirona.counters.Counter;
+import org.apache.sirona.counters.OptimizedStatistics;
+import org.apache.sirona.counters.Unit;
+import org.apache.sirona.math.M2AwareStatisticalSummary;
+import org.apache.sirona.repositories.Repository;
+import org.apache.sirona.store.counter.CollectorCounterStore;
+import org.apache.sirona.store.counter.CounterDataStore;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.sirona.boomerang.parser.QueryParser.parse;
+
+// all data are in query, this is parsed then added to relative counter
+// NOTE: concurrency is not supported
+// TODO: see if more metrics would be interesting or if we want generic metric support
+public class BoomerangServlet extends HttpServlet {
+    private static final String UTF_8 = "UTF-8";
+
+    private static final Unit BYTE_PER_SEC = new Unit("b/s");
+    private static final Role BOOMERANG_PERCEIVED = new Role("boomerang_perceived", Unit.Time.MILLISECOND);
+    private static final Role BOOMERANG_LATENCY = new Role("boomerang_latency", Unit.Time.MILLISECOND);
+    private static final Role BOOMERANG_BANDWITH = new Role("boomerang_bandwidth", BYTE_PER_SEC);
+
+    // marker doesn't make much sense for boomerang
+    private static final String BOOMERANG_MARKER = "boomerang";
+
+    private String encoding = UTF_8;
+    private CollectorCounterStore collectorCounterStore = null;
+    private CounterDataStore counterStore = null;
+
+    @Override
+    public void init(final ServletConfig config) throws ServletException {
+        encoding = config.getInitParameter("encoding");
+        if (encoding == null) {
+            encoding = UTF_8;
+        }
+
+        // force init to ensure we have stores
+        IoCs.findOrCreateInstance(Repository.class);
+        try {
+            collectorCounterStore = IoCs.findOrCreateInstance(CollectorCounterStore.class);
+        } catch (final SironaException se) {
+            counterStore = IoCs.findOrCreateInstance(CounterDataStore.class);
+        }
+    }
+
+    @Override
+    protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+        final BoomerangData data = parse(toMap(req.getQueryString()));
+        if (data.validate()) { // no url
+            // convert to counters
+            final String name = new URL(data.getUrl()).getPath(); // skip query
+            if (data.getTDone() != null) {
+                addToCounter(BOOMERANG_PERCEIVED, name, data.getTDone());
+            }
+            if (data.getLatency() != null) {
+                addToCounter(BOOMERANG_LATENCY, name, data.getLatency());
+            }
+            if (data.getBandwidth() != null) {
+                addToCounter(BOOMERANG_BANDWITH, name, data.getBandwidth());
+            }
+        }
+
+        // answer
+        resp.setStatus(200);
+        resp.getWriter().write("");
+    }
+
+    private void addToCounter(final Role role, final String name, final long value) throws MalformedURLException {
+        final Counter.Key key = new Counter.Key(role, name);
+        if (collectorCounterStore != null) { // TODO: better locking? or better window aggregation with bg thread
+            final Counter counter = collectorCounterStore.getOrCreateCounter(key, BOOMERANG_MARKER);
+            synchronized (counter) { // counter is cached so we can sync it
+                final OptimizedStatistics computationalStats = new OptimizedStatistics(
+                    counter.getHits(), counter.getSum(), counter.getMin(), counter.getMax(),
+                    counter.getMean(), counter.getSecondMoment()
+                ).addValue(value);
+
+                final M2AwareStatisticalSummary stats = new M2AwareStatisticalSummary(
+                    computationalStats.getMean(), computationalStats.getVariance(), computationalStats.getN(),
+                    computationalStats.getMax(), computationalStats.getMin(), computationalStats.getSum(),
+                    computationalStats.getSecondMoment()
+                );
+                collectorCounterStore.update(key, BOOMERANG_MARKER, stats, -1);
+            }
+        } else {
+            final Counter counter = counterStore.getOrCreateCounter(key);
+            counterStore.addToCounter(counter, key.getRole().getUnit().convert(value, Unit.Time.MILLISECOND));
+        }
+    }
+
+    private Map<String, String> toMap(final String query) {
+        if (query == null || query.isEmpty()) {
+            return Collections.emptyMap();
+        }
+
+        final Map<String, String> params = new HashMap<String, String>(15);
+        for (final String kv : query.split("&")) {
+            final String trimmed = kv.trim();
+            if (trimmed.isEmpty()) {
+                continue;
+            }
+
+            final String[] split = trimmed.split("=");
+            if (split.length == 2) {
+                try {
+                    params.put(split[0], URLDecoder.decode(split[1], encoding));
+                } catch (final UnsupportedEncodingException e) {
+                    params.put(split[0], split[1]);
+                }
+            } // else no value
+        }
+        return params;
+    }
+}

Added: incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/parser/BoomerangData.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/parser/BoomerangData.java?rev=1566522&view=auto
==============================================================================
--- incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/parser/BoomerangData.java (added)
+++ incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/parser/BoomerangData.java Mon Feb 10 06:53:14 2014
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sirona.boomerang.parser;
+
+import java.util.Map;
+
+public class BoomerangData {
+    private final Map<String, String> rawValues;
+    private String url = null;
+    private String version = null;
+    private Long tDone = null;
+    private Long bandwidth = null;
+    private Long latency = null;
+
+    public BoomerangData(final Map<String, String> rawValues) {
+        this.rawValues = rawValues;
+    }
+
+    public boolean validate() {
+        return url != null && !url.isEmpty();
+    }
+
+    public void setUrl(final String url) {
+        this.url = url;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setVersion(final String version) {
+        this.version = version;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public Long getTDone() {
+        return tDone;
+    }
+
+    public void setTDone(final Long tDone) {
+        this.tDone = tDone;
+    }
+
+    public void setBandwidth(final Long bandwidth) {
+        this.bandwidth = bandwidth;
+    }
+
+    public Long getBandwidth() {
+        return bandwidth;
+    }
+
+    public void setLatency(final Long latency) {
+        this.latency = latency;
+    }
+
+    public Long getLatency() {
+        return latency;
+    }
+}

Added: incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/parser/QueryParser.java
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/parser/QueryParser.java?rev=1566522&view=auto
==============================================================================
--- incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/parser/QueryParser.java (added)
+++ incubator/sirona/trunk/server/boomerang/src/main/java/org/apache/sirona/boomerang/parser/QueryParser.java Mon Feb 10 06:53:14 2014
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sirona.boomerang.parser;
+
+import java.util.Map;
+
+public class QueryParser {
+    public static BoomerangData parse(final Map<String, String> params) {
+        final BoomerangData data = new BoomerangData(params);
+
+        final String url = params.get("u");
+        if (url != null) {
+            data.setUrl(url);
+        }
+        // not yet used but depending on next releases it could
+        final String version = params.get("v");
+        if (version != null) {
+            data.setVersion(version);
+        }
+
+        final String tDone = params.get("t_done");
+        if (tDone != null && !tDone.isEmpty()) {
+            data.setTDone(parseLong(tDone));
+        }
+
+        final String bw = params.get("bw");
+        if (bw != null && !bw.isEmpty()) {
+            data.setBandwidth(parseLong(bw));
+        }
+
+        final String lat = params.get("lat");
+        if (lat != null && !lat.isEmpty()) {
+            data.setLatency(parseLong(lat));
+        }
+
+        return data;
+    }
+
+    private static Long parseLong(final String value) {
+        try {
+            return Long.parseLong(value);
+        } catch (final NumberFormatException nbe) {
+            return null;
+        }
+    }
+
+    private QueryParser() {
+        // no-op
+    }
+}

Modified: incubator/sirona/trunk/server/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sirona/trunk/server/pom.xml?rev=1566522&r1=1566521&r2=1566522&view=diff
==============================================================================
--- incubator/sirona/trunk/server/pom.xml (original)
+++ incubator/sirona/trunk/server/pom.xml Mon Feb 10 06:53:14 2014
@@ -32,5 +32,6 @@
     <module>collector</module>
     <module>reporting</module>
     <module>store</module>
+    <module>boomerang</module>
   </modules>
 </project>