Compare commits

...
60 Commits
Author SHA1 Message Date
Dave Marion 2fdfed7554 0.0.3 release 2016-10-27 13:40:22 -04:00
Brian Loss e90340be09 fixes #107 - Fix bad regex in timely Grafana app 2016-10-27 13:21:17 -04:00
Ivan Bella 9770dce1cd re #106: Significant performance enhancement where valid answers are preserved in a separate list avoiding excessive passes through the entire set of captured metrics on each round. 2016-10-26 15:48:56 -04:00
Ivan Bella 8f98199a37 re #101: Removing the first element from the list after computing. Also added some efficiencies in the metrics comparator and the setTopKeyValue method. 2016-10-26 14:52:20 -04:00
Dave Marion 425616d536 Update location of log4j configuration 2016-10-26 13:28:55 -04:00
Dave Marion 158ee4fd55 re #102 - sparse time series optimization 2016-10-26 12:04:25 -04:00
Dave Marion 89e8fd7ebd closes #103 - return rate of zero if no time has elapsed between data points 2016-10-24 11:05:44 -04:00
Dave Marion cb5794491a closes #102 - changes to handle sparse time series. New test. 2016-10-21 16:09:25 -04:00
Dave Marion 8b4f0d5764 closes #99 - re-implemented SlidingWindowFilter and added:
1. Multiple Time Series
2. Ability to handle when a time series drops off
3. Ability to handle when a time series appears
4. New tests
2016-10-20 15:42:52 -04:00
Dave Marion c90b86c4c9 re #91 : remove code added in dd30d54e (#77) because of downsample iterator changes. 2016-10-19 16:47:33 -04:00
Dave Marion f104d02dc6 closes #91 :
1. The DownsampleIterator no longer creates an array of downsamples upon initialization. Instead, it creates downsample buckets as needed.
2. The DownsampleIterator no longer interpolates for missing values.
3. The DownsampleIterator no longer converts counters to rates, this is done with a different iterator. The counter reset value and counter max value are no longer used.
2016-10-14 12:22:03 -04:00
Dave Marion ac85ad1aa7 closes #94 - Fixed rate calculations so that the result is divided by the time difference. Added test for non-constant sample time (added jitter). 2016-10-14 11:53:05 -04:00
Dave Marion 21f3c20a5f closes #93 : pushed common pom things up to the parent pom, removed System.out's in a test, created common module. 2016-10-12 16:07:42 -04:00
klucar b43d877035 final docker fixes, removed unused aggregator from query template 2016-10-10 20:06:22 -04:00
Jim Klucar 8f46ee052c Merge pull request #85 from trucemop/docker
Docker example update
2016-10-10 19:54:07 -04:00
klucar 6cda9c4a60 fixes so templated queries use regex instead of globs 2016-10-10 19:50:05 -04:00
Dave Marion cfc3e491d6 fixes #86 - removed rpm profile from server pom 2016-09-29 13:21:42 -04:00
Dave Marion 23668b294f fixes #84 - calculating rate before downsample iterator using the sliding window iterator 2016-09-29 13:07:41 -04:00
Dave Marion beceb678ea Merge branch 'master' of github.com:NationalSecurityAgency/timely 2016-09-28 14:07:46 -04:00
Dave Marion 4257e28233 Fixup warnings 2016-09-28 14:07:24 -04:00
Brian Loss fb007c170e Ensure server is shut down if there is an error during server.run in order to fix #89. 2016-09-28 14:01:56 -04:00
Dave Marion cabeb2c0d7 re #90 - fix script 2016-09-28 14:00:04 -04:00
Brian Loss e4a2b011a4 Merge branch 'master' of github.com:NationalSecurityAgency/timely 2016-09-28 13:19:13 -04:00
Brian Loss 8f6dfd1644 Update log4j2 configuration to fix #90
moved log4j2.xml to log4j2-spring.xml (recommended by spring boot)
	moved log4j2 config files to conf dir (since it's on the classpath)
	don't specify log4j config file location for spring boot apps (timely server/standalone) since the file is found on the classpath
2016-09-28 13:17:16 -04:00
Dave Marion 33fb3dc857 re #84 - added sliding window iterator which takes a filter. Tests added for moving average and rate calculations 2016-09-28 11:37:15 -04:00
John Highcock 186edeb0f2 Remove extra standalone_test.json 2016-09-26 11:26:39 -04:00
John Highcock a034223376 Install bouncycastle via epel-release 2016-09-25 11:58:51 -04:00
John Highcock 9c75c75aa5 Addressing some of the comments. JAVA_HOME specific version, script quotes, env: prefix for pass. 2016-09-25 09:36:10 -04:00
John Highcock c8646a8d59 Star the timely dashboard 2016-09-24 23:00:18 -04:00
John Highcock b28cb4451b Merge branch 'master' into docker 2016-09-24 21:57:24 -04:00
John Highcock a4b9a1034c Add the grafana bits so that datasource and dashboard are setup. 2016-09-24 21:51:45 -04:00
John Highcock 12e64316eb Can now just run 'docker-compose up' 2016-09-24 19:41:29 -04:00
John Highcock a2389435d4 Working again. 2016-09-24 17:29:17 -04:00
Jim Klucar 6a0455b1cd Merge pull request #82 from klucar/newapi
Timely Client jar and Test speed improvements
2016-09-23 10:19:09 -04:00
Jim Klucar 7abc9e68e4 Standardized on Jackson Json annotations over the XmlElement style
Updated test cases to use compact Json serialization format.
2016-09-22 10:28:34 -04:00
Jim Klucar e45dcb0450 standardized to all Jackson annotations 2016-09-22 09:57:34 -04:00
Jim Klucar a8ce05000e Fixed Metric::equals to ignore ordering of List.
Flattened Json format.
2016-09-22 09:51:57 -04:00
Jim Klucar 747d3e7ad1 removed TODO reminder comment that was fixed 2016-09-19 11:24:05 -04:00
Jim Klucar fcf0ec0b87 removed commented out plugin 2016-09-19 11:22:12 -04:00
Jim Klucar 976c6da07c fixed check to ensure correct number of tags of each type was found 2016-09-19 11:21:44 -04:00
Jim Klucar ed96a0a8e8 made shutdown quiet period configurable. 5 seconds by default 2016-09-19 10:17:48 -04:00
Jim Klucar d5c3bbbcc5 removed old commented out code 2016-09-19 09:22:39 -04:00
John Highcock ec1ac9af73 Remove TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 exception in Dockerfile. 2016-09-16 15:55:45 -04:00
Jim Klucar 2a2d11d01b Made sleep times configurable from the TestConfiguration. 2016-09-16 13:02:24 -04:00
Jim Klucar 14eba0fb93 added exclusion for Server.shutdown. Findbugs doesn't see Collection.forEach as a use and calls the collection of Futures useless 2016-09-16 13:01:57 -04:00
Jim Klucar 418afe8f87 fast server shutdown 2016-09-16 12:31:31 -04:00
Jim Klucar 2b39ec3ab5 Tests now re-use Mini Accumulo Cluster instance 2016-09-16 12:31:31 -04:00
Jim Klucar 2ff895b147 changed core module to client module 2016-09-16 12:31:14 -04:00
Jim Klucar 16a6223c48 Extracted former api classes into a client jar. 2016-09-15 15:40:08 -04:00
Jim Klucar e928ac3746 breaking out models into core module 2016-09-08 14:51:39 -04:00
Dave Marion 8f5d54ebd4 fixes #79 - disable console output from utility class 2016-09-07 10:13:11 -04:00
Dave Marion 123f63972e fixes #78 - changes for Timely to work with Accumulo 1.7 and 1.8 2016-09-06 11:43:42 -04:00
Dave Marion dd30d54ed9 closes #77 - return error when there are too many downsample buckets 2016-09-01 15:47:32 -04:00
Dave Marion d37bf1c824 #16 - per metric ageoff (#76)
* fixes #16, added age off map to configuration to specify ageoff, in days, per metric. "default" accepted. Remove all ageoff iterators on server startup and re-setup with current configuration
2016-08-31 15:48:41 -04:00
Dave Marion 6cd4a8bd67 closes #65: Added support for sending metrics in String and binary form to UDP socket 2016-08-30 15:51:20 -04:00
Dave Marion 1fa71e0c6a fixes #66 - allow metric data to be sent to Timely TCP port in Google Flatbuffers encoded binary form (#74) 2016-08-30 10:06:49 -04:00
Dave Marion c5efeb5be9 closes #69, removed double lexicoder for metric value encoding 2016-08-29 15:07:22 -04:00
Brian Loss 2c8fa5da44 fixes #71: Pass IPs stored in configuration through to tcp, query, and websocket servers. 2016-08-26 14:52:03 -04:00
Dave Marion 9cbc94eb58 turn formatter off so that whitespace changes are not lost 2016-08-26 12:26:07 -04:00
Jim Klucar 4ce4482764 changed whitespace for clarity 2016-08-25 14:29:54 -04:00
131 changed files with 4685 additions and 2319 deletions

No files matched your search

+2
View File
@@ -5,3 +5,5 @@ target/
.idea/
*.iml
logs/
server/pki/
+2
View File
@@ -0,0 +1,2 @@
This product includes Google Flatbuffers (https://google.github.io/flatbuffers/)
Copyright 2014 Google Inc. All rights reserved.
+1
View File
@@ -0,0 +1 @@
/target/
+120
View File
@@ -0,0 +1,120 @@
<?xml version="1.0"?>
<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">
<modelVersion>4.0.0</modelVersion>
<artifactId>timely-client</artifactId>
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.3</version>
</parent>
<dependencies>
<dependency>
<groupId>timely</groupId>
<artifactId>timely-common</artifactId>
<version>${parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>${version.findbugs-maven}</version>
<configuration>
<effort>Max</effort>
<threshold>Medium</threshold>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${version.jacoco}</version>
<reportSets>
<reportSet>
<id>JaCoCo Unit Test Coverage</id>
<configuration>
<dataFile>${project.build.directory}/coverage/jacoco-ut.exec</dataFile>
</configuration>
<reports>
<report>report</report>
</reports>
</reportSet>
<reportSet>
<id>JaCoCo Integration Test Coverage</id>
<configuration>
<dataFile>${project.build.directory}/coverage/jacoco-it.exec</dataFile>
</configuration>
<reports>
<report>report-integration</report>
</reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
</project>
@@ -0,0 +1,182 @@
package timely.model;
import com.fasterxml.jackson.annotation.*;
import timely.model.parse.TagParser;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* A Metric consists of a metric name, tags, and a Value
*
* Json has been flattened to reduce overhead. Example:
* {"name":"m1","timestamp":1,"measure":1.0,"tags":[{"k1":"v1"}]}
*
*/
@JsonRootName("metric")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "name" })
public class Metric {
private String name;
private List<Tag> tags;
private Value value;
public Metric() {
tags = new ArrayList<>();
value = new Value();
}
public Metric(Metric other) {
this();
this.name = other.getName();
this.tags.addAll(other.getTags());
this.value = new Value(other.getValue());
}
public Metric(String name, long timestamp, double measure) {
this();
this.name = name;
this.value.setTimestamp(timestamp);
this.value.setMeasure(measure);
}
public Metric(String name, long timestamp, double measure, List<Tag> tags) {
this(name, timestamp, measure);
this.setTags(tags);
}
public Metric(String name, List<Tag> tags) {
this();
this.name = name;
this.setTags(tags);
}
public static Builder newBuilder() {
return new Builder();
}
@JsonGetter("name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonGetter("tags")
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags.addAll(tags);
}
public void addTag(Tag tag) {
tags.add(new Tag(tag));
}
@JsonUnwrapped
public Value getValue() {
return value;
}
public void setValue(Value value) {
this.value = value;
}
@Override
public String toString() {
Collections.sort(tags);
return "Metric{" + "name='" + name + '\'' + ", tags=" + tags + ", value=" + value + '}';
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Metric metric = (Metric) o;
if (name != null ? !name.equals(metric.name) : metric.name != null)
return false;
if (tags != null) {
if (tags.size() != metric.tags.size()) {
return false;
} else if (!tags.containsAll(metric.tags)) {
return false;
}
}
return value != null ? value.equals(metric.value) : metric.value == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (tags != null ? tags.hashCode() : 0);
result = 31 * result + (value != null ? value.hashCode() : 0);
return result;
}
/**
* Simple Builder for Metric. Note: cannot re-use a builder after build is
* called.
*/
public static class Builder {
Metric metric;
private Builder() {
metric = new Metric();
}
private static TagParser parser = new TagParser();
public Builder tag(Tag tag) {
metric.addTag(tag);
return this;
}
public Builder tags(List<Tag> tags) {
metric.setTags(tags);
return this;
}
public Builder tag(String key, String value) {
metric.addTag(new Tag(key, value));
return this;
}
public Builder tag(String rawTag) {
metric.addTag(parser.parse(rawTag));
return this;
}
public Builder name(String name) {
metric.setName(name);
return this;
}
public Builder value(Value value) {
metric.setValue(value);
return this;
}
public Builder value(long timestamp, double measure) {
metric.setValue(new Value(timestamp, measure));
return this;
}
public Metric build() {
return this.metric;
}
}
}
+111
View File
@@ -0,0 +1,111 @@
package timely.model;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonRootName;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import timely.model.parse.TagParser;
import java.io.Serializable;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Tag consists of key value pair
*/
@JsonRootName("tag")
public class Tag implements Comparable<Tag>, Serializable {
private static final long serialVersionUID = 1L;
private static final Joiner equalJoiner = Joiner.on("=");
private static final TagParser tagParser = new TagParser();
private String key;
private String value;
public Tag() {
}
public Tag(Tag other) {
this.setKey(other.getKey());
this.setValue(other.getValue());
}
public Tag(String tag) {
this(tagParser.parse(tag));
}
public Tag(String key, String value) {
Preconditions.checkNotNull(key);
Preconditions.checkNotNull(value);
this.setKey(key);
this.setValue(value);
}
@JsonAnyGetter
public Map<String, String> get() {
return Stream.of(this).collect(Collectors.toMap(Tag::getKey, Tag::getValue));
}
@JsonAnySetter
public void set(String key, String value) {
this.key = key;
this.value = value;
}
@JsonIgnore
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
@JsonIgnore
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
/**
* Joins key and value into key=value
*
* @return
*/
public String join() {
return equalJoiner.join(key, value);
}
@Override
public String toString() {
return "Tag{" + equalJoiner.join(this.getKey(), this.getValue()) + "}";
}
@Override
public int hashCode() {
return this.toString().hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (null == o || getClass() != o.getClass())
return false;
return this.toString().equals(o.toString());
}
@Override
public int compareTo(Tag other) {
return this.toString().compareTo(other.toString());
}
}
@@ -0,0 +1,93 @@
package timely.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Objects;
import java.io.Serializable;
import java.util.Comparator;
import java.util.concurrent.TimeUnit;
/**
* Value consists of a long timestamp and a double measurement
*/
public class Value implements Comparator<Value>, Serializable {
private static final long serialVersionUID = 1L;
private Long timestamp;
private Double measure;
public Value() {
}
public Value(Value other) {
this.setTimestamp(other.getTimestamp());
this.setMeasure(other.getMeasure());
}
@JsonCreator
public Value(@JsonProperty("timestamp") Long timestamp, @JsonProperty("measure") Double measure) {
this.setTimestamp(timestamp);
this.setMeasure(measure);
}
@JsonProperty("timestamp")
public Long getTimestamp() {
return timestamp;
}
public void setTimestamp(final Long timestamp) {
this.setTimestamp(timestamp, TimeUnit.MILLISECONDS);
}
public void setTimestamp(final Long timestamp, TimeUnit timeUnit) {
this.timestamp = timeUnit.toMillis(timestamp);
}
@JsonProperty("measure")
public Double getMeasure() {
return measure;
}
public void setMeasure(final Double measure) {
this.measure = measure;
}
@Override
/**
* Compares timestamps for sorting.
*
* Note: this comparator imposes orderings that are inconsistent with equals
*
*/
public int compare(Value v1, Value v2) {
if (v1.getTimestamp().equals(v2.getTimestamp()))
return 0;
return v1.getTimestamp() > v2.getTimestamp() ? 1 : -1;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (null == o || getClass() != o.getClass())
return false;
if (getTimestamp() != null ? !getTimestamp().equals(((Value) o).getTimestamp())
: ((Value) o).getTimestamp() != null)
return false;
return !(getMeasure() != null ? !getMeasure().equals(((Value) o).getMeasure())
: ((Value) o).getMeasure() != null);
}
@Override
public int hashCode() {
return Objects.hashCode(timestamp, measure);
}
@Override
public String toString() {
return "Value{" + "timestamp=" + timestamp + ", measure=" + measure + "}";
}
}
@@ -0,0 +1,30 @@
package timely.model.parse;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import timely.model.Metric;
import java.util.List;
public class MetricParser implements Parser<Metric> {
private static final Splitter spaceSplitter = Splitter.on(" ").omitEmptyStrings().trimResults();
@Override
public Metric parse(String line) {
// put specification
//
// put <metricName> <timestamp> <value> <tagK=tagV> <tagK=tagV> ...
List<String> parts = spaceSplitter.splitToList(line);
Preconditions.checkPositionIndex(3, parts.size());
Metric.Builder builder = Metric.newBuilder();
// index 0 is put
builder.name(parts.get(1)); // metric name
builder.value(Long.parseLong(parts.get(2)), Double.parseDouble(parts.get(3)));
parts.stream().skip(4).forEach(builder::tag);
return builder.build();
}
}
@@ -0,0 +1,7 @@
package timely.model.parse;
@FunctionalInterface
public interface Parser<T> {
T parse(String t);
}
@@ -0,0 +1,23 @@
package timely.model.parse;
import com.google.common.base.Splitter;
import timely.model.Tag;
import java.util.ArrayList;
import java.util.List;
/**
* Parses tag1=val1,tag2=val2,tag3=val3 into a {@code List} of {@code Tag}
*/
public class TagListParser implements Parser<List<Tag>> {
private static final Splitter commaSplitter = Splitter.on(",").omitEmptyStrings();
private static final TagParser tagParser = new TagParser();
@Override
public List<Tag> parse(String t) {
ArrayList<Tag> tags = new ArrayList<>();
commaSplitter.splitToList(t).forEach(p -> tags.add(tagParser.parse(p)));
return tags;
}
}
@@ -0,0 +1,20 @@
package timely.model.parse;
import com.google.common.base.Splitter;
import timely.model.Tag;
import java.util.List;
public class TagParser implements Parser<Tag> {
private static final Splitter equalSplitter = Splitter.on("=").trimResults();
@Override
public Tag parse(String t) {
List<String> parts = equalSplitter.splitToList(t);
if (parts.size() != 2) {
throw new IllegalArgumentException("Invalid tag format: " + t);
}
return new Tag(parts.get(0), parts.get(1));
}
}
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
</FindBugsFilter>
@@ -0,0 +1,63 @@
package timely.model;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import java.io.IOException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
*
*
*
*/
public class MetricTest {
@Test
public void testEquals() {
Metric m1 = Metric.newBuilder().name("m1").tag("t1", "v1").tag("t2", "v2").value(1, 0.0).build();
Metric m2 = Metric.newBuilder().name("m1").tag("t2", "v2").tag("t1", "v1").value(1, 0.0).build();
assertTrue(m1.equals(m2));
assertTrue(m2.equals(m1));
Metric m3 = Metric.newBuilder().name("m1").tag("t1", "v1").value(1, 0.0).build();
assertFalse(m1.equals(m3));
Metric m4 = Metric.newBuilder().name("m4").tag("t2", "v2").tag("t1", "v1").value(1, 0.0).build();
assertFalse(m1.equals(m4));
Metric m5 = Metric.newBuilder().name("m1").tag("t3", "v3").tag("t2", "v2").tag("t1", "v1").value(1, 0.0)
.build();
assertFalse(m1.equals(m5));
Metric m6 = Metric.newBuilder().name("m1").tag("t2", "v2").tag("t1", "v1").value(2, 0.0).build();
assertFalse(m1.equals(m6));
Metric m7 = Metric.newBuilder().name("m1").tag("t2", "v2").tag("t1", "v1").value(1, 1.0).build();
assertFalse(m1.equals(m7));
}
@Test
public void testJson() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String expectedJson = "{\"name\":\"m1\",\"timestamp\":1,\"measure\":1.0,\"tags\":[{\"k1\":\"v1\"}]}";
Metric m1 = Metric.newBuilder().name("m1").tag("k1", "v1").value(1, 1.0).build();
Metric expectedMetric = mapper.readValue(expectedJson, Metric.class);
assertTrue(m1.equals(expectedMetric));
expectedJson = "{\"name\":\"m1\",\"tags\":[{\"k1\":\"v1\"}],\"timestamp\":5,\"measure\":5.0}";
expectedMetric = mapper.readValue(expectedJson, Metric.class);
assertEquals((long) expectedMetric.getValue().getTimestamp(), 5L);
assertEquals(expectedMetric.getValue().getMeasure(), 5.0D, 0.0);
}
}
+1 -26
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.3-SNAPSHOT</version>
<version>0.0.3</version>
</parent>
<artifactId>collectd-nsq-plugin</artifactId>
<dependencies>
@@ -35,19 +35,6 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<configuration>
<effort>Max</effort>
<threshold>Medium</threshold>
<xmlOutput>true</xmlOutput>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<phase>prepare-package</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -72,18 +59,6 @@
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<configuration>
<configFile>${project.parent.basedir}/eclipse/Eclipse-Formatter.xml</configFile>
<lineEnding>LF</lineEnding>
<overrideConfigCompilerVersion>true</overrideConfigCompilerVersion>
</configuration>
<executions>
<execution>
<goals>
<goal>format</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
</FindBugsFilter>
+5 -30
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.3-SNAPSHOT</version>
<version>0.0.3</version>
</parent>
<artifactId>collectd-plugin-parent</artifactId>
<dependencies>
@@ -42,43 +42,18 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<configuration>
<effort>Max</effort>
<threshold>Medium</threshold>
<xmlOutput>true</xmlOutput>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<phase>prepare-package</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludedGroups>timely.test.IntegrationTest</excludedGroups>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<configuration>
<configFile>${project.parent.basedir}/eclipse/Eclipse-Formatter.xml</configFile>
<lineEnding>LF</lineEnding>
<overrideConfigCompilerVersion>true</overrideConfigCompilerVersion>
</configuration>
<executions>
<execution>
<goals>
<goal>format</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
</FindBugsFilter>
+5 -31
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.3-SNAPSHOT</version>
<version>0.0.3</version>
</parent>
<artifactId>collectd-timely-plugin</artifactId>
<dependencies>
@@ -52,20 +52,6 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<configuration>
<effort>Max</effort>
<threshold>Medium</threshold>
<xmlOutput>true</xmlOutput>
<excludeFilterFile>src/main/resources/findbugs-excludes.xml</excludeFilterFile>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<phase>prepare-package</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -90,26 +76,14 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludedGroups>timely.test.IntegrationTest</excludedGroups>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<configuration>
<configFile>${project.parent.basedir}/eclipse/Eclipse-Formatter.xml</configFile>
<lineEnding>LF</lineEnding>
<overrideConfigCompilerVersion>true</overrideConfigCompilerVersion>
</configuration>
<executions>
<execution>
<goals>
<goal>format</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
+16
View File
@@ -0,0 +1,16 @@
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.3</version>
</parent>
<artifactId>timely-common</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.3-SNAPSHOT</version>
<version>0.0.3</version>
</parent>
<build>
<plugins>
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../../src/components/auths.js"],"names":[],"mappings":"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","file":"auths.js","sourcesContent":["import _ from 'lodash';\n\nexport class AuthsCtrl {\n\n constructor(backendSrv, $rootScope, $timeout){\n this.$rootScope = $rootScope;\n this.$timeout = $timeout;\n this.backendSrv = backendSrv;\n }\n\n login(datasource){\n this.fetching = {};\n this.fetching.done = false;\n this.fetching.show = true;\n this.fetching.status = 'warning';\n this.fetching.title = 'Fetching auths...';\n\n //this.$rootScope.appEvent('alert-success', ['Authorization Cookie Received', '']);\n //this.$rootScope.appEvent('alert-error', ['Authorization Failed', '']);\n //this.$rootScope.appEvent('alert-warning', ['Fetching Authorizations', '']);\n\n var uri = this._getURI(datasource.jsonData);\n\n if(datasource.jsonData.basicAuths){\n if( this.basicAuthUser && this.basicAuthPassword){\n var authBlob = {username: this.basicAuthUser, password: this.basicAuthPassword};\n this.doPostLogin(uri, authBlob);\n } else {\n this.$rootScope.appEvent('alert-warning', [datasource.name, 'requires User/Password']);\n this.fetching.status = 'warning';\n this.fetching.title = 'User/Password required';\n\n return;\n }\n } else {\n this.doGetLogin(uri);\n }\n\n }\n\n doPostLogin(uri, authBlob){\n this.doXHR('POST', uri, authBlob);\n }\n\n doGetLogin(uri){\n this.doXHR('GET', uri)\n }\n\n doXHR(verb, uri, data){\n if( !data){\n data = \"\";\n }\n var r = new XMLHttpRequest();\n r.open(verb, uri, true);\n r.withCredentials = true;\n r.setRequestHeader('Content-Type', 'application/json');\n r.onreadystatechange = function () {\n this.handleLoginResult(r);\n }.bind(this);\n r.send(JSON.stringify(data));\n }\n\n handleLoginResult(response){\n // wait for readyState to be '4 => done'\n if (response.readyState != 4) return;\n\n this.fetching.done = true;\n\n switch(response.status){\n case 200:\n var cookie = (document.cookie.match(/^(?:.*;)?TSESSIONID=([^;]+)(?:.*)?$/)||[,null])[1]\n console.log(cookie);\n console.log(document.cookie);\n \n this.fetching.status = 'success';\n this.fetching.title = 'Login successful';\n this.$rootScope.appEvent('alert-success', ['Success', '']);\n break;\n default:\n this.fetching.status = 'warning';\n this.fetching.title = response.statusText;\n this.$rootScope.appEvent('alert-warning', [response.status+': '+response.statusText,'']);\n break;\n }\n\n if (r.readyState != 4 || r.status != 200) return;\n alert(\"Success: \" + r.Line truncated
{"version":3,"sources":["../../src/components/auths.js"],"names":["_","AuthsCtrl","backendSrv","$rootScope","$timeout","datasource","fetching","done","show","status","title","uri","_getURI","jsonData","basicAuths","basicAuthUser","basicAuthPassword","authBlob","username","password","doPostLogin","appEvent","name","doGetLogin","doXHR","verb","data","r","XMLHttpRequest","open","withCredentials","setRequestHeader","onreadystatechange","handleLoginResult","bind","send","JSON","stringify","response","readyState","cookie","document","match","console","log","statusText","alert","getResponseHeader","timelyHost","httpsPort"],"mappings":"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","file":"auths.js","sourcesContent":["import _ from 'lodash';\n\nexport class AuthsCtrl {\n\n constructor(backendSrv, $rootScope, $timeout){\n this.$rootScope = $rootScope;\n this.$timeout = $timeout;\n this.backendSrv = backendSrv;\n }\n\n login(datasource){\n this.fetching = {};\n this.fetching.done = false;\n this.fetching.show = true;\n this.fetching.status = 'warning';\n this.fetching.title = 'Fetching auths...';\n\n //this.$rootScope.appEvent('alert-success', ['Authorization Cookie Received', '']);\n //this.$rootScope.appEvent('alert-error', ['Authorization Failed', '']);\n //this.$rootScope.appEvent('alert-warning', ['Fetching Authorizations', '']);\n\n var uri = this._getURI(datasource.jsonData);\n\n if(datasource.jsonData.basicAuths){\n if( this.basicAuthUser && this.basicAuthPassword){\n var authBlob = {username: this.basicAuthUser, password: this.basicAuthPassword};\n this.doPostLogin(uri, authBlob);\n } else {\n this.$rootScope.appEvent('alert-warning', [datasource.name, 'requires User/Password']);\n this.fetching.status = 'warning';\n this.fetching.title = 'User/Password required';\n\n return;\n }\n } else {\n this.doGetLogin(uri);\n }\n\n }\n\n doPostLogin(uri, authBlob){\n this.doXHR('POST', uri, authBlob);\n }\n\n doGetLogin(uri){\n this.doXHR('GET', uri)\n }\n\n doXHR(verb, uri, data){\n if( !data){\n data = \"\";\n }\n var r = new XMLHttpRequest();\n r.open(verb, uri, true);\n r.withCredentials = true;\n r.setRequestHeader('Content-Type', 'application/json');\n r.onreadystatechange = function () {\n this.handleLoginResult(r);\n }.bind(this);\n r.send(JSON.stringify(data));\n }\n\n handleLoginResult(response){\n // wait for readyState to be '4 => done'\n if (response.readyState != 4) return;\n\n this.fetching.done = true;\n\n switcLine truncated
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../../src/components/authspage.js"],"names":[],"mappings":";;;;;;;;;;;;;;;AACO,O;;AACC,gB,gBAAA,U;AAAY,e,gBAAA,S;;AACZ,e,oCAAA,S;;;;;;;;;;;;;;;;;;;;;+BAEK,a;AAEX,+BAAY,UAAZ,EAAwB,aAAxB,EAAsC;AAAA;;AACpC,eAAK,aAAL,GAAqB,aAArB;AACA,eAAK,WAAL,GAAmB,KAAK,oBAAL,EAAnB;AACA,qBAAW,UAAX,CAAsB,WAAtB,EAAmC,SAAnC;AACD;;;;iDAEqB;AACpB,gBAAI,aAAa,KAAK,aAAL,CAAmB,MAAnB,EAAjB;;AAEA,gBAAI,UAAU,EAAE,GAAF,CAAM,UAAN,EAAkB,UAAS,KAAT,EAAgB,GAAhB,EAAqB,GAArB,EAAyB;AACvD,kBAAI,MAAM,EAAV;AACA,kBAAI,IAAJ,GAAW,EAAX;AACA,kBAAI,IAAJ,CAAS,IAAT,GAAgB,IAAI,GAAJ,EAAS,IAAT,CAAc,IAA9B;AACA,kBAAI,IAAJ,CAAS,EAAT,GAAc,IAAI,GAAJ,EAAS,IAAT,CAAc,EAA5B;AACA,kBAAI,IAAJ,GAAW,GAAX;AACA,kBAAI,QAAJ,GAAe,IAAI,GAAJ,EAAS,QAAxB;AACA,qBAAO,GAAP;AACD,aARa,CAAd;AASA,mBAAO,EAAE,MAAF,CAAS,OAAT,EAAkB,UAAS,CAAT,EAAW;AAClC,qBAAQ,EAAE,IAAF,CAAO,IAAP,KAAgB,YAAhB,IAAgC,EAAE,IAAF,CAAO,EAAP,KAAc,mBAAtD;AACD,aAFM,CAAP;AAGD;;;;;;;;AAGH,oBAAc,WAAd,GAA4B,uBAA5B","file":"authspage.js","sourcesContent":["\nimport _ from 'lodash';\nimport {coreModule, appEvents} from 'app/core/core';\nimport {AuthsCtrl} from 'plugins/timely-app/components/auths';\n\nexport class AuthsPageCtrl {\n\n constructor(backendSrv, datasourceSrv){\n this.datasourceSrv = datasourceSrv;\n this.datasources = this.getTimelyDatasources();\n coreModule.controller('AuthsCtrl', AuthsCtrl);\n }\n\n getTimelyDatasources(){\n var allSources = this.datasourceSrv.getAll();\n\n var sources = _.map(allSources, function(value, key, col){\n var ret = {};\n ret.meta = {};\n ret.meta.type = col[key].meta.type;\n ret.meta.id = col[key].meta.id;\n ret.name = key;\n ret.jsonData = col[key].jsonData;\n return ret;\n });\n return _.filter(sources, function(d){\n return (d.meta.type === 'datasource' && d.meta.id === 'timely-datasource');\n });\n }\n\n}\nAuthsPageCtrl.templateUrl = 'components/auths.html';\n"]}
{"version":3,"sources":["../../src/components/authspage.js"],"names":["_","coreModule","appEvents","AuthsCtrl","AuthsPageCtrl","backendSrv","datasourceSrv","datasources","getTimelyDatasources","controller","allSources","getAll","sources","map","value","key","col","ret","meta","type","id","name","jsonData","filter","d","templateUrl"],"mappings":";;;;;;;;;;;;;;;AACOA,O;;AACCC,gB,gBAAAA,U;AAAYC,e,gBAAAA,S;;AACZC,e,oCAAAA,S;;;;;;;;;;;;;;;;;;;;;+BAEKC,a;AAEX,+BAAYC,UAAZ,EAAwBC,aAAxB,EAAsC;AAAA;;AACpC,eAAKA,aAAL,GAAqBA,aAArB;AACA,eAAKC,WAAL,GAAmB,KAAKC,oBAAL,EAAnB;AACAP,qBAAWQ,UAAX,CAAsB,WAAtB,EAAmCN,SAAnC;AACD;;;;iDAEqB;AACpB,gBAAIO,aAAa,KAAKJ,aAAL,CAAmBK,MAAnB,EAAjB;;AAEA,gBAAIC,UAAUZ,EAAEa,GAAF,CAAMH,UAAN,EAAkB,UAASI,KAAT,EAAgBC,GAAhB,EAAqBC,GAArB,EAAyB;AACvD,kBAAIC,MAAM,EAAV;AACAA,kBAAIC,IAAJ,GAAW,EAAX;AACAD,kBAAIC,IAAJ,CAASC,IAAT,GAAgBH,IAAID,GAAJ,EAASG,IAAT,CAAcC,IAA9B;AACAF,kBAAIC,IAAJ,CAASE,EAAT,GAAcJ,IAAID,GAAJ,EAASG,IAAT,CAAcE,EAA5B;AACAH,kBAAII,IAAJ,GAAWN,GAAX;AACAE,kBAAIK,QAAJ,GAAeN,IAAID,GAAJ,EAASO,QAAxB;AACA,qBAAOL,GAAP;AACD,aARa,CAAd;AASA,mBAAOjB,EAAEuB,MAAF,CAASX,OAAT,EAAkB,UAASY,CAAT,EAAW;AAClC,qBAAQA,EAAEN,IAAF,CAAOC,IAAP,KAAgB,YAAhB,IAAgCK,EAAEN,IAAF,CAAOE,EAAP,KAAc,mBAAtD;AACD,aAFM,CAAP;AAGD;;;;;;;;AAGHhB,oBAAcqB,WAAd,GAA4B,uBAA5B","file":"authspage.js","sourcesContent":["\nimport _ from 'lodash';\nimport {coreModule, appEvents} from 'app/core/core';\nimport {AuthsCtrl} from 'plugins/timely-app/components/auths';\n\nexport class AuthsPageCtrl {\n\n constructor(backendSrv, datasourceSrv){\n this.datasourceSrv = datasourceSrv;\n this.datasources = this.getTimelyDatasources();\n coreModule.controller('AuthsCtrl', AuthsCtrl);\n }\n\n getTimelyDatasources(){\n var allSources = this.datasourceSrv.getAll();\n\n var sources = _.map(allSources, function(value, key, col){\n var ret = {};\n ret.meta = {};\n ret.meta.type = col[key].meta.type;\n ret.meta.id = col[key].meta.id;\n ret.name = key;\n ret.jsonData = col[key].jsonData;\n return ret;\n });\n return _.filter(sources, function(d){\n return (d.meta.type === 'datasource' && d.meta.id === 'timely-datasource');\n });\n }\n\n}\nAuthsPageCtrl.templateUrl = 'components/auths.html';\n"]}
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../../src/components/config.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;qCACa,mB,GAEX,+BAAc;AAAA;AAEb,O;;;;AAGH,0BAAoB,WAApB,GAAkC,wBAAlC","file":"config.js","sourcesContent":["\nexport class TimelyAppConfigCtrl {\n\n constructor() {\n \n }\n\n}\nTimelyAppConfigCtrl.templateUrl = 'components/config.html';\n"]}
{"version":3,"sources":["../../src/components/config.js"],"names":["TimelyAppConfigCtrl","templateUrl"],"mappings":";;;;;;;;;;;;;;;;qCACaA,mB,GAEX,+BAAc;AAAA;AAEb,O;;;;AAGHA,0BAAoBC,WAApB,GAAkC,wBAAlC","file":"config.js","sourcesContent":["\nexport class TimelyAppConfigCtrl {\n\n constructor() {\n \n }\n\n}\nTimelyAppConfigCtrl.templateUrl = 'components/config.html';\n"]}
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../../src/components/metrics.js"],"names":[],"mappings":";;;;;;;;;;;;;;;AACO,O;;AACC,mB,wCAAA,a;;;;;;;;;;;;;;;;;;;;;iCAEK,e;AAEX,iCAAY,UAAZ,EAAwB,aAAxB,EAAsC;AAAA;;AACpC,eAAK,aAAL,GAAqB,KAArB;AACA,eAAK,UAAL,GAAkB,UAAlB;AACA,cAAI,MAAM,IAAI,aAAJ,CAAkB,UAAlB,EAA8B,aAA9B,CAAV;AACA,eAAK,WAAL,GAAmB,IAAI,oBAAJ,EAAnB;AACA,cAAI,KAAK,WAAL,CAAiB,MAAjB,GAA0B,CAA9B,EAAgC;AAC9B,iBAAK,MAAL,GAAc,KAAK,WAAL,CAAiB,CAAjB,CAAd;AACA,iBAAK,gBAAL;AACD;AACF;;;;6CAEiB;AAAA;;AAChB,iBAAK,aAAL;AACA,gBAAI,MAAM,KAAK,OAAL,CAAa,KAAK,MAAL,CAAY,QAAzB,CAAV;AACA,iBAAK,UAAL,CAAgB,OAAhB,CACE,EAAE,QAAQ,KAAV;AACE,mBAAK,GADP;AAEE,+BAAiB,IAFnB;AAGE,sBAAQ,EAHV,EADF,EAKE,IALF,CAME,oBAAY;AACV,oBAAK,OAAL,GAAe,MAAK,iBAAL,CAAuB,SAAS,OAAhC,CAAf;AACA,oBAAK,aAAL,GAAqB,IAArB;AACD,aATH;AAUD;;;0CAEc;AACb,iBAAK,OAAL,GAAe,EAAf;AACD;;;4CAEiB,O,EAAQ;AACxB,gBAAI,MAAM,EAAV;AACA,cAAE,IAAF,CAAO,OAAP,EAAgB,UAAS,KAAT,EAAgB,GAAhB,EAAoB;AAClC,kBAAI,SAAS,EAAb;AACA,qBAAO,MAAP,GAAgB,MAAM,MAAtB;AACA,qBAAO,IAAP,GAAc,EAAd;AACA,gBAAE,GAAF,CAAM,MAAM,IAAZ,EAAkB,UAAS,GAAT,EAAc,GAAd,EAAkB;AAC1C;AACA;AACA;AACA;AACQ,oBAAI,OAAO,EAAE,SAAF,CAAY,OAAO,IAAnB,EAAyB,EAAC,QAAQ,IAAI,GAAb,EAAzB,CAAX;AACA,oBAAI,OAAJ;AACA,oBAAI,QAAQ,CAAC,CAAb,EAAgB;AACd,4BAAU,EAAC,MAAM,EAAP,EAAW,QAAQ,EAAnB,EAAV;AACD,iBAFD,MAEO;AACL,4BAAU,OAAO,IAAP,CAAY,IAAZ,CAAV;AACD;AACD,wBAAQ,MAAR,CAAe,IAAf,CAAoB,IAAI,KAAxB;AACA,wBAAQ,MAAR,GAAiB,EAAE,MAAF,CAAS,EAAE,IAAF,CAAO,QAAQ,MAAf,CAAT,CAAjB;AACA,wBAAQ,IAAR,GAAe,IAAI,GAAnB;AACA,oBAAI,OAAO,CAAC,CAAZ,EAAe;AACb,yBAAO,IAAP,CAAY,IAAZ,IAAoB,OAApB;AACD,iBAFD,MAEO;AACL,yBAAO,IAAP,CAAY,IAAZ,CAAiB,OAAjB;AACD;AACF,eApBiB,CAoBhB,IApBgB,CAoBX,MApBW,CAAlB;AAqBA,qBAAO,IAAP,GAAc,EAAE,MAAF,CAAS,OAAO,IAAhB,EAAsB,MAAtB,CAAd;AACA,kBAAI,IAAJ,CAAS,MAAT;AACD,aA3Be,CA2Bd,IA3Bc,CA2BT,GA3BS,CAAhB;;AA6BA,mBAAO,EAAE,MAAF,CAAS,GAAT,EAAc,QAAd,CAAP;AACD;;;kCAEO,Q,EAAS;AACf,mBAAO,aAAW,SAAS,UAApB,GAA+B,GAA/B,GAAmC,SAAS,SAA5C,GAAsD,cAA7D;AACD;;;;;;;;AAGH,sBAAgB,WAAhB,GAA8B,yBAA9B","file":"metrics.js","sourcesContent":["\nimport _ from 'lodash';\nimport {AuthsPageCtrl} from 'plugins/timely-app/components/authspage';\n\nexport class MetricsPageCtrl {\n\n constructor(backendSrv, datasourceSrv){\n this.hasDatasource = false;\n this.backendSrv = backendSrv;\n var apc = new AuthsPageCtrl(backendSrv, datasourceSrv);\n this.datasources = apc.getTimelyDatasources();\n if( this.datasources.length > 0){\n this.source = this.datasources[0];\n this.updateDatasource();\n }\n }\n\n updateDatasource(){\n this._clearMetrics();\n var uri = this._getURI(this.source.jsonData);\n this.backendSrv.request(\n { method: 'GET',\n url: uri,\n withCredentials: true,\n params: \"\" }\n ).then(\n response => {\n this.metrics = this._transformMetrics(response.metrics);\n this.hasDatasource = true;\n });\n }\n\n _clearMetrics(){\n this.metrics = [];\n }\n\n _transformMetrics(metrics){\n var ret = [];\n _.each(metrics, function(value, idx){\n var metric = {};\n metric.metric = value.metric;\n metric.tags = [];\n _.map(value.tags, function(tag, key){\n// result || (result = {});\n// result['name'] = tag.key;\n// result['values'] || (result['values'] = []);\n// result['values'].push(tag.value);\n var gIdx = _.findIndex(metric.tags, {'name': tag.key});\n var grouped;\n if( gIdx == -1 ){\n grouped = {name: '', values: []};\n } else {\n grouped = metric.tags[gIdx];\n }\n grouped.values.push(tag.value);\n grouped.values = _.sortBy(_.uniq(grouped.values))\n grouped.name = tag.key;\n if( gIdx > -1 ){\n metric.tags[gIdx] = grouped;\n } else {\n metric.tags.push(grouped);\n }\n }.bind(metric));\n metric.tags = _.sortBy(metric.tags, 'name')\n ret.push(metric);\n }.bind(ret));\n\n return _.sortBy(ret, 'metric');\n }\n\n _getURI(jsonData){\n return 'https://'+jsonData.timelyHost+':'+jsonData.httpsPort+'/api/metrics'\n }\n\n}\nMetricsPageCtrl.templateUrl = 'components/metrics.html';\n"]}
{"version":3,"sources":["../../src/components/metrics.js"],"names":["_","AuthsPageCtrl","MetricsPageCtrl","backendSrv","datasourceSrv","hasDatasource","apc","datasources","getTimelyDatasources","length","source","updateDatasource","_clearMetrics","uri","_getURI","jsonData","request","method","url","withCredentials","params","then","metrics","_transformMetrics","response","ret","each","value","idx","metric","tags","map","tag","key","gIdx","findIndex","grouped","name","values","push","sortBy","uniq","bind","timelyHost","httpsPort","templateUrl"],"mappings":"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","file":"metrics.js","sourcesContent":["\nimport _ from 'lodash';\nimport {AuthsPageCtrl} from 'plugins/timely-app/components/authspage';\n\nexport class MetricsPageCtrl {\n\n constructor(backendSrv, datasourceSrv){\n this.hasDatasource = false;\n this.backendSrv = backendSrv;\n var apc = new AuthsPageCtrl(backendSrv, datasourceSrv);\n this.datasources = apc.getTimelyDatasources();\n if( this.datasources.length > 0){\n this.source = this.datasources[0];\n this.updateDatasource();\n }\n }\n\n updateDatasource(){\n this._clearMetrics();\n var uri = this._getURI(this.source.jsonData);\n this.backendSrv.request(\n { method: 'GET',\n url: uri,\n withCredentials: true,\n params: \"\" }\n ).then(\n response => {\n this.metrics = this._transformMetrics(response.metrics);\n this.hasDatasource = true;\n });\n }\n\n _clearMetrics(){\n this.metrics = [];\n }\n\n _transformMetrics(metrics){\n var ret = [];\n _.each(metrics, function(value, idx){\n var metric = {};\n metric.metric = value.metric;\n metric.tags = [];\n _.map(value.tags, function(tag, key){\n// result || (result = {});\n// result['name'] = tag.key;\n// result['values'] || (result['values'] = []);\n// result['values'].push(tag.value);\n var gIdx = _.findIndex(metric.tags, {'name': tag.key});\n var grouped;\n if( gIdx == -1 ){\n grouped = {name: '', values: []};\n } else {\n grouped = metric.tags[gIdx];\n }\n grouped.values.push(tag.value);\n grouped.values = _.sortBy(_.uniq(grouped.values))\n grouped.name = tag.key;\n if( gIdx > -1 ){\n metric.tags[gIdx] = grouped;\n } else {\n metric.tags.push(grouped);\n }\n }.bind(metric));\n metric.tags = _.sortBy(metric.tags, 'name')\n ret.push(metric);\n }.bind(ret));\n\n return _.sortBy(ret, 'metric');\n }\n\n _getURI(jsonData){\n return 'https://'+jsonData.timelyHost+':'+jsonData.httpsPort+'/api/metrics'\n }\n\n}\nMetricsPageCtrl.templateUrl = 'components/metrics.html';\n"]}
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../../src/datasource/config.js"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAO,O;;;sCAGM,oB,GAEX,gCAAc;AAAA;;AACZ,aAAK,OAAL,CAAa,QAAb,GAAwB,KAAK,OAAL,CAAa,QAAb,IAAyB,EAAjD;AACA,aAAK,OAAL,CAAa,MAAb,GAAsB,QAAtB;AACA,aAAK,OAAL,CAAa,SAAb,GAAyB,KAAzB;AACA,aAAK,OAAL,CAAa,eAAb,GAA+B,IAA/B;AACA,aAAK,OAAL,CAAa,WAAb,GAA2B,WAA3B;AACD,O;;;;AAEH,2BAAqB,WAArB,GAAmC,iCAAnC","file":"config.js","sourcesContent":["import _ from 'lodash';\n\n\nexport class DatasourceConfigCtrl {\n\n constructor() {\n this.current.jsonData = this.current.jsonData || {};\n this.current.access = 'direct';\n this.current.basicAuth = false;\n this.current.withCredentials = true;\n this.current.suggestHost = 'localhost';\n }\n}\nDatasourceConfigCtrl.templateUrl = 'datasource/partials/config.html';\n"]}
{"version":3,"sources":["../../src/datasource/config.js"],"names":["_","DatasourceConfigCtrl","current","jsonData","access","basicAuth","withCredentials","suggestHost","templateUrl"],"mappings":";;;;;;;;;;;;;;;AAAOA,O;;;sCAGMC,oB,GAEX,gCAAc;AAAA;;AACZ,aAAKC,OAAL,CAAaC,QAAb,GAAwB,KAAKD,OAAL,CAAaC,QAAb,IAAyB,EAAjD;AACA,aAAKD,OAAL,CAAaE,MAAb,GAAsB,QAAtB;AACA,aAAKF,OAAL,CAAaG,SAAb,GAAyB,KAAzB;AACA,aAAKH,OAAL,CAAaI,eAAb,GAA+B,IAA/B;AACA,aAAKJ,OAAL,CAAaK,WAAb,GAA2B,WAA3B;AACD,O;;;;AAEHN,2BAAqBO,WAArB,GAAmC,iCAAnC","file":"config.js","sourcesContent":["import _ from 'lodash';\n\n\nexport class DatasourceConfigCtrl {\n\n constructor() {\n this.current.jsonData = this.current.jsonData || {};\n this.current.access = 'direct';\n this.current.basicAuth = false;\n this.current.withCredentials = true;\n this.current.suggestHost = 'localhost';\n }\n}\nDatasourceConfigCtrl.templateUrl = 'datasource/partials/config.html';\n"]}
@@ -179,7 +179,7 @@
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {
"host": ".*"
@@ -265,7 +265,7 @@
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {
"rack": ".*"
@@ -351,7 +351,7 @@
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {}
}
+1 -1
View File
@@ -289,7 +289,7 @@ System.register(['lodash', 'angular', '../../../app/core/utils/datemath'], funct
return key.trim();
});
var key = keysArray[0];
var keysQuery = key + "=*";
var keysQuery = key + "=.*";
if (keysArray.length > 1) {
keysQuery += "," + keysArray.splice(1).join(",");
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../../src/datasource/datasource.js"],"names":[],"mappings":"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 truncated
{"version":3,"sources":["../../src/datasource/datasource.js"],"names":["_","angular","dateMath","TimelyDatasource","instanceSettings","$q","backendSrv","templateSrv","contextSrv","type","name","jsonData","httpsPort","timelyHost","wsPort","basicAuths","url","_makeHttpsUrl","withCredentials","basicAuth","supportMetrics","tagKeys","aggregatorsPromise","filterTypesPromise","options","start","convertToTSDBTime","rangeRaw","from","end","to","qs","each","targets","target","metric","push","convertTargetToQuery","bind","queries","compact","isEmpty","d","defer","resolve","data","promise","groupByTags","query","filters","length","val","tagk","tags","key","performTimeSeriesQuery","then","response","metricToTargetMapping","mapMetricsToTargets","result","map","metricData","index","_saveTagKeys","transformMetricData","datasourceRequest","method","status","message","title","eventList","aggregator","annotation","results","annotationObject","annotations","isGlobal","globalAnnotations","event","description","time","Math","floor","startTime","text","notes","when","interpolated","replace","err","reject","responseTransform","value","metrics_regex","tag_names_regex","tag_values_regex","tag_names_suggest_regex","tag_values_suggest_regex","metrics_query","match","_performSuggestQuery","tag_names_query","_performMetricKeyLookup","tag_values_query","_performMetricKeyValueLookup","tag_names_suggest_query","tag_values_suggest_query","msResolution","reqBody","showQuery","_addCredentialOptions","headers","Object","keys","aggregateTags","tag","_get","q","max","keysArray","split","trim","keysQuery","splice","join","m","limit","tagvs","r","indexOf","tagks","tagv","relativeUrl","params","isArray","sort","md","metricLabel","createMetricLabel","dps","v","k","datapoints","alias","scopedVars","clone","label","tagData","pairs","has","hide","shouldComputeRate","rate","rateOptions","counter","isCounter","counterMax","parseInt","counterResetValue","resetValue","disableDownsampling","interval","downsampleInterval","parseFloat","downsample","downsampleAggregator","downsampleFillPolicy","copy","filter_key","filter","tag_key","metrics","interpolatedTagValue","findIndex","all","tagV","tagK","date","roundUp","parse","valueOf"],"mappings":"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 truncated
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../../src/datasource/module.js"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAQ,sB,eAAA,gB;;AACA,qB,eAAA,e;;AACA,0B,WAAA,oB;;;sCAEF,0B;;;;AACN,iCAA2B,WAA3B,GAAyC,oCAAzC;;4BAGE,gB;;2BACA,e;;4BACA,oB;;sCACA,0B","file":"module.js","sourcesContent":["import {TimelyDatasource} from './datasource';\nimport {TimelyQueryCtrl} from './query_ctrl';\nimport {DatasourceConfigCtrl} from './config';\n\nclass TimelyAnnotationsQueryCtrl {}\nTimelyAnnotationsQueryCtrl.templateUrl = 'components/annotations.editor.html';\n\nexport {\n TimelyDatasource as Datasource,\n TimelyQueryCtrl as QueryCtrl,\n DatasourceConfigCtrl as ConfigCtrl,\n TimelyAnnotationsQueryCtrl as AnnotationsQueryCtrl\n};\n"]}
{"version":3,"sources":["../../src/datasource/module.js"],"names":["TimelyDatasource","TimelyQueryCtrl","DatasourceConfigCtrl","TimelyAnnotationsQueryCtrl","templateUrl"],"mappings":";;;;;;;;;;;;;;;AAAQA,sB,eAAAA,gB;;AACAC,qB,eAAAA,e;;AACAC,0B,WAAAA,oB;;;sCAEFC,0B;;;;AACNA,iCAA2BC,WAA3B,GAAyC,oCAAzC;;4BAGEJ,gB;;2BACAC,e;;4BACAC,oB;;sCACAC,0B","file":"module.js","sourcesContent":["import {TimelyDatasource} from './datasource';\nimport {TimelyQueryCtrl} from './query_ctrl';\nimport {DatasourceConfigCtrl} from './config';\n\nclass TimelyAnnotationsQueryCtrl {}\nTimelyAnnotationsQueryCtrl.templateUrl = 'components/annotations.editor.html';\n\nexport {\n TimelyDatasource as Datasource,\n TimelyQueryCtrl as QueryCtrl,\n DatasourceConfigCtrl as ConfigCtrl,\n TimelyAnnotationsQueryCtrl as AnnotationsQueryCtrl\n};\n"]}
+1 -1
View File
@@ -66,7 +66,7 @@ System.register(['lodash', 'app/plugins/sdk'], function (_export, _context) {
function TimelyQueryCtrl($scope, $injector, uiSegmentSrv) {
_classCallCheck(this, TimelyQueryCtrl);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(TimelyQueryCtrl).call(this, $scope, $injector));
var _this = _possibleConstructorReturn(this, (TimelyQueryCtrl.__proto__ || Object.getPrototypeOf(TimelyQueryCtrl)).call(this, $scope, $injector));
_this.errors = _this.validateTarget();
_this.aggregators = ['avg', 'sum', 'min', 'max', 'dev', 'zimsum', 'mimmin', 'mimmax'];
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../../src/datasource/query_ctrl.js"],"names":[],"mappings":"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","file":"query_ctrl.js","sourcesContent":["import _ from 'lodash';\nimport {QueryCtrl} from 'app/plugins/sdk';\n\nexport class TimelyQueryCtrl extends QueryCtrl {\n\n constructor($scope, $injector, uiSegmentSrv) {\n super($scope, $injector);\n\n this.errors = this.validateTarget();\n this.aggregators = ['avg', 'sum', 'min', 'max', 'dev', 'zimsum', 'mimmin', 'mimmax'];\n Line truncated
{"version":3,"sources":["../../src/datasource/query_ctrl.js"],"names":["_","QueryCtrl","TimelyQueryCtrl","$scope","$injector","uiSegmentSrv","errors","validateTarget","aggregators","fillPolicies","filterTypes","target","aggregator","downsampleAggregator","downsampleFillPolicy","datasource","getAggregators","then","aggs","length","getFilterTypes","suggestMetrics","query","callback","metricFindQuery","getTextValues","suggestTagKeys","metric","suggestTagValues","refresh","metricFindResult","map","value","text","filters","tags","addTagMode","currentTagKey","currentTagValue","targetBlur","key","removeTag","addTag","size","addFilterMode","currentFilterType","currentFilterGroupBy","currentFilter","type","tagk","currentFilterKey","filter","currentFilterValue","groupBy","push","index","splice","fil","removeFilter","addFilter","errs","shouldDownsample","downsampleInterval","kbn","describe_interval","err","message","has","templateUrl"],"mappings":"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 truncated
+1 -1
View File
@@ -1 +1 @@
{"version":3,"sources":["../src/module.js"],"names":[],"mappings":";;;;;;;;AAAQ,yB,qBAAA,mB;;AACA,qB,sBAAA,e;;AACA,mB,wBAAA,a;;;4BAGN,mB;;iCACA,e;;+BACA,a","file":"module.js","sourcesContent":["import {TimelyAppConfigCtrl} from './components/config';\nimport {MetricsPageCtrl} from './components/metrics';\nimport {AuthsPageCtrl} from './components/authspage';\n\nexport {\n TimelyAppConfigCtrl as ConfigCtrl,\n MetricsPageCtrl,\n AuthsPageCtrl\n};\n"]}
{"version":3,"sources":["../src/module.js"],"names":["TimelyAppConfigCtrl","MetricsPageCtrl","AuthsPageCtrl"],"mappings":";;;;;;;;AAAQA,yB,qBAAAA,mB;;AACAC,qB,sBAAAA,e;;AACAC,mB,wBAAAA,a;;;4BAGNF,mB;;iCACAC,e;;+BACAC,a","file":"module.js","sourcesContent":["import {TimelyAppConfigCtrl} from './components/config';\nimport {MetricsPageCtrl} from './components/metrics';\nimport {AuthsPageCtrl} from './components/authspage';\n\nexport {\n TimelyAppConfigCtrl as ConfigCtrl,\n MetricsPageCtrl,\n AuthsPageCtrl\n};\n"]}
+1 -1
View File
@@ -23,7 +23,7 @@
{"name": "Project site", "url": "https://github.com/NationalSecurityAgency/timely"},
{"name": "License & Terms", "url": "https://raw.githubusercontent.com/NationalSecurityAgency/timely/master/LICENSE"}
],
"version": "0.0.2",
"version": "0.0.3",
"updated": "2016-06-30"
},
+1 -1
View File
@@ -23,7 +23,7 @@
{"name": "Project site", "url": "https://github.com/NationalSecurityAgency/timely"},
{"name": "License & Terms", "url": "https://raw.githubusercontent.com/NationalSecurityAgency/timely/master/LICENSE"}
],
"version": "0.0.2",
"version": "0.0.3",
"updated": "2016-06-30"
},
@@ -179,7 +179,7 @@
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {
"host": ".*"
@@ -265,7 +265,7 @@
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {
"rack": ".*"
@@ -351,7 +351,7 @@
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"metric": "sys.cpu.user",
"refId": "A",
"tags": {}
}
@@ -241,7 +241,7 @@ export class TimelyDatasource {
return key.trim();
});
var key = keysArray[0];
var keysQuery = key + "=*";
var keysQuery = key + "=.*";
if (keysArray.length > 1) {
keysQuery += "," + keysArray.splice(1).join(",");
+103 -5
View File
@@ -3,10 +3,10 @@
<modelVersion>4.0.0</modelVersion>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.3-SNAPSHOT</version>
<version>0.0.3</version>
<packaging>pom</packaging>
<name>Timely</name>
<description>A secure time series database based on Apache Accumulo</description>
<description>A secure and scalable time series database based on Apache Accumulo</description>
<licenses>
<license>
<name>Apache License, Version 2.1</name>
@@ -23,6 +23,8 @@
<url>https://github.com/NationalSecurityAgency/timely/issues</url>
</issueManagement>
<modules>
<module>common</module>
<module>client</module>
<module>server</module>
<module>collectd-timely-plugin</module>
<module>collectd-nsq-plugin</module>
@@ -43,26 +45,32 @@
<version.caffeine>2.2.0</version.caffeine>
<version.collectd>5.5.1</version.collectd>
<version.commons-configuration>1.10</version.commons-configuration>
<version.commons-collections4>4.1</version.commons-collections4>
<version.commons-lang3>3.1</version.commons-lang3>
<version.disruptor>3.3.2</version.disruptor>
<version.fast-classpath-scanner>1.10.4</version.fast-classpath-scanner>
<version.google-flatbuffers>1.4.0</version.google-flatbuffers>
<version.guava>19.0</version.guava>
<version.hadoop>2.6.2</version.hadoop>
<version.httpcomponents>4.5.1</version.httpcomponents>
<version.jackson>2.6.1</version.jackson>
<version.javassist>3.20.0-GA</version.javassist>
<version.jcip-annotations>1.0</version.jcip-annotations>
<version.jsoup>1.9.2</version.jsoup>
<version.junit>4.12</version.junit>
<version.log4j>2.5</version.log4j>
<version.netty>4.0.38.Final</version.netty>
<version.netty-tcnative>1.1.33.Fork18</version.netty-tcnative>
<version.powermock>1.6.4</version.powermock>
<version.slf4j>1.7.12</version.slf4j>
<version.spring-boot>1.4.0.RELEASE</version.spring-boot>
<!-- plugin versions -->
<version.eclipse-lifecycle>1.0.0</version.eclipse-lifecycle>
<version.findbugs-maven>3.0.3</version.findbugs-maven>
<version.formatter>0.5.2</version.formatter>
<version.jacoco>0.7.6.201602180812</version.jacoco>
<version.maven-assembly>2.6</version.maven-assembly>
<version.maven-build-helper>1.12</version.maven-build-helper>
<version.maven-compiler>3.3</version.maven-compiler>
<version.maven-dependency>2.10</version.maven-dependency>
<version.maven-jar>3.0.1</version.maven-jar>
@@ -105,6 +113,16 @@
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${version.caffeine}</version>
</dependency>
<dependency>
<groupId>com.google.flatbuffers</groupId>
<artifactId>flatbuffers-java</artifactId>
<version>${version.google-flatbuffers}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${version.guava}</version>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
@@ -150,6 +168,11 @@
<version>${version.jcip-annotations}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${version.commons-collections4}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
@@ -261,7 +284,12 @@
<version>${version.javassist}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${version.jsoup}</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-easymock-release-full</artifactId>
<version>${version.powermock}</version>
@@ -277,7 +305,7 @@
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.4.0.RELEASE</version>
<version>${version.spring-boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -290,7 +318,19 @@
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>${version.formatter}</version>
</plugin>
<configuration>
<configFile>${project.parent.basedir}/eclipse/Eclipse-Formatter.xml</configFile>
<lineEnding>LF</lineEnding>
<overrideConfigCompilerVersion>true</overrideConfigCompilerVersion>
</configuration>
<executions>
<execution>
<goals>
<goal>format</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
@@ -314,11 +354,34 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${version.maven-surefire}</version>
<configuration>
<argLine>${failsafeArgLine} -Djava.library.path=${project.build.directory}/native/META-INF/native/libnetty-tcnative.so -Dzookeeper.sasl.client=false</argLine>
<includes>
<include>**/*.java</include>
</includes>
<groups>timely.test.IntegrationTest</groups>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${version.maven-jar}</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -329,6 +392,16 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.maven-surefire}</version>
<configuration>
<argLine>${sureFireArgLine} -Djava.library.path=${project.build.directory}/native/META-INF/native/libnetty-tcnative.so -Dzookeeper.sasl.client=false</argLine>
<excludedGroups>timely.test.IntegrationTest</excludedGroups>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>${version.maven-build-helper}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
@@ -338,6 +411,7 @@
<effort>Max</effort>
<threshold>Medium</threshold>
<xmlOutput>true</xmlOutput>
<excludeFilterFile>src/main/resources/findbugs-excludes.xml</excludeFilterFile>
</configuration>
<executions>
<execution>
@@ -352,6 +426,30 @@
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${version.jacoco}</version>
<executions>
<execution>
<id>jacoco-prepare-ut</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<phase>process-test-classes</phase>
<configuration>
<destFile>${project.build.directory}/coverage/jacoco-ut.exec</destFile>
<propertyName>sureFireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>jacoco-prepare-it</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<destFile>${project.build.directory}/coverage/jacoco-it.exec</destFile>
<propertyName>failsafeArgLine</propertyName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
+11 -5
View File
@@ -5,14 +5,20 @@ MAINTAINER Jim Klucar "[email protected]"
VOLUME /timely-server-src
VOLUME /timely
RUN yum -y update && \
yum -y install java-1.8.0-openjdk-devel maven openssl apr && \
mkdir -p /timely/bin
ENV JAVA_HOME /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.91-1.b14.el7_2.x86_64
RUN yum -y update && \
yum -y install java-1.8.0-openjdk-devel maven openssl apr wget epel-release && \
yum -y install bouncycastle && \
yum clean all && \
mkdir -p /timely/bin && \
echo "security.provider.9=org.bouncycastle.jce.provider.BouncyCastleProvider" >> /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/security/java.security && \
ln -sf /usr/share/java/bcprov.jar /usr/lib/jvm/java-1.8.0-openjdk/jre/lib/ext/bcprov.jar
ENV JAVA_HOME /usr/lib/jvm/java-1.8.0-openjdk
EXPOSE 9804 54321 54322
ENV TIMELY_VERSION 0.0.3-SNAPSHOT
#CMD /timely/bin/timely-standalone.sh
+6
View File
@@ -0,0 +1,6 @@
#!/bin/sh
export SRC_DIR=/timely-server-src
export TIMELY_DIR=/timely
@@ -1,6 +1,11 @@
#!/bin/sh
WORKING="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "${WORKING}/deploy-env.sh"
set -e
/timely-server-src/bin/docker/deploy-timely-build.sh
/timely/bin/timely-standalone.sh
"${SRC_DIR}/bin/docker/genCerts.sh"
"${SRC_DIR}/bin/docker/deploy-timely-build.sh"
"${TIMELY_DIR}/bin/timely-standalone.sh"
+6 -2
View File
@@ -1,5 +1,9 @@
#!/bin/sh
#!/bin/bash
WORKING="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "${WORKING}/deploy-env.sh"
set -e
tar xzf /timely-server-src/target/timely-server-$TIMELY_VERSION-dist.tar.gz -C /timely --strip-components 1
tar xzf "${SRC_DIR}/target/timely-server-$TIMELY_VERSION-dist.tar.gz" -C "${TIMELY_DIR}" --strip-components 1
+51 -12
View File
@@ -1,19 +1,58 @@
#!/bin/sh
#!/bin/bash
/timely-server-src/bin/docker/deploy-timely-build.sh
WORKING="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "${WORKING}/deploy-env.sh"
"${SRC_DIR}/bin/docker/deploy-timely-build.sh"
/timely-server-src/bin/docker/wait-for-it.sh timely:54322 -t 45
"${SRC_DIR}/bin/docker/wait-for-it.sh" timely:54322 -t 45
# create datasource in grafana
#curl -X POST -u admin:admin -H "Content-Type: application/json" -d \
#'{"name":"Timely","type":"opentsdb","url":"https://timely:54322","access":"proxy","jsonData":{"tsdbVersion":1,"tsdbResolution":1}}' \
#http://grafana:3000/api/datasources
# insert the dashboard
#curl -X POST -u admin:admin -H "Content-Type: application/json" \
#-d @/timely-server-src/bin/docker/standalone_test.json \
#http://grafana:3000/api/dashboards/db
# enable app
curl -k -H "Content-Type: application/json" -d \
'{
"enabled":true,
"pinned":true
}' \
https://admin:admin@grafana:3000/api/plugins/timely-app/settings
/timely/bin/insert-test-data.sh
# create data source
curl -k -H "Content-Type: application/json" -d \
'{
"name":"Timely",
"type":"timely-datasource",
"Access":"direct",
"jsonData":
{
"timelyHost":"localhost",
"httpsPort":"54322",
"wsPort":"54323",
"basicAuths":true
}
}' \
https://admin:admin@grafana:3000/api/datasources
# import the dashboard
curl -k -H "Content-Type: application/json" -d \
'{
"pluginId":"timely-datasource",
"path":"dashboards/standalone_test.json",
"overwrite":false,
"inputs":[{
"name":"*",
"type":"datasource",
"pluginId":"timely-datasource",
"value":"Timely"
}]
}' \
https://admin:admin@grafana:3000/api/dashboards/import
# star the dashboard
curl -k -X POST https://admin:admin@grafana:3000/api/user/stars/dashboard/1
"${TIMELY_DIR}/bin/insert-test-data.sh"
+56
View File
@@ -0,0 +1,56 @@
#!/bin/bash
WORKING="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "${WORKING}/deploy-env.sh"
PASSPREFIX=pass:
KEYPASS=password
export PASSWORD=$PASSPREFIX$KEYPASS
if [ ! -d "${SRC_DIR}/pki" ]; then
mkdir "${SRC_DIR}/pki"
pushd "${SRC_DIR}/pki"
#Create a private key
openssl genrsa -aes256 -out CA.key -passout env:PASSWORD 4096
#Create a certificate request using the private key
openssl req -x509 -new -key CA.key -sha256 -nodes -days 365 -out CA.pem -passin env:PASSWORD -subj '/C=US/ST=Confusion/L=Here/O=Timely/OU=Server/CN=localhost/emailAddress=noreply@localhost/subjectAltName=DNS.1=127.0.0.1'
#Create your SSL material for Grafana
#Create the private key for the Grafana server
openssl genrsa -out grafana.key -passout env:PASSWORD 4096
#Generate a certificate signing request (CSR) with our Grafana private key
openssl req -new -key grafana.key -sha256 -nodes -out grafana.csr -subj '/C=US/ST=Confusion/L=Here/O=Timely/OU=Server/CN=localhost/emailAddress=noreply@localhost/subjectAltName=DNS.1=127.0.0.1'
#Use the CSR and the CA to create a certificate for the server (a reply to the CSR)
openssl x509 -req -in grafana.csr -CA CA.pem -CAkey CA.key -CAcreateserial -out grafana.crt -days 365 -passin env:PASSWORD
#Create your SSL material for Timely
#Create the private key for the Timely server
openssl genrsa -out timely.key 4096
#Generate a certificate signing request (CSR) with our Timely private key
openssl req -new -key timely.key -sha256 -nodes -subj '/C=US/ST=Confusion/L=Here/O=Timely/OU=Server/CN=localhost/emailAddress=noreply@localhost/subjectAltName=DNS.1=127.0.0.1' > timely.csr
#Use the CSR and the CA to create a certificate for the server (a reply to the CSR)
openssl x509 -req -in timely.csr -CA CA.pem -CAkey CA.key -CAcreateserial -out timely.crt -days 365 -passin env:PASSWORD
#Convert the private key to pkcs#8 format
openssl pkcs8 -topk8 -inform PEM -outform PEM -in timely.key -out timely-pkcs8.key -passout env:PASSWORD
popd
fi
+2 -2
View File
@@ -55,8 +55,8 @@ http_port = 3000
;enable_gzip = false
# https certs & key file
cert_file = /etc/grafana/pki/timely-cert.pem
cert_key = /etc/grafana/pki/timely-key.pem
cert_file = /timely-server-src/pki/grafana.crt
cert_key = /timely-server-src/pki/grafana.key
#################################### Database ####################################
[database]
-429
View File
@@ -1,429 +0,0 @@
{"dashboard":
{
"id": null,
"title": "StandaloneTest",
"originalTitle": "StandaloneTest",
"tags": [],
"style": "dark",
"timezone": "browser",
"editable": true,
"hideControls": false,
"sharedCrosshair": false,
"rows": [
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "Timely",
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)",
"thresholdLine": false
},
"id": 1,
"legend": {
"alignAsTable": true,
"avg": false,
"current": true,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"total": true,
"values": true
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"disableDownsampling": false,
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"downsampleInterval": "",
"errors": {},
"isCounter": false,
"metric": "timely.metrics.received",
"refId": "A",
"shouldComputeRate": false
},
{
"aggregator": "sum",
"disableDownsampling": false,
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"downsampleInterval": "",
"errors": {},
"metric": "timely.keys.meta.inserted",
"refId": "B"
},
{
"aggregator": "sum",
"disableDownsampling": false,
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"downsampleInterval": "",
"errors": {},
"metric": "timely.keys.metric.inserted",
"refId": "C"
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Status",
"tooltip": {
"msResolution": true,
"shared": false,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": "Keys",
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"logBase": 1,
"max": null,
"min": null,
"show": false
}
]
}
],
"title": "Row"
},
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "Timely",
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 2,
"isNew": true,
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "max",
"alias": "$tag_host",
"currentTagKey": "",
"currentTagValue": "",
"disableDownsampling": false,
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CPU User by Host",
"tooltip": {
"msResolution": false,
"shared": true,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "Timely",
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 3,
"isNew": true,
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "max",
"alias": "$tag_rack",
"currentTagKey": "",
"currentTagValue": "",
"disableDownsampling": false,
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"refId": "A",
"tags": {
"rack": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CPU User by Rack",
"tooltip": {
"msResolution": false,
"shared": true,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "Timely",
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 4,
"isNew": true,
"legend": {
"alignAsTable": true,
"avg": false,
"current": false,
"max": false,
"min": false,
"rightSide": true,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 1,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "max",
"alias": "",
"currentTagKey": "",
"currentTagValue": "",
"disableDownsampling": false,
"downsampleAggregator": "max",
"downsampleFillPolicy": "none",
"downsampleInterval": "1s",
"metric": "sys.cpu0.user",
"refId": "A",
"tags": {}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Cumulative CPU",
"tooltip": {
"msResolution": false,
"shared": true,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"title": "New row"
}
],
"time": {
"from": "now-15m",
"to": "now"
},
"timepicker": {
"now": true,
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"templating": {
"list": []
},
"annotations": {
"list": []
},
"refresh": "5s",
"schemaVersion": 12,
"version": 1,
"links": []
}
}
+3 -1
View File
@@ -12,7 +12,9 @@ CONF_DIR="${BASE_DIR}/conf"
LIB_DIR="${BASE_DIR}/lib"
export CLASSPATH="${CONF_DIR}:${LIB_DIR}/*"
JVM_ARGS="-Xmx256m -Xms128m -Dlog4j.configurationFile=${THIS_DIR}/log4j2.xml"
JVM_ARGS="-Xmx256m -Xms128m"
JVM_ARGS="${JVM_ARGS} -Dlogging.config=${CONF_DIR}/log4j2-error-console.xml"
JVM_ARGS="${JVM_ARGS} -Dlog4j.configurationFile=${CONF_DIR}/log4j2-error-console.xml"
JVM_ARGS="${JVM_ARGS} -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"
echo "$JAVA_HOME/bin/java ${JVM_ARGS} timely.util.GetMetricTableSplitPoints --spring.config.name=timely"
+2 -1
View File
@@ -10,6 +10,7 @@ THIS_DIR="${THIS_SCRIPT%/*}"
BASE_DIR=${THIS_DIR}/..
LIB_DIR="${BASE_DIR}/lib"
NUM_SERVER_THREADS=4
CONF_DIR="${BASE_DIR}/conf"
if [ -z ${TIMELY_HOST+x} ]; then
echo "TIMELY_HOST is unset, using 127.0.0.1"
@@ -32,7 +33,7 @@ for j in ${LIB_DIR}/*.jar; do
SEP=":"
done
JVM_ARGS="-Xmx128m -Xms128m -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS} -Dlog4j.configurationFile=${THIS_DIR}/log4j2.xml"
JVM_ARGS="-Xmx128m -Xms128m -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS} -Dlog4j.configurationFile=${CONF_DIR}/log4j2-spring.xml"
echo "$JAVA_HOME/bin/java -classpath ${CP} ${JVM_ARGS} timely.util.InsertTestData ${TIMELY_HOST} ${TIMELY_PORT} --fast"
exec $JAVA_HOME/bin/java -classpath ${CP} ${JVM_ARGS} timely.util.InsertTestData ${TIMELY_HOST} ${TIMELY_PORT} --fast
+2 -1
View File
@@ -10,6 +10,7 @@ THIS_DIR="${THIS_SCRIPT%/*}"
BASE_DIR=${THIS_DIR}/..
LIB_DIR="${BASE_DIR}/lib"
NUM_SERVER_THREADS=4
CONF_DIR="${BASE_DIR}/conf"
if [ -z ${TIMELY_HOST+x} ]; then
echo "TIMELY_HOST is unset, using 127.0.0.1"
@@ -32,7 +33,7 @@ for j in ${LIB_DIR}/*.jar; do
SEP=":"
done
JVM_ARGS="-Xmx128m -Xms128m -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS} -Dlog4j.configurationFile=${THIS_DIR}/log4j2.xml"
JVM_ARGS="-Xmx128m -Xms128m -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS} -Dlog4j.configurationFile=${CONF_DIR}/log4j2-spring.xml"
echo "$JAVA_HOME/bin/java -classpath ${CP} ${JVM_ARGS} timely.util.InsertTestData ${TIMELY_HOST} ${TIMELY_PORT}"
exec $JAVA_HOME/bin/java -classpath ${CP} ${JVM_ARGS} timely.util.InsertTestData ${TIMELY_HOST} ${TIMELY_PORT}
+1 -1
View File
@@ -36,7 +36,7 @@ $JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-tcnative*.jar META-INF/native/libnetty-${
popd
export CLASSPATH="${CONF_DIR}:${LIB_DIR}/*"
JVM_ARGS="-Xmx256m -Xms256m -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS} -Dlog4j.configurationFile=${THIS_DIR}/log4j2.xml"
JVM_ARGS="-Xmx256m -Xms256m -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS}"
JVM_ARGS="${JVM_ARGS} -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"
JVM_ARGS="${JVM_ARGS} -Djava.library.path=${NATIVE_DIR}/libnetty-${TCNATIVE_SUFFIX}"
+1 -1
View File
@@ -36,7 +36,7 @@ $JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-tcnative*.jar META-INF/native/libnetty-${
popd
export CLASSPATH="${CONF_DIR}:${LIB_DIR}/*"
JVM_ARGS="-Xmx256m -Xms256m -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS} -Dlog4j.configurationFile=${THIS_DIR}/log4j2.xml"
JVM_ARGS="-Xmx256m -Xms256m -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS}"
JVM_ARGS="${JVM_ARGS} -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"
JVM_ARGS="${JVM_ARGS} -Djava.library.path=${NATIVE_DIR}"
# for debugging
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" monitorInterval="60">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error" includeLocation="false">
<AppenderRef ref="Console" level="error" />
</Root>
</Loggers>
</Configuration>
@@ -1,16 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" monitorInterval="60">
<Properties>
<Property name="PID">????</Property>
<Property name="LOG_PATTERN">%clr{%d{yyyy-MM-dd HH:mm:ss.SSS}}{faint} %clr{%5p} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n%wEx</Property>
</Properties>
<Appenders>
<RollingRandomAccessFile name="Rolling" fileName="logs/timely-server.log"
filePattern="logs/$${date:yyyy-MM}/timely-server-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<SizeBasedTriggeringPolicy size="1024 MB" />
</Policies>
<DefaultRolloverStrategy max="10" />
</RollingRandomAccessFile>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
</Appenders>
<Loggers>
+57
View File
@@ -0,0 +1,57 @@
timely:
metrics-table: timely.metrics
meta-table: timely.meta
metric-age-off-days:
default: 7
metrics-report-ignored-tags:
accumulo:
instance-name: TimelyStandalone
zookeepers: 127.0.0.1:9804
username: root
password: secret
write:
latency: 5s
threads: 3
bufferSize: 52428800
scan:
threads: 4
security:
session-max-age: 86400
allow-anonymous-access: true
ssl:
certificate-file: /timely-server-src/server/pki/timely.csr
key-file: /timely-server-src/server/pki/timely-pkcs8.key
key-password: password
use-generated-keypair: false
trust-store-file: /timely-server-src/server/pki/timely.crt
use-openssl: false
server:
ip: 0.0.0.0
tcp-port: 54321
udp-port: 54325
http:
ip: 0.0.0.0
port: 54322
host: localhost
redirect-path: /secure-me
strict-transport-max-age: 608400
cors:
allow-any-origin: true
allow-null-origin: false
allow-credentials: true
allowed-origins:
allowed-methods: DELETE,GET,HEAD,OPTIONS,PUT,POST
allowed-header: content-type
websocket:
ip: 0.0.0.0
port: 54323
timeout: 60
subscription-lag: 120
meta-cache:
expiration-minutes: 60
initial-capacity: 2000
max-capacity: 10000
visibility-cache:
expiration-minutes: 60
initial-capacity: 2000
max-capacity: 10000
+3 -1
View File
@@ -1,7 +1,8 @@
timely:
metrics-table: timely.metrics
meta-table: timely.meta
metric-age-off-days: 7
metric-age-off-days:
default: 7
metrics-report-ignored-tags:
accumulo:
instance-name: TimelyStandalone
@@ -27,6 +28,7 @@ timely:
server:
ip: 0.0.0.0
tcp-port: 54321
udp-port: 54325
http:
ip: 0.0.0.0
port: 54322
+3 -1
View File
@@ -1,7 +1,8 @@
timely:
metrics-table: timely.metrics
meta-table: timely.meta
metric-age-off-days: 7
metric-age-off-days:
default: 7
metrics-report-ignored-tags:
accumulo:
instance-name:
@@ -28,6 +29,7 @@ timely:
server:
ip:
tcp-port:
udp-port:
http:
host:
ip:
+2 -1
View File
@@ -30,6 +30,7 @@ services:
volumes:
- ${PWD}/../grafana/timely-app:/var/lib/grafana/plugins/timely-app
- ${PWD}/bin/docker/grafana:/etc/grafana
- ${PWD}/:/timely-server-src
entrypoint:
- gosu
- grafana
@@ -40,4 +41,4 @@ services:
- cfg:default.paths.logs=/var/log/grafana
- cfg:default.paths.plugins=/var/lib/grafana/plugins
depends_on:
- timely
- timely
Binary file not shown.
Binary file not shown.
+45 -159
View File
@@ -5,9 +5,20 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.3-SNAPSHOT</version>
<version>0.0.3</version>
</parent>
<dependencies>
<dependency>
<groupId>timely</groupId>
<artifactId>timely-client</artifactId>
<version>${parent.version}</version>
</dependency>
<dependency>
<groupId>timely</groupId>
<artifactId>timely-common</artifactId>
<version>${parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
@@ -28,6 +39,12 @@
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>com.google.flatbuffers</groupId>
<artifactId>flatbuffers-java</artifactId>
<scope>system</scope>
<systemPath>${project.basedir}/lib/flatbuffers-java-1.4.0.jar</systemPath>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
@@ -90,6 +107,10 @@
<groupId>org.apache.accumulo</groupId>
<artifactId>accumulo-minicluster</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
@@ -117,6 +138,11 @@
<artifactId>javassist</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
@@ -159,7 +185,6 @@
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>${version.os-maven}</version>
</extension>
</extensions>
<plugins>
@@ -223,186 +248,47 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<argLine>${failsafeArgLine} -Djava.library.path=${project.build.directory}/native/META-INF/native/libnetty-tcnative.so -Dzookeeper.sasl.client=false</argLine>
<includes>
<include>**/*.java</include>
</includes>
<groups>timely.test.IntegrationTest</groups>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/generated-java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<configuration>
<effort>Max</effort>
<threshold>Medium</threshold>
<xmlOutput>true</xmlOutput>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
<phase>prepare-package</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${sureFireArgLine} -Djava.library.path=${project.build.directory}/native/META-INF/native/libnetty-tcnative.so -Dzookeeper.sasl.client=false</argLine>
<excludedGroups>timely.test.IntegrationTest</excludedGroups>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>jacoco-prepare-ut</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<phase>process-test-classes</phase>
<configuration>
<destFile>${project.build.directory}/coverage/jacoco-ut.exec</destFile>
<propertyName>sureFireArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>jacoco-prepare-it</id>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<phase>pre-integration-test</phase>
<configuration>
<destFile>${project.build.directory}/coverage/jacoco-it.exec</destFile>
<propertyName>failsafeArgLine</propertyName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<configuration>
<configFile>${project.parent.basedir}/eclipse/Eclipse-Formatter.xml</configFile>
<lineEnding>LF</lineEnding>
<overrideConfigCompilerVersion>true</overrideConfigCompilerVersion>
</configuration>
<executions>
<execution>
<goals>
<goal>format</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>rpm</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-rpm</id>
<goals>
<goal>rpm</goal>
</goals>
<phase>package</phase>
<configuration>
<name>timely-server</name>
<group>Applications/System</group>
<prefix>/opt/timely</prefix>
<prefixes>
<prefix>INSTALL_DIR</prefix>
</prefixes>
<mappings>
<mapping>
<directory>/opt/timely/bin</directory>
<filemode>600</filemode>
<sources>
<source>
<location>${project.basedir}/bin</location>
<excludes>
<excludes>*.sh</excludes>
</excludes>
</source>
</sources>
</mapping>
<mapping>
<directory>/opt/timely/bin</directory>
<filemode>700</filemode>
<sources>
<source>
<location>${project.basedir}/bin</location>
<includes>
<include>*.sh</include>
</includes>
</source>
</sources>
</mapping>
<mapping>
<directory>/opt/timely/conf</directory>
<filemode>600</filemode>
<sources>
<source>
<location>${project.basedir}/conf</location>
<includes>
<include>*</include>
</includes>
</source>
</sources>
</mapping>
<mapping>
<directory>/opt/timely/lib</directory>
<filemode>600</filemode>
<sources>
<source>
<location>${project.basedir}/target/lib</location>
</source>
<source>
<location>${project.basedir}/target/${project.artifactId}-${project.version}.jar</location>
</source>
</sources>
</mapping>
</mappings>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<reporting>
<plugins>
<plugin>
@@ -0,0 +1,49 @@
// automatically generated by the FlatBuffers compiler, do not modify
package timely.api.flatbuffer;
import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Metric extends Table {
public static Metric getRootAsMetric(ByteBuffer _bb) { return getRootAsMetric(_bb, new Metric()); }
public static Metric getRootAsMetric(ByteBuffer _bb, Metric obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public Metric __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
public String name() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; }
public ByteBuffer nameAsByteBuffer() { return __vector_as_bytebuffer(4, 1); }
public long timestamp() { int o = __offset(6); return o != 0 ? bb.getLong(o + bb_pos) : 0; }
public double value() { int o = __offset(8); return o != 0 ? bb.getDouble(o + bb_pos) : 0.0; }
public Tag tags(int j) { return tags(new Tag(), j); }
public Tag tags(Tag obj, int j) { int o = __offset(10); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
public int tagsLength() { int o = __offset(10); return o != 0 ? __vector_len(o) : 0; }
public static int createMetric(FlatBufferBuilder builder,
int nameOffset,
long timestamp,
double value,
int tagsOffset) {
builder.startObject(4);
Metric.addValue(builder, value);
Metric.addTimestamp(builder, timestamp);
Metric.addTags(builder, tagsOffset);
Metric.addName(builder, nameOffset);
return Metric.endMetric(builder);
}
public static void startMetric(FlatBufferBuilder builder) { builder.startObject(4); }
public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(0, nameOffset, 0); }
public static void addTimestamp(FlatBufferBuilder builder, long timestamp) { builder.addLong(1, timestamp, 0); }
public static void addValue(FlatBufferBuilder builder, double value) { builder.addDouble(2, value, 0.0); }
public static void addTags(FlatBufferBuilder builder, int tagsOffset) { builder.addOffset(3, tagsOffset, 0); }
public static int createTagsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
public static void startTagsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static int endMetric(FlatBufferBuilder builder) {
int o = builder.endObject();
return o;
}
}
@@ -0,0 +1,38 @@
// automatically generated by the FlatBuffers compiler, do not modify
package timely.api.flatbuffer;
import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Metrics extends Table {
public static Metrics getRootAsMetrics(ByteBuffer _bb) { return getRootAsMetrics(_bb, new Metrics()); }
public static Metrics getRootAsMetrics(ByteBuffer _bb, Metrics obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public static boolean MetricsBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "TMFB"); }
public Metrics __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
public Metric metrics(int j) { return metrics(new Metric(), j); }
public Metric metrics(Metric obj, int j) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
public int metricsLength() { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; }
public static int createMetrics(FlatBufferBuilder builder,
int metricsOffset) {
builder.startObject(1);
Metrics.addMetrics(builder, metricsOffset);
return Metrics.endMetrics(builder);
}
public static void startMetrics(FlatBufferBuilder builder) { builder.startObject(1); }
public static void addMetrics(FlatBufferBuilder builder, int metricsOffset) { builder.addOffset(0, metricsOffset, 0); }
public static int createMetricsVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
public static void startMetricsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static int endMetrics(FlatBufferBuilder builder) {
int o = builder.endObject();
return o;
}
public static void finishMetricsBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "TMFB"); }
}
@@ -0,0 +1,38 @@
// automatically generated by the FlatBuffers compiler, do not modify
package timely.api.flatbuffer;
import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Tag extends Table {
public static Tag getRootAsTag(ByteBuffer _bb) { return getRootAsTag(_bb, new Tag()); }
public static Tag getRootAsTag(ByteBuffer _bb, Tag obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public Tag __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
public String key() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; }
public ByteBuffer keyAsByteBuffer() { return __vector_as_bytebuffer(4, 1); }
public String value() { int o = __offset(6); return o != 0 ? __string(o + bb_pos) : null; }
public ByteBuffer valueAsByteBuffer() { return __vector_as_bytebuffer(6, 1); }
public static int createTag(FlatBufferBuilder builder,
int keyOffset,
int valueOffset) {
builder.startObject(2);
Tag.addValue(builder, valueOffset);
Tag.addKey(builder, keyOffset);
return Tag.endTag(builder);
}
public static void startTag(FlatBufferBuilder builder) { builder.startObject(2); }
public static void addKey(FlatBufferBuilder builder, int keyOffset) { builder.addOffset(0, keyOffset, 0); }
public static void addValue(FlatBufferBuilder builder, int valueOffset) { builder.addOffset(1, valueOffset, 0); }
public static int endTag(FlatBufferBuilder builder) {
int o = builder.endObject();
return o;
}
}
+42 -11
View File
@@ -1,19 +1,23 @@
package timely;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.apache.accumulo.core.client.BatchWriterConfig;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.stereotype.Component;
import timely.validator.NotEmptyIfFieldSet;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.common.collect.Lists;
@Component
@ConfigurationProperties(prefix = "timely")
@@ -21,7 +25,7 @@ public class Configuration {
private String metricsTable = "timely.metrics";
private String metaTable = "timely.meta";
private int metricAgeOffDays = 7;
private HashMap<String, Integer> metricAgeOffDays = new HashMap<>();
private List<String> metricsReportIgnoredTags = new ArrayList<>();
@Valid
@@ -64,13 +68,12 @@ public class Configuration {
return this;
}
public int getMetricAgeOffDays() {
public HashMap<String, Integer> getMetricAgeOffDays() {
return metricAgeOffDays;
}
public Configuration setMetricAgeOffDays(int metricAgeOffDays) {
public void setMetricAgeOffDays(HashMap<String, Integer> metricAgeOffDays) {
this.metricAgeOffDays = metricAgeOffDays;
return this;
}
public List<String> getMetricsReportIgnoredTags() {
@@ -342,6 +345,9 @@ public class Configuration {
private String ip;
@NotNull
private Integer tcpPort;
@NotNull
private Integer udpPort;
private Integer shutdownQuietPeriod = 5;
@NotNull
public String getIp() {
@@ -361,6 +367,31 @@ public class Configuration {
this.tcpPort = tcpPort;
return Configuration.this;
}
public int getUdpPort() {
return udpPort;
}
public Configuration setUdpPort(Integer udpPort) {
this.udpPort = udpPort;
return Configuration.this;
}
/**
* Time to wait (in seconds) for connections to finish and to make sure
* no new connections happen before shutting down Netty event loop
* groups.
*
* @return
*/
public int getShutdownQuietPeriod() {
return this.shutdownQuietPeriod;
}
public Configuration setShutdownQuietPeriod(Integer quietPeriod) {
this.shutdownQuietPeriod = quietPeriod;
return Configuration.this;
}
}
public class Http {
+184 -74
View File
@@ -1,17 +1,17 @@
package timely;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.*;
import io.netty.channel.epoll.EpollDatagramChannel;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramChannel;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
@@ -40,14 +40,18 @@ import io.netty.util.internal.SystemPropertyUtil;
import java.io.File;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import timely.api.response.TimelyException;
import timely.auth.AuthCache;
import timely.auth.VisibilityCache;
@@ -64,9 +68,12 @@ import timely.netty.http.timeseries.HttpMetricsRequestHandler;
import timely.netty.http.timeseries.HttpQueryRequestHandler;
import timely.netty.http.timeseries.HttpSearchLookupRequestHandler;
import timely.netty.http.timeseries.HttpSuggestRequestHandler;
import timely.netty.tcp.MetricsBufferDecoder;
import timely.netty.tcp.TcpDecoder;
import timely.netty.tcp.TcpPutHandler;
import timely.netty.tcp.TcpVersionHandler;
import timely.netty.udp.UdpDecoder;
import timely.netty.udp.UdpPacketToByteBuf;
import timely.netty.websocket.WSMetricPutHandler;
import timely.netty.websocket.WSVersionRequestHandler;
import timely.netty.websocket.WebSocketHttpCookieHandler;
@@ -104,9 +111,12 @@ public class Server {
private EventLoopGroup httpBossGroup = null;
private EventLoopGroup wsWorkerGroup = null;
private EventLoopGroup wsBossGroup = null;
protected Channel putChannelHandle = null;
protected Channel queryChannelHandle = null;
private EventLoopGroup udpBossGroup = null;
private EventLoopGroup udpWorkerGroup = null;
protected Channel tcpChannelHandle = null;
protected Channel httpChannelHandle = null;
protected Channel wsChannelHandle = null;
protected Channel udpChannelHandle = null;
protected DataStore dataStore = null;
protected volatile boolean shutdown = false;
@@ -150,11 +160,18 @@ public class Server {
Server s = new Server(conf);
try {
s.run();
LATCH.await();
} catch (final InterruptedException e) {
LOG.info("Server shutting down.");
} catch (Exception e) {
LOG.error("Error running server.", e);
} finally {
s.shutdown();
try {
s.shutdown();
} catch (Exception e) {
System.exit(1);
}
}
}
@@ -175,59 +192,114 @@ public class Server {
}
public void shutdown() {
try {
putChannelHandle.close().sync();
} catch (final Exception e) {
LOG.error("Error shutting down tcp channel", e);
List<ChannelFuture> channelFutures = new ArrayList<>();
if (tcpChannelHandle != null) {
LOG.info("Closing tcpChannelHandle");
channelFutures.add(tcpChannelHandle.close());
}
try {
queryChannelHandle.close().sync();
} catch (final Exception e) {
LOG.error("Error shutting down http channel", e);
if (httpChannelHandle != null) {
LOG.info("Closing httpChannelHandle");
channelFutures.add(httpChannelHandle.close());
}
try {
wsChannelHandle.close().sync();
} catch (final Exception e) {
LOG.error("Error shutting down websocket channel", e);
if (wsChannelHandle != null) {
LOG.info("Closing wsChannelHandle");
channelFutures.add(wsChannelHandle.close());
}
try {
tcpBossGroup.shutdownGracefully().sync();
} catch (final Exception e) {
LOG.error("Error closing Netty TCP boss thread group", e);
if (udpChannelHandle != null) {
LOG.info("Closing udpChannelHandle");
channelFutures.add(udpChannelHandle.close());
}
try {
tcpWorkerGroup.shutdownGracefully().sync();
} catch (final Exception e) {
LOG.error("Error closing Netty TCP worker thread group", e);
// wait for the channels to shutdown
channelFutures.forEach(f -> {
try {
f.get();
} catch (final Exception e) {
LOG.error("Error while shutting down channel: {}", f.channel().config());
LOG.error("{}", e.getMessage());
e.printStackTrace();
}
});
Integer quietPeriod = config.getServer().getShutdownQuietPeriod();
List<Future<?>> groupFutures = new ArrayList<>();
if (tcpBossGroup != null) {
LOG.info("Shutting down tcpBossGroup");
groupFutures.add(tcpBossGroup.shutdownGracefully(quietPeriod, 10, TimeUnit.SECONDS));
}
try {
httpBossGroup.shutdownGracefully().sync();
} catch (final Exception e) {
LOG.error("Error closing Netty HTTP boss thread group", e);
if (tcpWorkerGroup != null) {
LOG.info("Shutting down tcpWorkerGroup");
groupFutures.add(tcpWorkerGroup.shutdownGracefully(quietPeriod, 10, TimeUnit.SECONDS));
}
try {
httpWorkerGroup.shutdownGracefully().sync();
} catch (final Exception e) {
LOG.error("Error closing Netty HTTP worker thread group", e);
if (httpBossGroup != null) {
LOG.info("Shutting down httpBossGroup");
groupFutures.add(httpBossGroup.shutdownGracefully(quietPeriod, 10, TimeUnit.SECONDS));
}
try {
wsBossGroup.shutdownGracefully().sync();
} catch (final Exception e) {
LOG.error("Error closing Netty websocket boss thread group", e);
if (httpWorkerGroup != null) {
LOG.info("Shutting down httpWorkerGroup");
groupFutures.add(httpWorkerGroup.shutdownGracefully(quietPeriod, 10, TimeUnit.SECONDS));
}
try {
wsWorkerGroup.shutdownGracefully().sync();
} catch (final Exception e) {
LOG.error("Error closing Netty websocket worker thread group", e);
if (wsBossGroup != null) {
LOG.info("Shutting down wsBossGroup");
groupFutures.add(wsBossGroup.shutdownGracefully(quietPeriod, 10, TimeUnit.SECONDS));
}
if (wsWorkerGroup != null) {
LOG.info("Shutting down wsWorkerGroup");
groupFutures.add(wsWorkerGroup.shutdownGracefully(quietPeriod, 10, TimeUnit.SECONDS));
}
if (udpBossGroup != null) {
LOG.info("Shutting down udpBossGroup");
groupFutures.add(udpBossGroup.shutdownGracefully(quietPeriod, 10, TimeUnit.SECONDS));
}
if (udpWorkerGroup != null) {
LOG.info("Shutting down udpWorkerGroup");
groupFutures.add(udpWorkerGroup.shutdownGracefully(quietPeriod, 10, TimeUnit.SECONDS));
}
groupFutures.parallelStream().forEach(f -> {
try {
f.get();
} catch (final Exception e) {
LOG.error("Error while shutting down group: {}", f.toString());
LOG.error("{}", e.getMessage());
e.printStackTrace();
}
});
try {
LOG.info("Flushing datastore.");
dataStore.flush();
} catch (TimelyException e) {
LOG.error("Error flushing to server during shutdown", e);
}
MetaCacheFactory.close();
WebSocketRequestDecoder.close();
try {
LOG.info("Closing MetaCacheFactory");
MetaCacheFactory.close();
} catch (Exception e) {
LOG.error("Error closing MetaCacheFactory during shutdown", e);
}
try {
LOG.info("Closing WebSocketRequestDecoder");
WebSocketRequestDecoder.close();
} catch (Exception e) {
LOG.error("Error closing WebSocketRequestDecoder during shutdown", e);
}
if (applicationContext != null) {
LOG.info("Closing applicationContext");
applicationContext.close();
}
this.shutdown = true;
@@ -237,6 +309,9 @@ public class Server {
public Server(Configuration conf) throws Exception {
this.config = conf;
}
public void run() throws Exception {
int nettyThreads = Math.max(1,
SystemPropertyUtil.getInt("io.netty.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2));
@@ -249,6 +324,7 @@ public class Server {
VisibilityCache.init(config);
final boolean useEpoll = useEpoll();
Class<? extends ServerSocketChannel> channelClass;
Class<? extends Channel> datagramChannelClass;
if (useEpoll) {
tcpWorkerGroup = new EpollEventLoopGroup();
tcpBossGroup = new EpollEventLoopGroup();
@@ -256,7 +332,10 @@ public class Server {
httpBossGroup = new EpollEventLoopGroup();
wsWorkerGroup = new EpollEventLoopGroup();
wsBossGroup = new EpollEventLoopGroup();
udpWorkerGroup = new EpollEventLoopGroup();
udpBossGroup = new EpollEventLoopGroup();
channelClass = EpollServerSocketChannel.class;
datagramChannelClass = EpollDatagramChannel.class;
} else {
tcpWorkerGroup = new NioEventLoopGroup();
tcpBossGroup = new NioEventLoopGroup();
@@ -264,46 +343,51 @@ public class Server {
httpBossGroup = new NioEventLoopGroup();
wsWorkerGroup = new NioEventLoopGroup();
wsBossGroup = new NioEventLoopGroup();
udpWorkerGroup = new NioEventLoopGroup();
udpBossGroup = new NioEventLoopGroup();
channelClass = NioServerSocketChannel.class;
datagramChannelClass = NioDatagramChannel.class;
}
LOG.info("Using channel class {}", channelClass.getSimpleName());
final ServerBootstrap putServer = new ServerBootstrap();
putServer.group(tcpBossGroup, tcpWorkerGroup);
putServer.channel(channelClass);
putServer.handler(new LoggingHandler());
putServer.childHandler(setupTcpChannel());
putServer.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
putServer.option(ChannelOption.SO_BACKLOG, 128);
putServer.option(ChannelOption.SO_KEEPALIVE, true);
final int putPort = config.getServer().getTcpPort();
putChannelHandle = putServer.bind(putPort).sync().channel();
final String putAddress = ((InetSocketAddress) putChannelHandle.localAddress()).getAddress().getHostAddress();
final ServerBootstrap tcpServer = new ServerBootstrap();
tcpServer.group(tcpBossGroup, tcpWorkerGroup);
tcpServer.channel(channelClass);
tcpServer.handler(new LoggingHandler());
tcpServer.childHandler(setupTcpChannel());
tcpServer.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
tcpServer.option(ChannelOption.SO_BACKLOG, 128);
tcpServer.option(ChannelOption.SO_KEEPALIVE, true);
final int tcpPort = config.getServer().getTcpPort();
final String tcpIp = config.getServer().getIp();
tcpChannelHandle = tcpServer.bind(tcpIp, tcpPort).sync().channel();
final String tcpAddress = ((InetSocketAddress) tcpChannelHandle.localAddress()).getAddress().getHostAddress();
final int queryPort = config.getHttp().getPort();
final int httpPort = config.getHttp().getPort();
final String httpIp = config.getHttp().getIp();
SslContext sslCtx = createSSLContext(config);
if (sslCtx instanceof OpenSslServerContext) {
OpenSslServerContext openssl = (OpenSslServerContext) sslCtx;
String application = "Timely_" + queryPort;
String application = "Timely_" + httpPort;
OpenSslServerSessionContext opensslCtx = openssl.sessionContext();
opensslCtx.setSessionCacheEnabled(true);
opensslCtx.setSessionCacheSize(128);
opensslCtx.setSessionIdContext(application.getBytes(StandardCharsets.UTF_8));
opensslCtx.setSessionTimeout(config.getSecurity().getSessionMaxAge());
}
final ServerBootstrap queryServer = new ServerBootstrap();
queryServer.group(httpBossGroup, httpWorkerGroup);
queryServer.channel(channelClass);
queryServer.handler(new LoggingHandler());
queryServer.childHandler(setupHttpChannel(config, sslCtx));
queryServer.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
queryServer.option(ChannelOption.SO_BACKLOG, 128);
queryServer.option(ChannelOption.SO_KEEPALIVE, true);
queryChannelHandle = queryServer.bind(queryPort).sync().channel();
final String queryAddress = ((InetSocketAddress) queryChannelHandle.localAddress()).getAddress()
.getHostAddress();
final ServerBootstrap httpServer = new ServerBootstrap();
httpServer.group(httpBossGroup, httpWorkerGroup);
httpServer.channel(channelClass);
httpServer.handler(new LoggingHandler());
httpServer.childHandler(setupHttpChannel(config, sslCtx));
httpServer.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
httpServer.option(ChannelOption.SO_BACKLOG, 128);
httpServer.option(ChannelOption.SO_KEEPALIVE, true);
httpChannelHandle = httpServer.bind(httpIp, httpPort).sync().channel();
final String httpAddress = ((InetSocketAddress) httpChannelHandle.localAddress()).getAddress().getHostAddress();
final int wsPort = config.getWebsocket().getPort();
final String wsIp = config.getWebsocket().getIp();
final ServerBootstrap wsServer = new ServerBootstrap();
wsServer.group(wsBossGroup, wsWorkerGroup);
wsServer.channel(channelClass);
@@ -312,13 +396,23 @@ public class Server {
wsServer.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
wsServer.option(ChannelOption.SO_BACKLOG, 128);
wsServer.option(ChannelOption.SO_KEEPALIVE, true);
wsChannelHandle = wsServer.bind(wsPort).sync().channel();
wsChannelHandle = wsServer.bind(wsIp, wsPort).sync().channel();
final String wsAddress = ((InetSocketAddress) wsChannelHandle.localAddress()).getAddress().getHostAddress();
final int udpPort = config.getServer().getUdpPort();
final String udpIp = config.getServer().getIp();
final Bootstrap udpServer = new Bootstrap();
udpServer.group(udpBossGroup);
udpServer.channel(datagramChannelClass);
udpServer.handler(setupUdpChannel());
udpServer.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
udpChannelHandle = udpServer.bind(udpIp, udpPort).sync().channel();
final String udpAddress = ((InetSocketAddress) wsChannelHandle.localAddress()).getAddress().getHostAddress();
shutdownHook();
LOG.info(
"Server started. Listening on {}:{} for TCP traffic, {}:{} for HTTP traffic, and {}:{} for WebSocket traffic",
putAddress, putPort, queryAddress, queryPort, wsAddress, wsPort);
"Server started. Listening on {}:{} for TCP traffic, {}:{} for HTTP traffic, {}:{} for WebSocket traffic, and {}:{} for UDP traffic",
tcpAddress, tcpPort, httpAddress, httpPort, wsAddress, wsPort, udpAddress, udpPort);
}
protected SslContext createSSLContext(Configuration config) throws Exception {
@@ -412,11 +506,27 @@ public class Server {
};
}
protected ChannelHandler setupUdpChannel() {
return new ChannelInitializer<DatagramChannel>() {
@Override
protected void initChannel(DatagramChannel ch) throws Exception {
ch.pipeline().addLast("logger", new LoggingHandler());
ch.pipeline().addLast("packetDecoder", new UdpPacketToByteBuf());
ch.pipeline().addLast("buffer", new MetricsBufferDecoder());
ch.pipeline().addLast("frame", new DelimiterBasedFrameDecoder(8192, true, Delimiters.lineDelimiter()));
ch.pipeline().addLast("putDecoder", new UdpDecoder());
ch.pipeline().addLast(udpWorkerGroup, "putHandler", new TcpPutHandler(dataStore));
}
};
}
protected ChannelHandler setupTcpChannel() {
return new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("buffer", new MetricsBufferDecoder());
ch.pipeline().addLast("frame", new DelimiterBasedFrameDecoder(8192, true, Delimiters.lineDelimiter()));
ch.pipeline().addLast("putDecoder", new TcpDecoder());
ch.pipeline().addLast("putHandler", new TcpPutHandler(dataStore));
@@ -82,7 +82,8 @@ public class StandaloneServer extends Server {
}
try {
LOG.info("Starting StandaloneServer");
new StandaloneServer(conf);
StandaloneServer s = new StandaloneServer(conf);
s.run();
} catch (Exception e) {
System.err.println("Error starting server");
e.printStackTrace();
@@ -0,0 +1,108 @@
package timely.adapter.accumulo;
import org.apache.accumulo.core.client.lexicoder.LongLexicoder;
import org.apache.accumulo.core.client.lexicoder.PairLexicoder;
import org.apache.accumulo.core.client.lexicoder.StringLexicoder;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Mutation;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.security.ColumnVisibility;
import org.apache.accumulo.core.util.ComparablePair;
import org.apache.accumulo.core.util.Pair;
import timely.model.Metric;
import timely.model.Tag;
import timely.model.parse.TagListParser;
import timely.model.parse.TagParser;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* Creates Accumulo data structures from {@link timely.model.Metric}
*/
public class MetricAdapter {
private static final PairLexicoder<String, Long> rowCoder = new PairLexicoder<>(new StringLexicoder(),
new LongLexicoder());
private static final TagParser tagParser = new TagParser();
private static final TagListParser tagListParser = new TagListParser();
public static final ColumnVisibility EMPTY_VISIBILITY = new ColumnVisibility();
public static final String VISIBILITY_TAG = "viz";
public static Mutation toMutation(Metric metric) {
final Mutation mutation = new Mutation(encodeRowKey(metric));
List<Tag> tags = metric.getTags();
Collections.sort(tags);
for (final Tag entry : tags) {
if (entry.getKey().equals(VISIBILITY_TAG))
continue;
final String cf = entry.join();
// @formatter:off
String cq = tags.stream().filter(inner -> !inner.equals(entry))
.filter(inner -> !inner.getKey().equals(VISIBILITY_TAG))
.map(Tag::join)
.collect(Collectors.joining(","));
// @formatter:on
mutation.put(cf, cq, extractVisibility(tags), metric.getValue().getTimestamp(), extractValue(metric));
}
return mutation;
}
private static Value extractValue(Metric metric) {
return new Value(encodeValue(metric.getValue().getMeasure()));
}
public static byte[] encodeValue(Double d) {
byte[] b = new byte[Double.BYTES];
ByteBuffer bb = ByteBuffer.wrap(b);
bb.putDouble(d);
return b;
}
public static Double decodeValue(byte[] buf) {
ByteBuffer bb = ByteBuffer.wrap(buf);
return bb.getDouble();
}
private static ColumnVisibility extractVisibility(List<Tag> tags) {
// @formatter:off
Optional<Tag> visTag = tags.stream()
.filter(t -> t.getKey().equals(VISIBILITY_TAG))
.findFirst();
return visTag.isPresent() ? new ColumnVisibility(visTag.get().getValue()) : EMPTY_VISIBILITY;
// @formatter:on
}
public static Metric parse(Key k, Value v) {
ComparablePair<String, Long> row = rowCoder.decode(k.getRow().getBytes());
// @formatter:off
Metric.Builder builder = Metric.newBuilder()
.name(row.getFirst())
.value(row.getSecond(), ByteBuffer.wrap(v.get()).getDouble())
.tag(tagParser.parse(k.getColumnFamily().toString()));
// @formatter:on
tagListParser.parse(k.getColumnQualifier().toString()).forEach(builder::tag);
return builder.build();
}
public static byte[] encodeRowKey(String metricName, Long timestamp) {
return rowCoder.encode(new ComparablePair<>(metricName, timestamp));
}
public static byte[] encodeRowKey(Metric metric) {
return encodeRowKey(metric.getName(), metric.getValue().getTimestamp());
}
public static Pair<String, Long> decodeRowKey(Key k) {
return rowCoder.decode(k.getRow().getBytes());
}
}
@@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
import timely.api.request.HttpGetRequest;
import timely.api.request.HttpPostRequest;
import timely.api.request.TcpRequest;
import timely.api.request.UdpRequest;
import timely.api.request.WebSocketRequest;
public class AnnotationResolver {
@@ -20,9 +21,11 @@ public class AnnotationResolver {
private static List<String> tcpClassNames;
private static List<String> httpClassNames;
private static List<String> wsClassNames;
private static List<String> udpClassNames;
private static List<Class<?>> tcpClasses = new ArrayList<>();
private static List<Class<?>> httpClasses = new ArrayList<>();
private static List<Class<?>> wsClasses = new ArrayList<>();
private static List<Class<?>> udpClasses = new ArrayList<>();
private AnnotationResolver() {
}
@@ -64,6 +67,22 @@ public class AnnotationResolver {
}
}
LOG.trace("Loaded web socket classes: {}", wsClasses);
udpClassNames = scanner.getNamesOfClassesWithAnnotation(Udp.class);
LOG.trace("Found udp classes: {}", udpClassNames);
if (null != udpClassNames) {
for (String cls : udpClassNames) {
try {
udpClasses.add(Class.forName(cls));
} catch (Exception e) {
LOG.error("Error loading/creating class: " + cls, e);
}
}
}
LOG.trace("Loaded udp classes: {}", tcpClasses);
}
public static List<Class<?>> getTcpClasses() {
return tcpClasses;
}
public static TcpRequest getClassForTcpOperation(String operation) throws Exception {
@@ -122,4 +141,17 @@ public class AnnotationResolver {
return null;
}
public static UdpRequest getClassForUdpOperation(String operation) throws Exception {
for (Class<?> c : udpClasses) {
if (c.getAnnotation(Udp.class).operation().equals(operation)) {
Object o = c.newInstance();
if (o instanceof UdpRequest) {
LOG.trace("Returning {} for UDP operation {}", c, operation);
return (UdpRequest) o;
}
}
}
return null;
}
}
@@ -0,0 +1,14 @@
package timely.api.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Udp {
public String operation();
}
@@ -1,232 +0,0 @@
package timely.api.model;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.accumulo.core.client.lexicoder.DoubleLexicoder;
import org.apache.accumulo.core.client.lexicoder.LongLexicoder;
import org.apache.accumulo.core.client.lexicoder.PairLexicoder;
import org.apache.accumulo.core.client.lexicoder.StringLexicoder;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Mutation;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.security.ColumnVisibility;
import org.apache.accumulo.core.util.ComparablePair;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import timely.api.annotation.Http;
import timely.api.annotation.Tcp;
import timely.api.annotation.WebSocket;
import timely.api.request.HttpPostRequest;
import timely.api.request.TcpRequest;
import timely.api.request.WebSocketRequest;
import timely.api.response.MetricResponse;
import timely.auth.VisibilityCache;
import timely.util.JsonUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Tcp(operation = "put")
@Http(path = "/api/put")
@WebSocket(operation = "put")
public class Metric implements TcpRequest, HttpPostRequest, WebSocketRequest {
private static final PairLexicoder<String, Long> rowCoder = new PairLexicoder<>(new StringLexicoder(),
new LongLexicoder());
private static final DoubleLexicoder valueCoder = new DoubleLexicoder();
public static final ColumnVisibility EMPTY_VISIBILITY = new ColumnVisibility();
private static final String VISIBILITY_TAG = "viz=";
private static final int VISIBILITY_TAG_LENGTH = VISIBILITY_TAG.length();
private String metric;
private long timestamp;
private double value;
private List<Tag> tags;
@JsonIgnore
private ColumnVisibility visibility = EMPTY_VISIBILITY;
public Metric() {
}
public Metric(String metric, long timestamp, double value, List<Tag> tags) {
super();
this.metric = metric;
this.timestamp = timestamp;
this.value = value;
this.tags = tags;
}
public String getMetric() {
return metric;
}
public void setMetric(String metric) {
this.metric = metric;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
public void addTag(Tag tag) {
if (null == this.tags) {
tags = new ArrayList<Tag>();
}
this.tags.add(tag);
}
public ColumnVisibility getVisibility() {
return visibility;
}
public void setVisibility(ColumnVisibility visibility) {
this.visibility = visibility;
}
public Mutation toMutation() {
final byte[] row = rowCoder.encode(new ComparablePair<String, Long>(this.metric, this.timestamp));
final Value value = new Value(valueCoder.encode(this.value));
final Mutation m = new Mutation(row);
Collections.sort(tags);
for (final Tag entry : tags) {
final String cf = entry.getKey() + "=" + entry.getValue();
final StringBuffer otherTags = new StringBuffer();
String sep = "";
for (final Tag inner : this.tags) {
if (inner != entry) {
otherTags.append(sep).append(inner.getKey()).append("=").append(inner.getValue());
sep = ",";
}
}
m.put(cf, otherTags, visibility, this.timestamp, value);
}
return m;
}
public static Metric parse(Key k, Value v) {
ComparablePair<String, Long> row = rowCoder.decode(k.getRow().getBytes());
Double value = valueCoder.decode(v.get());
Metric m = new Metric();
m.setMetric(row.getFirst());
m.setTimestamp(row.getSecond());
Tag tag = new Tag(k.getColumnFamily().toString());
m.addTag(tag);
String qualifier = k.getColumnQualifier().toString();
if (!qualifier.isEmpty()) {
for (String otherTag : qualifier.split(",")) {
m.addTag(new Tag(otherTag));
}
}
m.setValue(value);
return m;
}
public static byte[] encodeRowKey(String metric, Long timestamp) {
return rowCoder.encode(new ComparablePair<String, Long>(metric, timestamp));
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("[metric = ").append(metric);
buf.append(", timestamp = ").append(timestamp);
tags.forEach(t -> buf.append(", ").append(t.getKey()).append(" = ").append(t.getValue()));
buf.append(", value = ").append(value).append("]");
return buf.toString();
}
@Override
public int hashCode() {
HashCodeBuilder hc = new HashCodeBuilder(17, 37);
hc.append(metric);
hc.append(timestamp);
hc.append(value);
hc.append(tags);
return hc.toHashCode();
}
@Override
public boolean equals(Object obj) {
if (null == obj) {
return false;
}
if (this == obj) {
return true;
}
if (!(obj instanceof Metric)) {
return false;
}
Metric other = (Metric) obj;
EqualsBuilder equals = new EqualsBuilder();
equals.append(this.metric, other.metric);
equals.append(this.timestamp, other.timestamp);
equals.append(this.value, other.value);
equals.append(this.tags, other.tags);
return equals.isEquals();
}
@Override
public void parse(String line) {
// put specification
//
// put <metricName> <timestamp> <value> <tagK=tagV> <tagK=tagV> ...
String[] parts = line.split(" ");
this.setMetric(parts[1]);
long ts = Long.parseLong(parts[2]);
if (ts < 9999999999L) {
ts *= 1000;
}
this.setTimestamp(ts);
this.setValue(Double.valueOf(parts[3]));
String part;
for (int i = 4; i < parts.length; i++) {
part = parts[i];
if (part.startsWith(VISIBILITY_TAG) && part.length() > VISIBILITY_TAG_LENGTH) {
this.setVisibility(VisibilityCache.getColumnVisibility(part.substring(VISIBILITY_TAG_LENGTH)));
} else if (!part.isEmpty()) {
this.addTag(new Tag(parts[i]));
}
}
}
@Override
public HttpPostRequest parseBody(String content) throws Exception {
return JsonUtil.getObjectMapper().readValue(content.getBytes(StandardCharsets.UTF_8), Metric.class);
}
public MetricResponse toMetricResponse(String subscriptionId) {
MetricResponse response = new MetricResponse();
response.setMetric(this.metric);
response.setTimestamp(this.timestamp);
response.setTags(this.tags);
response.setValue(this.value);
response.setSubscriptionId(subscriptionId);
return response;
}
}
@@ -1,96 +0,0 @@
package timely.api.model;
import java.io.Serializable;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
public class Tag implements Comparable<Tag>, Serializable {
private static final long serialVersionUID = 1L;
private String key;
private String value;
public Tag() {
super();
}
public Tag(String tagValue) {
super();
String[] tv = tagValue.split("=");
if (tv.length != 2) {
throw new IllegalArgumentException("Invalid tag format: " + tagValue);
}
this.key = tv[0];
this.value = tv[1];
}
public Tag(String key, String value) {
super();
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public int hashCode() {
HashCodeBuilder hcb = new HashCodeBuilder();
hcb.append(key);
hcb.append(value);
return hcb.toHashCode();
}
@Override
public boolean equals(Object obj) {
if (null == obj) {
return false;
}
if (this == obj) {
return true;
}
if (obj instanceof Tag) {
Tag other = (Tag) obj;
EqualsBuilder eq = new EqualsBuilder();
eq.append(this.key, other.key);
eq.append(this.value, other.value);
return eq.isEquals();
} else {
return false;
}
}
@Override
public String toString() {
ToStringBuilder tsb = new ToStringBuilder(this);
tsb.append("key", key);
tsb.append("value", value);
return tsb.toString();
}
@Override
public int compareTo(Tag o) {
int result = key.compareTo(o.key);
if (result != 0) {
return result;
}
return value.compareTo(o.value);
}
}
@@ -0,0 +1,82 @@
package timely.api.request;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.api.annotation.Http;
import timely.api.annotation.Tcp;
import timely.api.annotation.Udp;
import timely.api.annotation.WebSocket;
import timely.model.Metric;
import timely.model.parse.MetricParser;
import timely.util.JsonUtil;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.nio.charset.StandardCharsets;
@Tcp(operation = "put")
@Udp(operation = "put")
@Http(path = "/api/put")
@WebSocket(operation = "put")
@XmlRootElement(name = "metric")
public class MetricRequest implements TcpRequest, HttpPostRequest, WebSocketRequest, UdpRequest {
private static final Logger LOG = LoggerFactory.getLogger(MetricRequest.class);
@XmlElement
@JsonUnwrapped
private Metric metric;
private static final MetricParser metricParser = new MetricParser();
public MetricRequest() {
}
public MetricRequest(Metric metric) {
this.metric = metric;
}
public Metric getMetric() {
return metric;
}
public void setMetric(Metric metric) {
this.metric = metric;
}
@Override
public HttpPostRequest parseBody(String content) throws Exception {
metric = JsonUtil.getObjectMapper().readValue(content.getBytes(StandardCharsets.UTF_8), Metric.class);
return this;
}
@Override
public void parse(String line) {
LOG.trace("Parsing Line: {}", line);
metric = metricParser.parse(line);
}
@Override
public String toString() {
return metric.toString();
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
MetricRequest that = (MetricRequest) o;
return metric != null ? metric.equals(that.metric) : that.metric == null;
}
@Override
public int hashCode() {
return metric != null ? metric.hashCode() : 0;
}
}
@@ -0,0 +1,12 @@
package timely.api.request;
public interface UdpRequest {
/**
* Parse a line of text received and populate this object
*
* @param line
*/
public void parse(String line);
}
@@ -10,7 +10,11 @@ import timely.api.annotation.WebSocket;
@WebSocket(operation = "version")
public class VersionRequest implements TcpRequest, HttpGetRequest, HttpPostRequest, WebSocketRequest {
public static final String VERSION = VersionRequest.class.getPackage().getImplementationVersion();
public static final String VERSION;
static {
String ver = VersionRequest.class.getPackage().getImplementationVersion();
VERSION = (null == ver) ? "Unknown" : ver;
}
public String getVersion() {
return VERSION;
@@ -11,7 +11,7 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
import timely.api.annotation.Http;
import timely.api.annotation.WebSocket;
import timely.api.model.Tag;
import timely.model.Tag;
import timely.api.request.AuthenticatedRequest;
import timely.api.request.HttpGetRequest;
import timely.api.request.HttpPostRequest;
@@ -107,6 +107,7 @@ public class SearchLookupRequest extends AuthenticatedRequest implements HttpGet
JsonNode operation = root.findValue("operation");
if (null == operation) {
StringBuilder buf = new StringBuilder(content.length() + 10);
// TODO building JSON by hand? ugh
buf.append("{ \"operation\" : \"lookup\", ");
int open = content.indexOf("{");
buf.append(content.substring(open + 1));
@@ -122,6 +123,7 @@ public class SearchLookupRequest extends AuthenticatedRequest implements HttpGet
throw new IllegalArgumentException("m parameter is required for lookup");
}
final String m = decoder.parameters().get("m").get(0);
// TODO are you parsing json yourself here? that's always a bad idea.
final int tagIdx = m.indexOf("{");
if (-1 == tagIdx) {
search.setQuery(m);
@@ -6,7 +6,8 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import timely.api.model.Tag;
import timely.model.Metric;
import timely.model.Tag;
public class MetricResponse {
@@ -56,6 +57,16 @@ public class MetricResponse {
this.subscriptionId = subscriptionId;
}
public static MetricResponse fromMetric(Metric metric, String subscriptionId) {
MetricResponse response = new MetricResponse();
response.setMetric(metric.getName());
response.setTimestamp(metric.getValue().getTimestamp());
response.setTags(metric.getTags());
response.setValue(metric.getValue().getMeasure());
response.setSubscriptionId(subscriptionId);
return response;
}
@Override
public int hashCode() {
HashCodeBuilder hash = new HashCodeBuilder();
@@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import timely.Configuration;
import timely.adapter.accumulo.MetricAdapter;
import timely.api.model.Meta;
import timely.netty.Constants;
import timely.store.MetaCache;
@@ -39,6 +40,7 @@ public class MetricsResponse {
private static final Logger LOG = LoggerFactory.getLogger(MetricsResponse.class);
// TODO get rid of this HTML monstronsity
private static final String DOCTYPE = "<!DOCTYPE html>\n";
private static final String META = "<meta charset=\"UTF-8\">\n";
private static final String HTML_START = "<html>\n";
@@ -70,6 +72,7 @@ public class MetricsResponse {
public MetricsResponse(Configuration conf) {
this.conf = conf;
ignoredTags = new HashSet<>(conf.getMetricsReportIgnoredTags());
ignoredTags.add(MetricAdapter.VISIBILITY_TAG);
}
public TextWebSocketFrame toWebSocketResponse(String acceptHeader) throws Exception {
@@ -12,12 +12,12 @@ import io.netty.handler.codec.http.HttpHeaders.Names;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.api.model.Metric;
import timely.api.request.MetricRequest;
import timely.api.response.TimelyException;
import timely.netty.Constants;
import timely.store.DataStore;
public class HttpMetricPutHandler extends SimpleChannelInboundHandler<Metric> implements TimelyHttpHandler {
public class HttpMetricPutHandler extends SimpleChannelInboundHandler<MetricRequest> implements TimelyHttpHandler {
private static final Logger LOG = LoggerFactory.getLogger(HttpMetricPutHandler.class);
private final DataStore dataStore;
@@ -27,9 +27,9 @@ public class HttpMetricPutHandler extends SimpleChannelInboundHandler<Metric> im
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Metric m) throws Exception {
protected void channelRead0(ChannelHandlerContext ctx, MetricRequest m) throws Exception {
try {
this.dataStore.store(m);
this.dataStore.store(m.getMetric());
} catch (TimelyException e) {
LOG.error(e.getMessage(), e);
this.sendHttpError(ctx, e);
@@ -30,7 +30,7 @@ public class HttpQueryRequestHandler extends SimpleChannelInboundHandler<QueryRe
@Override
protected void channelRead0(ChannelHandlerContext ctx, QueryRequest msg) throws Exception {
byte[] buf = null;
byte[] buf;
try {
buf = JsonUtil.getObjectMapper().writeValueAsBytes(dataStore.query(msg));
} catch (TimelyException e) {
@@ -0,0 +1,66 @@
package timely.netty.tcp;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.api.flatbuffer.Metrics;
import timely.api.request.MetricRequest;
import timely.model.Metric;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import timely.model.Tag;
public class MetricsBufferDecoder extends ByteToMessageDecoder {
private static final Logger LOG = LoggerFactory.getLogger(MetricsBufferDecoder.class);
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (in.readableBytes() < 8) {
return;
}
LOG.debug("Received {} bytes", in.readableBytes());
boolean isFlatBuffer = false;
try {
isFlatBuffer = Metrics.MetricsBufferHasIdentifier(in.slice().nioBuffer());
} catch (Exception e) {
LOG.warn("Error checking for identifier: " + e.getClass().getSimpleName());
isFlatBuffer = false;
}
if (!isFlatBuffer) {
LOG.debug("Input is not a Flatbuffer");
out.add(in.readBytes(in.readableBytes()));
} else {
LOG.debug("Input is a Flatbuffer");
ByteBuf copy = in.readBytes(in.readableBytes());
try {
Metrics metrics = Metrics.getRootAsMetrics(copy.nioBuffer());
int length = metrics.metricsLength();
for (int i = 0; i < length; i++) {
MetricRequest m = new MetricRequest(parseFlatbuffer(metrics.metrics(i)));
LOG.debug("Returning {}", m);
out.add(m);
}
} catch (Exception e) {
LOG.warn("Error decoding byte[] with Google Flatbuffers: " + e.getMessage());
return;
} finally {
copy.release();
}
}
}
public Metric parseFlatbuffer(timely.api.flatbuffer.Metric flatMetric) {
Metric.Builder builder = Metric.newBuilder().name(flatMetric.name())
.value(flatMetric.timestamp(), flatMetric.value());
for (int i = 0; i < flatMetric.tagsLength(); i++) {
timely.api.flatbuffer.Tag t = flatMetric.tags(i);
builder.tag(new Tag(t.key(), t.value()));
}
return builder.build();
}
}
@@ -37,10 +37,10 @@ public class TcpDecoder extends ByteToMessageDecoder {
LOG.warn("Received no input");
return;
}
LOG.trace("Received input {}", input);
LOG.trace("Received input: {}", input);
String[] parts = input.split(" ");
String operation = null;
String operation;
if (parts.length == 0 && !StringUtils.isEmpty(input)) {
operation = input;
} else {
@@ -48,7 +48,7 @@ public class TcpDecoder extends ByteToMessageDecoder {
}
TcpRequest tcp = null;
try {
tcp = (TcpRequest) AnnotationResolver.getClassForTcpOperation(operation);
tcp = AnnotationResolver.getClassForTcpOperation(operation);
} catch (Exception e) {
LOG.error("Error getting class for operation: " + operation, e);
}
@@ -10,11 +10,11 @@ import java.nio.charset.StandardCharsets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.api.model.Metric;
import timely.api.request.MetricRequest;
import timely.netty.Constants;
import timely.store.DataStore;
public class TcpPutHandler extends SimpleChannelInboundHandler<Metric> {
public class TcpPutHandler extends SimpleChannelInboundHandler<MetricRequest> {
private static final Logger LOG = LoggerFactory.getLogger(TcpPutHandler.class);
private static final String LOG_ERR_MSG = "Error storing put metric: {}";
@@ -26,10 +26,10 @@ public class TcpPutHandler extends SimpleChannelInboundHandler<Metric> {
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Metric msg) throws Exception {
protected void channelRead0(ChannelHandlerContext ctx, MetricRequest msg) throws Exception {
LOG.trace("Received {}", msg);
try {
store.store(msg);
store.store(msg.getMetric());
} catch (Exception e) {
LOG.error(LOG_ERR_MSG, msg, e);
ChannelFuture cf = ctx.writeAndFlush(Unpooled.copiedBuffer((ERR_MSG + e.getMessage() + "\n")
@@ -0,0 +1,67 @@
package timely.netty.udp;
import static java.nio.charset.StandardCharsets.UTF_8;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.api.annotation.AnnotationResolver;
import timely.api.request.UdpRequest;
public class UdpDecoder extends ByteToMessageDecoder {
private static final Logger LOG = LoggerFactory.getLogger(UdpDecoder.class);
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
ByteBuf buf = in.readBytes(in.readableBytes());
try {
if (buf == Unpooled.EMPTY_BUFFER) {
return;
}
final String input;
if (buf.hasArray()) {
input = new String(buf.array(), UTF_8);
} else {
input = buf.toString(UTF_8);
}
if (StringUtils.isEmpty(input)) {
LOG.warn("Received no input");
return;
}
LOG.trace("Received input {}", input);
String[] parts = input.split(" ");
String operation = null;
if (parts.length == 0 && !StringUtils.isEmpty(input)) {
operation = input;
} else {
operation = parts[0];
}
UdpRequest tcp = null;
try {
tcp = (UdpRequest) AnnotationResolver.getClassForUdpOperation(operation);
} catch (Exception e) {
LOG.error("Error getting class for operation: " + operation, e);
}
if (null == tcp) {
LOG.error("Unknown udp operation: " + parts[0]);
return;
}
tcp.parse(input);
out.add(tcp);
LOG.trace("Converted {} to {}", input, tcp);
} finally {
buf.release();
}
}
}
@@ -0,0 +1,19 @@
package timely.netty.udp;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import io.netty.handler.codec.MessageToMessageDecoder;
import java.util.List;
public class UdpPacketToByteBuf extends MessageToMessageDecoder<DatagramPacket> {
@Override
protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List<Object> out) throws Exception {
ByteBuf buf = msg.content();
buf.retain();
out.add(buf);
}
}
@@ -2,10 +2,10 @@ package timely.netty.websocket;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import timely.api.model.Metric;
import timely.api.request.MetricRequest;
import timely.store.DataStore;
public class WSMetricPutHandler extends SimpleChannelInboundHandler<Metric> {
public class WSMetricPutHandler extends SimpleChannelInboundHandler<MetricRequest> {
private final DataStore dataStore;
@@ -14,8 +14,8 @@ public class WSMetricPutHandler extends SimpleChannelInboundHandler<Metric> {
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Metric m) throws Exception {
this.dataStore.store(m);
protected void channelRead0(ChannelHandlerContext ctx, MetricRequest m) throws Exception {
this.dataStore.store(m.getMetric());
}
}
@@ -7,18 +7,53 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
import timely.api.request.timeseries.QueryRequest.RateOption;
import com.google.common.base.Preconditions;
public class Downsample implements Iterable<Sample>, Serializable {
private static Logger LOG = LoggerFactory.getLogger(Downsample.class);
public static class AggregatedValue implements Serializable {
private static final long serialVersionUID = 1L;
private int count = 0;
private double value = 0.0D;
public void incrementCount() {
count++;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("{count: ").append(this.count);
buf.append(" value: ").append(this.value).append("}");
return buf.toString();
}
}
private static final long serialVersionUID = 1L;
@@ -26,8 +61,8 @@ public class Downsample implements Iterable<Sample>, Serializable {
private final String aggregatorClassname;
private final long start;
private final long period;
private final double[] values;
private final int[] counts;
private final TreeMap<Long, AggregatedValue> buckets = new TreeMap<>();
public Downsample(long start, long end, long period, Aggregator agg) {
Preconditions.checkArgument(start < end, "Start must be < end");
@@ -37,12 +72,6 @@ public class Downsample implements Iterable<Sample>, Serializable {
this.period = period;
this.aggregator = agg;
this.aggregatorClassname = agg.getClass().getName();
long buckets = (end - start) / period + 1;
if (buckets > Integer.MAX_VALUE) {
throw new RuntimeException("Cannot downsample to " + buckets + " items");
}
values = new double[(int) buckets];
counts = new int[(int) buckets];
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@@ -58,19 +87,24 @@ public class Downsample implements Iterable<Sample>, Serializable {
if (ts < start) {
throw new IllegalArgumentException("timestamp is out of range");
}
int bucket = (int) ((ts - start) / period);
if (bucket > values.length) {
throw new IllegalArgumentException("timestamp is out of range");
// find the start time of the bucket
long sampleStart = ts - ((ts - start) % period);
AggregatedValue val = buckets.get(sampleStart);
if (null == val) {
buckets.put(sampleStart, val = new AggregatedValue());
}
values[bucket] = aggregator.aggregate(values[bucket], counts[bucket], value);
counts[bucket]++;
val.setValue(aggregator.aggregate(val.getValue(), val.getCount(), value));
val.incrementCount();
}
public void merge(Downsample other) {
for (int i = 0; i < other.counts.length; i++) {
if (other.counts[i] > 0) {
counts[i] += other.counts[i];
values[i] = aggregator.aggregate(values[i], counts[i], other.values[i]);
for (Entry<Long, AggregatedValue> e : other.buckets.entrySet()) {
AggregatedValue thisVal = buckets.get(e.getKey());
if (null == thisVal) {
buckets.put(e.getKey(), e.getValue());
} else {
thisVal.setCount(thisVal.getCount() + e.getValue().getCount());
thisVal.setValue(aggregator.aggregate(thisVal.getValue(), thisVal.getCount(), e.getValue().getValue()));
}
}
}
@@ -79,23 +113,19 @@ public class Downsample implements Iterable<Sample>, Serializable {
public Iterator<Sample> iterator() {
return new Iterator<Sample>() {
int next = 0;
Sample sample = new Sample();
Iterator<Long> keys = buckets.keySet().iterator();
@Override
public boolean hasNext() {
while (next < values.length && counts[next] == 0) {
next++;
}
return next < values.length;
return keys.hasNext();
}
@Override
public Sample next() {
double value = aggregator.last(values[next], counts[next]);
sample.set(start + next * period, value);
next++;
return sample;
long time = keys.next();
AggregatedValue val = buckets.get(time);
double value = aggregator.last(val.getValue(), val.getCount());
return new Sample(time, value);
}
};
}
@@ -104,10 +134,13 @@ public class Downsample implements Iterable<Sample>, Serializable {
public String toString() {
ToStringBuilder tsb = new ToStringBuilder(this);
tsb.append("aggregator", this.aggregatorClassname);
tsb.append("counts", this.counts);
tsb.append("period", this.period);
tsb.append("start", this.start);
tsb.append("values", this.values);
tsb.append("values={");
for (Entry<Long, AggregatedValue> e : this.buckets.entrySet()) {
tsb.append(e.getKey()).append("=").append(e.getValue()).append(", ");
}
tsb.append("}");
return tsb.toString();
}
@@ -117,10 +150,6 @@ public class Downsample implements Iterable<Sample>, Serializable {
throw new IllegalArgumentException("Empty samples to combine");
}
for (Downsample ds : samples) {
if (rateOption != null && rateOption.isCounter()) {
ds = convertCountToRate(ds, rateOption.getResetValue(), rateOption.getCounterMax());
}
ds = interpolateMissingValues(ds);
sampleList.add(ds);
}
Iterator<Downsample> iter = sampleList.iterator();
@@ -131,64 +160,4 @@ public class Downsample implements Iterable<Sample>, Serializable {
return result;
}
private static Downsample interpolateMissingValues(Downsample ds) {
Downsample result = new Downsample(ds.start, ds.start + ds.counts.length * ds.period, ds.period, ds.aggregator);
int lastPos = -1;
for (int i = 0; i < ds.counts.length; i++) {
if (ds.counts[i] != 0) {
result.values[i] = ds.values[i];
result.counts[i] = ds.counts[i];
if (lastPos >= 0) {
double diff = ds.values[i] - ds.values[lastPos];
for (int j = lastPos + 1; j < i; j++) {
result.values[j] = result.values[j - 1] + diff / (i - lastPos);
result.counts[j] = 1;
}
}
lastPos = i;
}
}
LOG.debug("interpolate: {}", result);
return result;
}
private static Downsample convertCountToRate(Downsample ds, long resetValue, long counterMax) {
Downsample result = new Downsample(ds.start + ds.period, ds.start + ds.counts.length * ds.period, ds.period,
ds.aggregator);
int lastPos = 0;
for (int i = 1; i < ds.counts.length; i++) {
if (ds.counts[i] != 0) {
if (((Long) counterMax).equals(((Double) ds.values[i]).longValue())) {
result.values[i - 1] = resetValue;
result.counts[i - 1] = 1;
} else {
double diff = ds.values[i] - ds.values[lastPos];
if (diff < 0) {
// wrap around formula from
// https://collectd.org/wiki/index.php/Data_source says
// to do
// the following:
// double wrapValue = (counterMax - ds.values[lastPos] +
// ds.values[i]) / (ds.period);
// When counterMax is not defined it defaults to
// Long.MAX_VALUE which leaves wrapValue
// very close to counterMax. This renders the resulting
// graph useless as it blows up the
// scale, we are going to set the value to -1. If we
// have a constantly decreasing counter,
// which in theory should not happen, then all of the
// values will be -1.
double wrapValue = -1.0;
result.values[i - 1] = wrapValue;
result.counts[i - 1] = 1;
} else {
result.values[i - 1] = diff;
result.counts[i - 1] = 1;
}
}
lastPos = i;
}
}
return result;
}
}
@@ -10,6 +10,11 @@ public class Sample {
public Sample() {
}
public Sample(long timestamp, double value) {
this.timestamp = timestamp;
this.value = value;
}
public void set(long timestamp, double value) {
this.timestamp = timestamp;
this.value = value;
@@ -17,8 +17,9 @@ import org.apache.accumulo.core.iterators.IteratorEnvironment;
import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
import org.apache.accumulo.core.iterators.WrappingIterator;
import timely.api.model.Metric;
import timely.api.model.Tag;
import timely.adapter.accumulo.MetricAdapter;
import timely.model.Metric;
import timely.model.Tag;
import timely.api.response.TimelyException;
import timely.sample.Aggregator;
import timely.sample.Downsample;
@@ -57,7 +58,7 @@ public class DownsampleIterator extends WrappingIterator {
public boolean hasTop() {
while (super.hasTop()) {
last = super.getTopKey();
Metric metric = Metric.parse(super.getTopKey(), super.getTopValue());
Metric metric = MetricAdapter.parse(super.getTopKey(), super.getTopValue());
Set<Tag> tags = new HashSet<Tag>(metric.getTags());
Downsample sample = value.get(tags);
if (sample == null) {
@@ -67,7 +68,7 @@ public class DownsampleIterator extends WrappingIterator {
throw new RuntimeException(e);
}
}
sample.add(metric.getTimestamp(), metric.getValue());
sample.add(metric.getValue().getTimestamp(), metric.getValue().getMeasure());
try {
super.next();
} catch (IOException e) {
@@ -5,7 +5,7 @@ import java.util.Map;
import org.apache.accumulo.core.client.Scanner;
import timely.api.model.Metric;
import timely.model.Metric;
import timely.api.request.timeseries.QueryRequest;
import timely.api.request.timeseries.SearchLookupRequest;
import timely.api.request.timeseries.SuggestRequest;
@@ -51,7 +51,6 @@ import org.apache.accumulo.core.data.PartialKey;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
import org.apache.accumulo.core.iterators.user.AgeOffFilter;
import org.apache.accumulo.core.iterators.user.RegExFilter;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.util.Pair;
@@ -61,27 +60,29 @@ import org.apache.hadoop.io.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.Server;
import timely.Configuration;
import timely.Server;
import timely.adapter.accumulo.MetricAdapter;
import timely.api.model.Meta;
import timely.api.model.Metric;
import timely.api.model.Tag;
import timely.api.request.AuthenticatedRequest;
import timely.api.request.timeseries.QueryRequest;
import timely.api.request.timeseries.SearchLookupRequest;
import timely.api.request.timeseries.SuggestRequest;
import timely.api.request.timeseries.QueryRequest.RateOption;
import timely.api.request.timeseries.QueryRequest.SubQuery;
import timely.api.request.timeseries.SearchLookupRequest;
import timely.api.request.timeseries.SuggestRequest;
import timely.api.response.TimelyException;
import timely.api.response.timeseries.QueryResponse;
import timely.api.response.timeseries.SearchLookupResponse;
import timely.api.response.timeseries.SuggestResponse;
import timely.api.response.timeseries.SearchLookupResponse.Result;
import timely.api.response.timeseries.SuggestResponse;
import timely.auth.AuthCache;
import timely.model.Metric;
import timely.model.Tag;
import timely.sample.Aggregator;
import timely.sample.Downsample;
import timely.sample.Sample;
import timely.sample.iterators.DownsampleIterator;
import timely.store.iterators.RateIterator;
import timely.util.MetaKeySet;
public class DataStoreImpl implements DataStore {
@@ -145,13 +146,6 @@ public class DataStoreImpl implements DataStore {
scannerThreads = accumuloConf.getScan().getThreads();
anonAccessAllowed = conf.getSecurity().isAllowAnonymousAccess();
String ageoff = Long.toString(conf.getMetricAgeOffDays() * 86400000L);
Map<String, String> ageOffOptions = new HashMap<>();
ageOffOptions.put("ttl", ageoff);
IteratorSetting ageOffIteratorSettings = new IteratorSetting(100, "ageoff", AgeOffFilter.class,
ageOffOptions);
EnumSet<IteratorScope> ageOffIteratorScope = EnumSet.allOf(IteratorScope.class);
metricsTable = conf.getMetricsTable();
if (metricsTable.contains(".")) {
final String[] parts = metricsTable.split("\\.", 2);
@@ -170,36 +164,25 @@ public class DataStoreImpl implements DataStore {
try {
LOG.info("Creating table " + metricsTable);
connector.tableOperations().create(metricsTable);
connector.tableOperations().attachIterator(metricsTable, ageOffIteratorSettings,
ageOffIteratorScope);
} catch (final TableExistsException ex) {
// don't care
}
} else {
for (IteratorScope scope : IteratorScope.values()) {
if (connector.tableOperations().getIteratorSetting(metricsTable, "ageoff", scope) == null) {
connector.tableOperations().attachIterator(metricsTable, ageOffIteratorSettings,
EnumSet.of(scope));
}
}
}
this.removeAgeOffIterators(connector, metricsTable);
this.applyAgeOffIterator(connector, metricsTable, conf);
metaTable = conf.getMetaTable();
if (!tableIdMap.containsKey(metaTable)) {
try {
LOG.info("Creating table " + metaTable);
connector.tableOperations().create(metaTable);
connector.tableOperations().attachIterator(metaTable, ageOffIteratorSettings, ageOffIteratorScope);
} catch (final TableExistsException ex) {
// don't care
}
} else {
for (IteratorScope scope : IteratorScope.values()) {
if (connector.tableOperations().getIteratorSetting(metaTable, "ageoff", scope) == null) {
connector.tableOperations()
.attachIterator(metaTable, ageOffIteratorSettings, EnumSet.of(scope));
}
}
}
this.removeAgeOffIterators(connector, metaTable);
this.applyAgeOffIterator(connector, metaTable, conf);
internalMetricsTimer.schedule(new TimerTask() {
@Override
@@ -215,8 +198,32 @@ public class DataStoreImpl implements DataStore {
}
}
private static final EnumSet<IteratorScope> AGEOFF_SCOPES = EnumSet.allOf(IteratorScope.class);
private void removeAgeOffIterators(Connector con, String tableName) throws Exception {
Map<String, EnumSet<IteratorScope>> iters = con.tableOperations().listIterators(tableName);
for (String name : iters.keySet()) {
if (name.startsWith("ageoff")) {
con.tableOperations().removeIterator(tableName, name, AGEOFF_SCOPES);
}
}
}
private void applyAgeOffIterator(Connector con, String tableName, Configuration config) throws Exception {
int priority = 100;
Map<String, String> ageOffOptions = new HashMap<>();
for (Entry<String, Integer> e : config.getMetricAgeOffDays().entrySet()) {
String ageoff = Long.toString(e.getValue() * 86400000L);
ageOffOptions.put(MetricAgeOffFilter.AGE_OFF_PREFIX + e.getKey(), ageoff);
}
IteratorSetting ageOffIteratorSettings = new IteratorSetting(priority, "ageoff", MetricAgeOffFilter.class,
ageOffOptions);
connector.tableOperations().attachIterator(tableName, ageOffIteratorSettings, AGEOFF_SCOPES);
}
@Override
public void store(Metric metric) {
LOG.trace("Received Store Request for: {}", metric);
if (null == metaWriter.get()) {
try {
BatchWriter w = connector.createBatchWriter(metaTable, bwConfig);
@@ -241,7 +248,7 @@ public class DataStoreImpl implements DataStore {
internalMetrics.incrementMetricsReceived(1);
List<Meta> toCache = new ArrayList<>(metric.getTags().size());
for (final Tag tag : metric.getTags()) {
Meta key = new Meta(metric.getMetric(), tag.getKey(), tag.getValue());
Meta key = new Meta(metric.getName(), tag.getKey(), tag.getValue());
if (!metaCache.contains(key)) {
toCache.add(key);
}
@@ -289,7 +296,8 @@ public class DataStoreImpl implements DataStore {
metaCache.addAll(toCache);
}
try {
batchWriter.get().addMutation(metric.toMutation());
batchWriter.get().addMutation(MetricAdapter.toMutation(metric));
internalMetrics.incrementMetricKeysInserted(metric.getTags().size());
} catch (MutationsRejectedException e) {
LOG.error("Unable to write to metrics table", e);
@@ -311,15 +319,17 @@ public class DataStoreImpl implements DataStore {
}
}
private static final long FIVE_MINUTES_IN_MS = TimeUnit.MINUTES.toMillis(5);
private void updateMetricCounts() {
long now = System.currentTimeMillis();
if (now - lastCountTime.get() > 5 * 60 * 1000) {
if (now - lastCountTime.get() > FIVE_MINUTES_IN_MS) {
this.lastCountTime.set(now);
SortedMap<MetricTagK, Integer> update = new TreeMap<>();
for (Meta meta : this.metaCache) {
MetricTagK key = new MetricTagK(meta.getMetric(), meta.getTagKey());
Integer count = update.getOrDefault(key, Integer.valueOf(0));
update.put(key, Integer.valueOf(count.intValue() + 1));
Integer count = update.getOrDefault(key, 0);
update.put(key, count + 1);
}
this.metaCounts.set(update);
}
@@ -452,6 +462,12 @@ public class DataStoreImpl implements DataStore {
List<String> tagOrder = prioritizeTags(query);
Map<String, String> orderedTags = orderTags(tagOrder, query.getTags());
setQueryColumns(scanner, metric, orderedTags);
if (query.isRate()) {
LOG.trace("Adding rate iterator");
IteratorSetting rate = new IteratorSetting(499, RateIterator.class);
scanner.addScanIterator(rate);
}
long downsample = getDownsamplePeriod(query);
LOG.trace("Downsample period {}", downsample);
Class<? extends Aggregator> aggClass = getAggregator(query);
@@ -459,6 +475,7 @@ public class DataStoreImpl implements DataStore {
IteratorSetting is = new IteratorSetting(500, DownsampleIterator.class);
DownsampleIterator.setDownsampleOptions(is, startTs, endTs, downsample, aggClass.getName());
scanner.addScanIterator(is);
// tag -> array of results by period starting at start
for (Entry<Key, Value> encoded : scanner) {
Map<Set<Tag>, Downsample> samples = DownsampleIterator.decodeValue(encoded.getValue());
@@ -704,9 +721,9 @@ public class DataStoreImpl implements DataStore {
}
private void setQueryRange(BatchScanner scanner, String metric, long start, long end) {
final byte[] start_row = Metric.encodeRowKey(metric, start);
final byte[] start_row = MetricAdapter.encodeRowKey(metric, start);
LOG.trace("Start key for metric {} and time {} is {}", metric, start, start_row);
final byte[] end_row = Metric.encodeRowKey(metric, end);
final byte[] end_row = MetricAdapter.encodeRowKey(metric, end);
LOG.trace("End key for metric {} and time {} is {}", metric, end, end_row);
Range range = new Range(new Text(start_row), new Text(end_row));
LOG.trace("Set query range to {}", range);
@@ -779,9 +796,9 @@ public class DataStoreImpl implements DataStore {
if (null == metric) {
throw new IllegalArgumentException("metric name must be specified");
}
byte[] start = Metric.encodeRowKey(metric, startTime);
byte[] start = MetricAdapter.encodeRowKey(metric, startTime);
long endTime = (System.currentTimeMillis() - (lag * 1000));
byte[] end = Metric.encodeRowKey(metric, endTime);
byte[] end = MetricAdapter.encodeRowKey(metric, endTime);
s.setRange(new Range(new Text(start), true, new Text(end), false));
SubQuery query = new SubQuery();
query.setMetric(metric);
@@ -8,8 +8,8 @@ import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.api.model.Metric;
import timely.api.model.Tag;
import timely.model.Metric;
import timely.model.Tag;
import com.google.common.util.concurrent.AtomicDouble;
@@ -0,0 +1,132 @@
package timely.store;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.IOException;
import java.util.Map;
import org.apache.accumulo.core.data.ByteSequence;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.iterators.Filter;
import org.apache.accumulo.core.iterators.IteratorEnvironment;
import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
import org.apache.commons.collections4.trie.PatriciaTrie;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MetricAgeOffFilter extends Filter {
private static final Logger LOG = LoggerFactory.getLogger(MetricAgeOffFilter.class);
public static final String AGE_OFF_PREFIX = "ageoff.";
public static final String DEFAULT_AGEOFF_KEY = "default";
private PatriciaTrie<Long> ageoffs = null;
private Long currentTime = 0L;
private Long defaultAgeOff = 0L;
private Long minAgeOff = Long.MAX_VALUE;
private Long maxAgeOff = Long.MIN_VALUE;
private byte[] prevMetricBytes = null;
private Long prevAgeOff = null;
@Override
public boolean accept(Key k, Value v) {
// If less than any configured ageoff, then keep it
if ((this.currentTime - k.getTimestamp()) < this.minAgeOff) {
return true;
}
// If greater than any configured ageoff, then drop it
if ((this.currentTime - k.getTimestamp()) > this.maxAgeOff) {
return false;
}
// There is a high probability that this key will have
// the same metric name as the last key.
ByteSequence rowData = k.getRowData();
int rowStart = rowData.offset();
int i = 0;
if (null != prevMetricBytes && (rowData.length() >= (rowStart + prevMetricBytes.length + 1))
&& (rowData.byteAt(rowStart + prevMetricBytes.length + 1) == 0x00)) {
// Double check metric name is the same
boolean same = true;
for (; i < prevMetricBytes.length; i++) {
if (prevMetricBytes[i] != rowData.byteAt(rowStart + i)) {
same = false;
break;
}
}
if (same) {
if ((currentTime - k.getTimestamp()) > prevAgeOff)
return false;
return true;
}
}
// Metric name is different or prev information is not set
// We have not found the null byte up to this point.
// Keep scanning for the null byte
int y = rowStart + i;
for (; y < rowData.length(); y++) {
byte b = rowData.byteAt(y);
if (b == 0x00) {
break;
}
}
byte[] metricName = new byte[(y - rowStart)];
System.arraycopy(rowData.getBackingArray(), rowStart, metricName, 0, (y - rowStart));
prevMetricBytes = metricName;
prevAgeOff = ageoffs.get(new String(prevMetricBytes, UTF_8));
if (null == prevAgeOff) {
// no specific ageoff for this metric name, use default
prevAgeOff = defaultAgeOff;
}
if (currentTime - k.getTimestamp() > prevAgeOff)
return false;
return true;
}
@Override
public void init(SortedKeyValueIterator<Key, Value> source, Map<String, String> options, IteratorEnvironment env)
throws IOException {
super.init(source, options, env);
validateOptions(options);
ageoffs = new PatriciaTrie<>();
options.forEach((k, v) -> {
if (k.startsWith(AGE_OFF_PREFIX)) {
String name = k.substring(AGE_OFF_PREFIX.length());
LOG.trace("Adding {} to Trie with value", name, Long.parseLong(v));
long ageoff = Long.parseLong(v);
this.minAgeOff = Math.min(this.minAgeOff, ageoff);
this.maxAgeOff = Math.max(this.maxAgeOff, ageoff);
ageoffs.put(name, ageoff);
}
});
defaultAgeOff = ageoffs.get(DEFAULT_AGEOFF_KEY);
currentTime = System.currentTimeMillis();
}
@Override
public SortedKeyValueIterator<Key, Value> deepCopy(IteratorEnvironment env) {
MetricAgeOffFilter filter = (MetricAgeOffFilter) super.deepCopy(env);
filter.ageoffs = this.ageoffs;
return filter;
}
@Override
public IteratorOptions describeOptions() {
IteratorOptions io = super.describeOptions();
io.addNamedOption(DEFAULT_AGEOFF_KEY, "default age off days");
return io;
}
@Override
public boolean validateOptions(Map<String, String> options) {
if (null == options.get(MetricAgeOffFilter.AGE_OFF_PREFIX + DEFAULT_AGEOFF_KEY)) {
throw new IllegalArgumentException(DEFAULT_AGEOFF_KEY + " must be configured for MetricAgeOffFilter");
}
return super.validateOptions(options);
}
}
@@ -0,0 +1,52 @@
package timely.store.iterators;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.iterators.IteratorEnvironment;
import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
import org.apache.accumulo.core.util.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RateIterator extends TimeSeriesGroupingIterator {
public static final Logger LOG = LoggerFactory.getLogger(RateIterator.class);
@Override
public void init(SortedKeyValueIterator<Key, Value> source, Map<String, String> options, IteratorEnvironment env)
throws IOException {
Map<String, String> opts = new HashMap<>(options);
opts.put(TimeSeriesGroupingIterator.FILTER, "-1,1");
super.init(source, opts, env);
}
@Override
protected Double compute(List<Pair<Key, Double>> values) {
Iterator<Pair<Key, Double>> iter = values.iterator();
Pair<Key, Double> first = iter.next();
Long firstTs = first.getFirst().getTimestamp();
Double firstVal = first.getSecond() * -1;
LOG.trace("first ts:{}, value:{}", firstTs, firstVal);
Pair<Key, Double> second = iter.next();
Long secondTs = second.getFirst().getTimestamp();
Double secondVal = second.getSecond();
LOG.trace("second ts:{}, value:{}", secondTs, secondVal);
long timeDiff = secondTs - firstTs;
if (timeDiff == 0) {
return 0.0D;
}
Double result = ((firstVal + secondVal) / timeDiff);
LOG.trace("compute - result: {}", result);
return result;
}
}
@@ -0,0 +1,265 @@
package timely.store.iterators;
import org.apache.accumulo.core.data.ByteSequence;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.iterators.IteratorEnvironment;
import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
import org.apache.accumulo.core.iterators.WrappingIterator;
import org.apache.accumulo.core.util.Pair;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.adapter.accumulo.MetricAdapter;
import timely.model.Metric;
import java.io.IOException;
import java.io.Serializable;
import java.util.*;
/**
* Iterator that groups time series so that a filter can be applied to the time
* series. Filters are specified as a comma separated list of doubles. For
* example, a five day moving average filter would be specified as:
* "0.20,0.20,0.20,0.20,0.20"
*
* Note that this iterator will consume at the start F keys where F is the
* number of elements in the filter. So, if you have a five day moving average
* filter and a time series as 100 data points, then you will receive 95
* results.
*
* For multiple time series, K/V pairs will be reported in time order where time
* is taken from the key of the last element in the filter. For example, if you
* have series {A,B,C} and {A,C} are on the same time interval and B is lagging
* behind them, then this iterator will return K/V answers for the time series
* in the following manner:
*
* A, C, B, A, C, B, ...
*
* Also of note is that this iterator handles new time series appearing in the
* middle of the time range. Time series that disappear during the time range
* will stop reporting an answer.
*
* NOTE: This iterator does not handle being re-seeked. It is currently designed
* to be used with the DownsampleIterator above it.
*
*/
public class TimeSeriesGroupingIterator extends WrappingIterator {
/**
* Object representing a single time series and its computed value. The
* value will be computed when the time series its values reach the target
* size. Calling getAndRemoveAnswer will return the answer and clear it's
* internal representation.
*
*/
private static class TimeSeries extends LinkedList<Pair<Key, Double>> implements Serializable {
private static final long serialVersionUID = 1L;
private int targetSize;
private transient TimeSeriesGroupingIterator iter;
private Double answer;
public TimeSeries(TimeSeriesGroupingIterator iter, int size) {
this.iter = iter;
this.targetSize = size;
}
public void add(Key key, Double value) {
super.add(new Pair<>(key, value));
if (super.size() == this.targetSize) {
recompute();
// remove first key as it is no longer needed for any
// computations
Pair<Key, Double> e = this.pollFirst();
LOG.trace("Removing first entry {}", e.getFirst());
}
}
public Double getAndRemoveAnswer() {
try {
return this.answer;
} finally {
this.answer = null;
}
}
private void recompute() {
this.answer = iter.compute(this);
LOG.trace("recomputed, new answer: {}", this.answer);
}
}
/**
*
* Object representing a group of time series, where uniqueness is defined
* by the name of the metric and a unique tag set.
*
*/
private static class TimeSeriesGroup extends HashMap<Metric, TimeSeries> implements Iterable<Pair<Key, Double>> {
private static final long serialVersionUID = 1L;
private transient List<Pair<Key, Double>> answers;
public TimeSeriesGroup() {
this.answers = new ArrayList<>();
}
@Override
public TimeSeries put(Metric key, TimeSeries value) {
TimeSeries old = super.put(key, value);
Double answer = value.getAndRemoveAnswer();
if (answer != null) {
answers.add(new Pair<>(value.getLast().getFirst(), answer));
}
return old;
}
/**
* Iterates over the time series group and returns for each time series
* the last key and the filtered value.
*/
@Override
public Iterator<Pair<Key, Double>> iterator() {
try {
return answers.iterator();
} finally {
answers = new ArrayList<>();
}
}
}
private static final Logger LOG = LoggerFactory.getLogger(TimeSeriesGroupingIterator.class);
public static final String FILTER = "sliding.window.filter";
private TimeSeriesGroup series = new TimeSeriesGroup();
protected Double[] filters = null;
private Key topKey = null;
private Value topValue = null;
private Iterator<Pair<Key, Double>> seriesIterator = null;
protected Double compute(List<Pair<Key, Double>> values) {
double result = 0D;
int i = 0;
for (Pair<Key, Double> e : values) {
LOG.trace("compute - key:{}, value: {}", e.getFirst(), e.getSecond());
result += (filters[i] * e.getSecond());
i++;
}
LOG.trace("compute - result: {}", result);
return result;
}
@Override
public Key getTopKey() {
return topKey;
}
@Override
public Value getTopValue() {
return topValue;
}
@Override
public boolean hasTop() {
LOG.trace("hasTop()");
return (null != topKey && null != topValue);
}
private void setTopKeyValue() {
while (!seriesIterator.hasNext() && super.hasTop()) {
try {
refillBuffer();
seriesIterator = series.iterator();
} catch (IOException e) {
throw new RuntimeException("Error filling buffer", e);
}
}
if (seriesIterator.hasNext()) {
Pair<Key, Double> p = seriesIterator.next();
topKey = p.getFirst();
topValue = new Value(MetricAdapter.encodeValue(p.getSecond()));
} else {
topKey = null;
topValue = null;
}
}
@Override
public void next() throws IOException {
LOG.trace("next()");
setTopKeyValue();
}
@Override
public void init(SortedKeyValueIterator<Key, Value> source, Map<String, String> options, IteratorEnvironment env)
throws IOException {
super.init(source, options, env);
String filterOption = options.getOrDefault(FILTER, null);
if (null == filterOption) {
throw new IllegalArgumentException("Window size must be specified.");
}
String[] split = StringUtils.split(filterOption, ',');
filters = new Double[split.length];
for (int i = 0; i < split.length; i++) {
filters[i] = Double.parseDouble(split[i]);
}
LOG.trace("init - filter: {}", Arrays.toString(filters));
}
@Override
public void seek(Range range, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException {
super.seek(range, columnFamilies, inclusive);
series.clear();
seriesIterator = series.iterator();
setTopKeyValue();
}
/**
* This will parse the next set of keys with the same timestamp (encoded in
* the row) from the underlying source.
*
* @throws IOException
*/
private void refillBuffer() throws IOException {
LOG.trace("refill()");
Long time = null;
while (super.hasTop()) {
Key k = super.getTopKey();
Long newTime = MetricAdapter.decodeRowKey(k).getSecond();
if (time == null) {
time = newTime;
}
if (time.equals(newTime)) {
Metric m = MetricAdapter.parse(k, super.getTopValue());
timely.model.Value v = m.getValue();
m.setValue(null);
TimeSeries values = series.get(m);
if (null == values) {
LOG.trace("Creating new time series {}", m);
values = new TimeSeries(this, filters.length);
}
LOG.trace("Adding value {} to series {}", v.getMeasure(), m);
values.add(k, v.getMeasure());
// always re-put the metric back into the TimeSeriesGroup as it
// maintains a list of prepared answers
series.put(m, values);
super.next();
} else {
break;
}
}
LOG.trace("Buffer contents: {}", series);
}
}
@@ -1,5 +1,6 @@
package timely.subscription;
import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterruptibly;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
@@ -7,18 +8,20 @@ import java.lang.Thread.UncaughtExceptionHandler;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import org.apache.accumulo.core.client.Scanner;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.util.UtilWaitThread;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.hadoop.io.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.api.model.Metric;
import timely.adapter.accumulo.MetricAdapter;
import timely.api.response.MetricResponse;
import timely.model.Metric;
import timely.api.response.TimelyException;
import timely.store.DataStore;
import timely.util.JsonUtil;
@@ -73,9 +76,9 @@ public class MetricScanner extends Thread implements UncaughtExceptionHandler {
if (this.iter.hasNext()) {
Entry<Key, Value> e = this.iter.next();
m = Metric.parse(e.getKey(), e.getValue());
m = MetricAdapter.parse(e.getKey(), e.getValue());
try {
String json = om.writeValueAsString(m.toMetricResponse(this.subscriptionId));
String json = om.writeValueAsString(MetricResponse.fromMetric(m, this.subscriptionId));
LOG.trace("Returning {} for subscription", json);
this.ctx.writeAndFlush(new TextWebSocketFrame(json));
} catch (JsonProcessingException e1) {
@@ -83,22 +86,22 @@ public class MetricScanner extends Thread implements UncaughtExceptionHandler {
}
} else {
long endTime = (System.currentTimeMillis() - (lag * 1000));
byte[] end = Metric.encodeRowKey(this.metric, endTime);
byte[] end = MetricAdapter.encodeRowKey(this.metric, endTime);
Text endRow = new Text(end);
this.scanner.close();
Range prevRange = this.scanner.getRange();
if (null == m) {
LOG.debug("No results found, waiting {}ms to retry.", delay);
UtilWaitThread.sleep(delay);
sleepUninterruptibly(delay, TimeUnit.MILLISECONDS);
this.scanner.setRange(new Range(prevRange.getStartKey().getRow(), prevRange
.isStartKeyInclusive(), endRow, false));
this.iter = this.scanner.iterator();
} else {
// Reset the starting range to the last key returned
LOG.debug("Exhausted scanner, waiting {}ms to retry.", delay);
UtilWaitThread.sleep(delay);
this.scanner.setRange(new Range(new Text(Metric.encodeRowKey(m.getMetric(), m.getTimestamp())),
false, endRow, prevRange.isEndKeyInclusive()));
sleepUninterruptibly(delay, TimeUnit.MILLISECONDS);
this.scanner.setRange(new Range(new Text(MetricAdapter.encodeRowKey(m)), false, endRow,
prevRange.isEndKeyInclusive()));
this.iter = this.scanner.iterator();
}
}
@@ -13,9 +13,10 @@ import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.data.Value;
import org.apache.commons.configuration.BaseConfiguration;
import org.springframework.boot.Banner.Mode;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import timely.SpringBootstrap;
import timely.Configuration;
import timely.api.model.Meta;
@@ -24,8 +25,8 @@ public class GetMetricTableSplitPoints {
public static void main(String[] args) throws Exception {
try (ConfigurableApplicationContext ctx = new SpringApplicationBuilder(SpringBootstrap.class).web(false).run(
args)) {
try (ConfigurableApplicationContext ctx = new SpringApplicationBuilder(SpringBootstrap.class)
.bannerMode(Mode.OFF).web(false).run(args)) {
Configuration conf = ctx.getBean(Configuration.class);
final BaseConfiguration apacheConf = new BaseConfiguration();
@@ -1,8 +1,8 @@
package timely.util;
import java.nio.ByteBuffer;
import java.util.Map.Entry;
import org.apache.accumulo.core.client.lexicoder.DoubleLexicoder;
import org.apache.accumulo.core.client.lexicoder.LongLexicoder;
import org.apache.accumulo.core.client.lexicoder.PairLexicoder;
import org.apache.accumulo.core.client.lexicoder.StringLexicoder;
@@ -15,7 +15,6 @@ public class TimelyMetricsFormatter extends DefaultFormatter {
private static final PairLexicoder<String, Long> rowCoder = new PairLexicoder<>(new StringLexicoder(),
new LongLexicoder());
private static final DoubleLexicoder valueCoder = new DoubleLexicoder();
@Override
public String next() {
@@ -34,7 +33,8 @@ public class TimelyMetricsFormatter extends DefaultFormatter {
b.append(e.getKey().getTimestamp());
}
b.append(" ");
b.append(valueCoder.decode(e.getValue().get()));
ByteBuffer.wrap(e.getValue().get());
b.append(ByteBuffer.wrap(e.getValue().get()).getDouble());
return b.toString();
}
@@ -0,0 +1,2 @@
cd src/main/generated-java
flatc --java ../resources/fb/metric.fbs
+21
View File
@@ -0,0 +1,21 @@
namespace timely.api.flatbuffer;
file_identifier "TMFB";
table Tag {
key:string;
value:string;
}
table Metric {
name:string;
timestamp:long;
value:double;
tags:[Tag];
}
table Metrics {
metrics:[Metric];
}
root_type Metrics;
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
<Or>
<Package name="timely.api.flatbuffer"/>
</Or>
<Match>
<Class name="timely.Server" />
<Method name="shutdown" />
<Bug pattern="UC_USELESS_OBJECT" />
</Match>
</FindBugsFilter>
Loaded 100 of 131 files, more files were not shown because too many files have changed in this diff. Show more