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>