Compare commits

...
74 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
Jim Klucar 49a8d970fe minor pom consistency tweaks 2016-08-25 14:18:55 -04:00
brianloss 1be6f24676 Use Spring Configuration (#68)
* Initial pass at converting timely configuration to Spring Boot for type-safe config that is a lot more flexible than standard properties file configuration.

* Change banner color to red.

* Update Configuration class to support fluent API.

* Re-work configuration to group properties in a more sensible manner.

* Use NotBlank everywhere instead of NotEmpty for validations.
2016-08-25 13:19:59 -04:00
Dave Marion 82b94f1a71 fixes #40 - add regex support for lookup requests 2016-08-23 09:26:56 -04:00
Jim Klucar 019c5789ce fixed bug where timely.ssl.trust.store.file property is defined but is empty string 2016-08-05 11:27:43 -04:00
klucar 4336defc14 docker update version 2016-08-05 07:45:56 -04:00
klucar 712a2100bb added instances to metrics 2016-08-05 07:44:57 -04:00
klucar bc46f54604 updated to 0.0.3-SNAPSHOT 2016-08-03 13:54:42 -04:00
Dave Marion 1b713e7874 re #56: fixed some scanner handling, log messages 2016-08-02 10:38:25 -04:00
Dave Marion 3f5dfd2219 fixes #56: Added a Netty handler in the web socket pipeline to get the TSESSIONID cookie value before the web socket upgrade and store it in the channel attribute map. Replaced sessionId property on subscription objects with subscriptionId, which will now allow multiple subscriptions per channel. Modified MetricResponse to contain the subscriptionId in the returned data. Updated tests and example. 2016-08-02 09:29:49 -04:00
Dave Marion ea707fda42 fixes #57, moved plugin/dependency versions to parent pom 2016-08-01 13:02:29 -04:00
klucar b245be476a fixed display name of dashboard 2016-07-28 09:25:24 -04:00
klucar 9619530814 making dashboards available for #59 2016-07-28 09:23:21 -04:00
klucar adf617e59f First cut at #59 2016-07-28 09:20:05 -04:00
Dave Marion 3f49855840 Set version to 0.0.3-SNAPSHOT 2016-07-27 08:23:50 -04:00
173 changed files with 22438 additions and 3376 deletions

No files matched your search

+3
View File
@@ -4,3 +4,6 @@
target/
.idea/
*.iml
logs/
server/pki/
+1
View File
@@ -3,3 +3,4 @@ Eric Newton ([email protected])
Jim Klucar ([email protected])
Charlie Williams ([email protected])
Drew Farris ([email protected])
Brian Loss ([email protected])
+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 -61
View File
@@ -4,21 +4,17 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.2</version>
<version>0.0.3</version>
</parent>
<artifactId>collectd-nsq-plugin</artifactId>
<dependencies>
<dependency>
<groupId>collectd</groupId>
<artifactId>collectd-api</artifactId>
<version>5.5.1</version>
<scope>system</scope>
<systemPath>${collectd-api-jar}</systemPath>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.1</version>
</dependency>
<dependency>
<groupId>timely</groupId>
@@ -39,24 +35,10 @@
<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-shade-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<artifactSet>
<includes>
@@ -77,49 +59,7 @@
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>0.5.2</version>
<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>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<versionRange>[0.5.2,)</versionRange>
<goals>
<goal>format</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
</FindBugsFilter>
+5 -66
View File
@@ -4,21 +4,17 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.2</version>
<version>0.0.3</version>
</parent>
<artifactId>collectd-plugin-parent</artifactId>
<dependencies>
<dependency>
<groupId>collectd</groupId>
<artifactId>collectd-api</artifactId>
<version>5.5.1</version>
<scope>system</scope>
<systemPath>${collectd-api-jar}</systemPath>
</dependency>
<dependency>
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -29,7 +25,6 @@
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-easymock-release-full</artifactId>
<version>1.6.4</version>
<classifier>full</classifier>
<scope>test</scope>
</dependency>
@@ -47,75 +42,19 @@
<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>
<version>2.19</version>
<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>
<version>0.5.2</version>
<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>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<versionRange>[0.5.2,)</versionRange>
<goals>
<goal>format</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
</FindBugsFilter>
+5 -68
View File
@@ -4,21 +4,17 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.2</version>
<version>0.0.3</version>
</parent>
<artifactId>collectd-timely-plugin</artifactId>
<dependencies>
<dependency>
<groupId>collectd</groupId>
<artifactId>collectd-api</artifactId>
<version>5.5.1</version>
<scope>system</scope>
<systemPath>${collectd-api-jar}</systemPath>
</dependency>
<dependency>
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -34,7 +30,6 @@
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-easymock-release-full</artifactId>
<version>1.6.4</version>
<classifier>full</classifier>
<scope>test</scope>
</dependency>
@@ -57,25 +52,10 @@
<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>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<artifactSet>
<includes>
@@ -96,58 +76,15 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<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>
<version>0.5.2</version>
<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>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<versionRange>[0.5.2,)</versionRange>
<goals>
<goal>format</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
+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 -2
View File
@@ -4,14 +4,13 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.2</version>
<version>0.0.3</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>assemble</id>
+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"]}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,786 @@
{
"__inputs": [
{
"name": "DS_TIMELY",
"label": "Timely",
"description": "",
"type": "datasource",
"pluginId": "timely-datasource",
"pluginName": "Timely"
}
],
"__requires": [
{
"type": "panel",
"id": "singlestat",
"name": "Singlestat",
"version": ""
},
{
"type": "panel",
"id": "graph",
"name": "Graph",
"version": ""
},
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "3.1.0"
},
{
"type": "datasource",
"id": "timely-datasource",
"name": "Timely",
"version": "1.0.0"
}
],
"id": null,
"title": "Timely Status",
"tags": [],
"style": "dark",
"timezone": "browser",
"editable": true,
"hideControls": false,
"sharedCrosshair": false,
"rows": [
{
"collapse": false,
"editable": true,
"height": "150",
"panels": [
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"format": "none",
"gauge": {
"maxValue": 100000,
"minValue": 0,
"show": true,
"thresholdLabels": false,
"thresholdMarkers": false
},
"height": "150",
"hideTimeOverride": true,
"id": 8,
"interval": null,
"isNew": true,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "count",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.metrics.received",
"refId": "A"
}
],
"thresholds": "",
"timeFrom": null,
"timeShift": "1m",
"title": "Metrics Received Last Minute",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "avg"
},
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"height": "150",
"hideTimeOverride": true,
"id": 9,
"interval": null,
"isNew": true,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "count",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "count",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.queue_length",
"refId": "A",
"tags": {}
}
],
"thresholds": "",
"timeShift": "1m",
"title": "CollectD Instances Reporting",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "avg"
},
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"height": "150",
"hideTimeOverride": true,
"id": 10,
"interval": null,
"isNew": true,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.derive.dropped",
"refId": "A",
"tags": {}
}
],
"thresholds": "",
"timeShift": "1m",
"title": "Metrics Dropped By CollectD",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "avg"
}
],
"title": "New row"
},
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 3,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.keys.metric.inserted",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Metrics Inserted",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "none",
"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": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 4,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.keys.meta.inserted",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Meta Inserted",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "none",
"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": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 5,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.metrics.received",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Metrics Received",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "none",
"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"
},
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 7,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"alias": "$tag_host",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.cache_size",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CollectD Cache Sizes",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"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": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 11,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"alias": "$tag_host",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.queue_length",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CollectD Queue Length",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"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-1h",
"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": "1m",
"schemaVersion": 12,
"version": 8,
"links": [],
"gnetId": null
}
@@ -7,8 +7,8 @@
}
],
"id": null,
"title": "${DS_NAME} - Status",
"originalTitle": "${DS_NAME} - Status",
"title": "Timely Standalone Demo",
"originalTitle": "Timely Standalone Demo",
"tags": ["imported"],
"style": "dark",
"timezone": "browser",
@@ -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"]}
+5 -1
View File
@@ -8,7 +8,11 @@
"annotations": true,
"includes": [
{"type": "dashboard", "name": "Timely Metrics", "path": "dashboards/standalone_test.json"}
{"type": "dashboard", "name": "Timely Standalone Test", "path": "dashboards/standalone_test.json"},
{"type": "dashboard", "name": "Accumulo Overview", "path": "dashboards/AccumuloOverview.json"},
{"type": "dashboard", "name": "Hadoop Overview", "path": "dashboards/HadoopOverview.json"},
{"type": "dashboard", "name": "System Overview", "path": "dashboards/SystemOverview.json"},
{"type": "dashboard", "name": "Timely Status", "path": "dashboards/TimelyStatus.json"}
],
"info": {
+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"
},
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,786 @@
{
"__inputs": [
{
"name": "DS_TIMELY",
"label": "Timely",
"description": "",
"type": "datasource",
"pluginId": "timely-datasource",
"pluginName": "Timely"
}
],
"__requires": [
{
"type": "panel",
"id": "singlestat",
"name": "Singlestat",
"version": ""
},
{
"type": "panel",
"id": "graph",
"name": "Graph",
"version": ""
},
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "3.1.0"
},
{
"type": "datasource",
"id": "timely-datasource",
"name": "Timely",
"version": "1.0.0"
}
],
"id": null,
"title": "Timely Status",
"tags": [],
"style": "dark",
"timezone": "browser",
"editable": true,
"hideControls": false,
"sharedCrosshair": false,
"rows": [
{
"collapse": false,
"editable": true,
"height": "150",
"panels": [
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"format": "none",
"gauge": {
"maxValue": 100000,
"minValue": 0,
"show": true,
"thresholdLabels": false,
"thresholdMarkers": false
},
"height": "150",
"hideTimeOverride": true,
"id": 8,
"interval": null,
"isNew": true,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "count",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.metrics.received",
"refId": "A"
}
],
"thresholds": "",
"timeFrom": null,
"timeShift": "1m",
"title": "Metrics Received Last Minute",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "avg"
},
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"height": "150",
"hideTimeOverride": true,
"id": 9,
"interval": null,
"isNew": true,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "count",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "count",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.queue_length",
"refId": "A",
"tags": {}
}
],
"thresholds": "",
"timeShift": "1m",
"title": "CollectD Instances Reporting",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "avg"
},
{
"cacheTimeout": null,
"colorBackground": false,
"colorValue": false,
"colors": [
"rgba(245, 54, 54, 0.9)",
"rgba(237, 129, 40, 0.89)",
"rgba(50, 172, 45, 0.97)"
],
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"format": "none",
"gauge": {
"maxValue": 100,
"minValue": 0,
"show": false,
"thresholdLabels": false,
"thresholdMarkers": true
},
"height": "150",
"hideTimeOverride": true,
"id": 10,
"interval": null,
"isNew": true,
"links": [],
"mappingType": 1,
"mappingTypes": [
{
"name": "value to text",
"value": 1
},
{
"name": "range to text",
"value": 2
}
],
"maxDataPoints": 100,
"nullPointMode": "connected",
"nullText": null,
"postfix": "",
"postfixFontSize": "50%",
"prefix": "",
"prefixFontSize": "50%",
"rangeMaps": [
{
"from": "null",
"text": "N/A",
"to": "null"
}
],
"span": 4,
"sparkline": {
"fillColor": "rgba(31, 118, 189, 0.18)",
"full": false,
"lineColor": "rgb(31, 120, 193)",
"show": false
},
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.derive.dropped",
"refId": "A",
"tags": {}
}
],
"thresholds": "",
"timeShift": "1m",
"title": "Metrics Dropped By CollectD",
"transparent": true,
"type": "singlestat",
"valueFontSize": "80%",
"valueMaps": [
{
"op": "=",
"text": "N/A",
"value": "null"
}
],
"valueName": "avg"
}
],
"title": "New row"
},
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 3,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.keys.metric.inserted",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Metrics Inserted",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "none",
"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": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 4,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "avg",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.keys.meta.inserted",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Meta Inserted",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "none",
"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": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 5,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 4,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "timely.metrics.received",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "Timely Metrics Received",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "none",
"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"
},
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 7,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"alias": "$tag_host",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.cache_size",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CollectD Cache Sizes",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"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": "${DS_TIMELY}",
"editable": true,
"error": false,
"fill": 0,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 11,
"isNew": true,
"legend": {
"avg": false,
"current": false,
"max": false,
"min": false,
"show": true,
"total": false,
"values": false
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 6,
"stack": false,
"steppedLine": false,
"targets": [
{
"aggregator": "sum",
"alias": "$tag_host",
"currentTagKey": "",
"currentTagValue": "",
"downsampleAggregator": "sum",
"downsampleFillPolicy": "none",
"downsampleInterval": "1m",
"metric": "sys.collectd.queue_length",
"refId": "A",
"tags": {
"host": ".*"
}
}
],
"timeFrom": null,
"timeShift": null,
"title": "CollectD Queue Length",
"tooltip": {
"msResolution": true,
"shared": true,
"sort": 0,
"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-1h",
"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": "1m",
"schemaVersion": 12,
"version": 8,
"links": [],
"gnetId": null
}
@@ -7,8 +7,8 @@
}
],
"id": null,
"title": "${DS_NAME} - Status",
"originalTitle": "${DS_NAME} - Status",
"title": "Timely Standalone Demo",
"originalTitle": "Timely Standalone Demo",
"tags": ["imported"],
"style": "dark",
"timezone": "browser",
@@ -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(",");
@@ -8,7 +8,11 @@
"annotations": true,
"includes": [
{"type": "dashboard", "name": "Timely Metrics", "path": "dashboards/standalone_test.json"}
{"type": "dashboard", "name": "Timely Standalone Test", "path": "dashboards/standalone_test.json"},
{"type": "dashboard", "name": "Accumulo Overview", "path": "dashboards/AccumuloOverview.json"},
{"type": "dashboard", "name": "Hadoop Overview", "path": "dashboards/HadoopOverview.json"},
{"type": "dashboard", "name": "System Overview", "path": "dashboards/SystemOverview.json"},
{"type": "dashboard", "name": "Timely Status", "path": "dashboards/TimelyStatus.json"}
],
"info": {
+265 -13
View File
@@ -3,9 +3,28 @@
<modelVersion>4.0.0</modelVersion>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.2</version>
<version>0.0.3</version>
<packaging>pom</packaging>
<name>Timely</name>
<description>A secure and scalable time series database based on Apache Accumulo</description>
<licenses>
<license>
<name>Apache License, Version 2.1</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<scm>
<connection>scm:git:https://github.com/NationalSecurityAgency/timely.git</connection>
<developerConnection>scm:git:[email protected]:NationalSecurityAgency/timely.git</developerConnection>
<url>https://github.com/NationalSecurityAgency/timely</url>
</scm>
<issueManagement>
<system>GitHub</system>
<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>
@@ -18,25 +37,58 @@
<os.detection.classifierWithLikes>fedora</os.detection.classifierWithLikes>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- dependency versions -->
<collectd-api-jar>/usr/share/collectd/java/collectd-api.jar</collectd-api-jar>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<version.accumulo>1.7.0</version.accumulo>
<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.junit>4.11</version.junit>
<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.security>4.0.4.RELEASE</version.security>
<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>
<version.os-maven>1.5.0.Final</version.os-maven>
<version.maven-pmd>3.6</version.maven-pmd>
<version.maven-rpm>2.1.4</version.maven-rpm>
<version.maven-shade>2.4.2</version.maven-shade>
<version.maven-surefire>2.19.1</version.maven-surefire>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>collectd</groupId>
<artifactId>collectd-api</artifactId>
<version>${version.collectd}</version>
<scope>system</scope>
<systemPath>${collectd-api-jar}</systemPath>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
@@ -61,6 +113,27 @@
<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>
<artifactId>disruptor</artifactId>
<version>${version.disruptor}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
@@ -73,6 +146,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.github.lukehutch</groupId>
<artifactId>fast-classpath-scanner</artifactId>
<version>${version.fast-classpath-scanner}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
@@ -84,6 +162,17 @@
<version>${version.junit}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<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>
@@ -184,6 +273,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${version.httpcomponents}</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
@@ -191,47 +285,133 @@
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${version.security}</version>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${version.jsoup}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${version.security}</version>
</dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-easymock-release-full</artifactId>
<version>${version.powermock}</version>
<classifier>full</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${version.slf4j}</version>
</dependency>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring-boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>${version.formatter}</version>
<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>
<version>${version.maven-assembly}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<version>${version.maven-compiler}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${version.maven-dependency}</version>
</plugin>
<plugin>
<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>3.0.2</version>
<version>${version.maven-jar}</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${version.maven-shade}</version>
</plugin>
<plugin>
<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>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.3</version>
<version>${version.findbugs-maven}</version>
<configuration>
<effort>Max</effort>
<threshold>Medium</threshold>
<xmlOutput>true</xmlOutput>
<excludeFilterFile>src/main/resources/findbugs-excludes.xml</excludeFilterFile>
</configuration>
<executions>
<execution>
@@ -242,6 +422,78 @@
</execution>
</executions>
</plugin>
<plugin>
<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>
<artifactId>rpm-maven-plugin</artifactId>
<version>${version.maven-rpm}</version>
</plugin>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>${version.eclipse-lifecycle}</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<versionRange>[0.5.2,)</versionRange>
<goals>
<goal>format</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<versionRange>[2.10,)</versionRange>
<goals>
<goal>copy-dependencies</goal>
<goal>unpack</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
+12 -5
View File
@@ -3,15 +3,22 @@ FROM centos:centos7
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
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-1.8.0.91-1.b14.el7_2.x86_64
ENV JAVA_HOME /usr/lib/jvm/java-1.8.0-openjdk
EXPOSE 9804 54321 54322
ENV TIMELY_VERSION 0.0.2-SNAPSHOT
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": []
}
}
+5 -4
View File
@@ -9,12 +9,13 @@ fi
THIS_DIR="${THIS_SCRIPT%/*}"
BASE_DIR=${THIS_DIR}/..
CONF_DIR="${BASE_DIR}/conf"
CONF_FILE="${CONF_DIR}/timely.properties"
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 "${CONF_FILE}""
$JAVA_HOME/bin/java ${JVM_ARGS} timely.util.GetMetricTableSplitPoints "${CONF_FILE}"
echo "$JAVA_HOME/bin/java ${JVM_ARGS} timely.util.GetMetricTableSplitPoints --spring.config.name=timely"
$JAVA_HOME/bin/java ${JVM_ARGS} timely.util.GetMetricTableSplitPoints --spring.config.name=timely
+2 -3
View File
@@ -8,10 +8,9 @@ fi
THIS_DIR="${THIS_SCRIPT%/*}"
BASE_DIR=${THIS_DIR}/..
CONF_DIR="${BASE_DIR}/conf"
CONF_FILE="${CONF_DIR}/timely.properties"
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"
@@ -34,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 -3
View File
@@ -8,10 +8,9 @@ fi
THIS_DIR="${THIS_SCRIPT%/*}"
BASE_DIR=${THIS_DIR}/..
CONF_DIR="${BASE_DIR}/conf"
CONF_FILE="${CONF_DIR}/timely.properties"
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"
@@ -34,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}
+3 -4
View File
@@ -18,7 +18,6 @@ NATIVE_DIR="${THIS_DIR}/META-INF/native"
BASE_DIR=${THIS_DIR}/..
TMP_DIR="${BASE_DIR}/tmp"
CONF_DIR="${BASE_DIR}/conf"
CONF_FILE="${CONF_DIR}/timely.properties"
LIB_DIR="${BASE_DIR}/lib"
NUM_SERVER_THREADS=4
@@ -37,10 +36,10 @@ $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}"
echo "$JAVA_HOME/bin/java ${JVM_ARGS} timely.Server "${CONF_FILE}""
$JAVA_HOME/bin/java ${JVM_ARGS} timely.Server "${CONF_FILE}"
echo "$JAVA_HOME/bin/java ${JVM_ARGS} timely.Server --spring.config.name=timely"
$JAVA_HOME/bin/java ${JVM_ARGS} timely.Server --spring.config.name=timely
+3 -4
View File
@@ -18,7 +18,6 @@ NATIVE_DIR="${THIS_DIR}/META-INF/native"
BASE_DIR=${THIS_DIR}/..
TMP_DIR="${BASE_DIR}/tmp"
CONF_DIR="${BASE_DIR}/conf"
CONF_FILE="${CONF_DIR}/timely-standalone.properties"
LIB_DIR="${BASE_DIR}/lib"
NUM_SERVER_THREADS=4
@@ -37,12 +36,12 @@ $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
#JVM_ARGS="${JVM_ARGS} -agentlib:jdwp=transport=dt_socket,address=54323,server=y,suspend=y"
echo "$JAVA_HOME/bin/java ${JVM_ARGS} timely.StandaloneServer "${CONF_FILE}" "${TMP_DIR}""
$JAVA_HOME/bin/java ${JVM_ARGS} timely.StandaloneServer "${CONF_FILE}" "${TMP_DIR}"
echo "$JAVA_HOME/bin/java ${JVM_ARGS} timely.StandaloneServer "${TMP_DIR}" --spring.config.name=timely --spring.profiles.active=standalone"
$JAVA_HOME/bin/java ${JVM_ARGS} timely.StandaloneServer "${TMP_DIR}" --spring.config.name=timely --spring.profiles.active=standalone
+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
-39
View File
@@ -1,39 +0,0 @@
timely.ip=0.0.0.0
timely.port.put=54321
timely.port.query=54322
timely.port.websocket=54323
timely.instance_name=TimelyStandalone
timely.zookeepers=127.0.0.1:9804
timely.username=root
timely.password=secret
timely.table=timely.metrics
timely.meta=timely.meta
timely.write.latency=5s
timely.write.threads=3
timely.write.buffer.size=52428800
timely.metric.age.off.days=7
timely.cors.allow.any.origin=true
timely.cors.allow.null.origin=false
timely.cors.allowed.origins=
timely.cors.allowed.methods=DELETE,GET,HEAD,OPTIONS,PUT,POST
timely.cors.allowed.headers=content-type
timely.cors.allow.credentials=true
timely.scanner.threads=4
timely.metrics.report.tags.ignored=
timely.meta.cache.expiration.minutes=60
timely.meta.cache.initial.capacity=2000
timely.meta.cache.max.capacity=10000
timely.ssl.certificate.file=/timely-server-src/bin/docker/grafana/pki/timely-cert.pem
timely.ssl.key.file=/timely-server-src/bin/docker/grafana/pki/timely-pkcs8-key.pem
timely.ssl.key.pass=timely
timely.ssl.use.generated.keypair=false
timely.ssl.trust.store.file=/timely-server-src/bin/docker/grafana/pki/timely-ca.pem
timely.ssl.use.openssl=true
#timely.ssl.use.ciphers=
timely.session.max.age=86400
timely.http.host=localhost
timely.allow.anonymous.access=true
timely.web.socket.timeout=60
timely.ws.subscription.lag=120
timely.http.redirect.path=/secure-me
timely.hsts.max.age=608400
+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:
key-file:
key-password: timely
use-generated-keypair: true
trust-store-file:
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
-39
View File
@@ -1,39 +0,0 @@
timely.ip=
timely.port.put=
timely.port.query=
timely.port.websocket=
timely.instance_name=
timely.zookeepers=
timely.username=
timely.password=
timely.table=timely.metrics
timely.meta=timely.meta
timely.write.latency=5s
timely.write.threads=3
timely.write.buffer.size=52428800
timely.metric.age.off.days=7
timely.cors.allow.any.origin=false
timely.cors.allow.null.origin=false
timely.cors.allowed.origins=
timely.cors.allowed.methods=DELETE,GET,HEAD,OPTIONS,PUT,POST
timely.cors.allowed.headers=content-type
timely.cors.allow.credentials=true
timely.scanner.threads=4
timely.metrics.report.tags.ignored=
timely.meta.cache.expiration.minutes=60
timely.meta.cache.initial.capacity=2000
timely.meta.cache.max.capacity=10000
timely.ssl.certificate.file=
timely.ssl.key.file=
timely.ssl.key.pass=
timely.ssl.use.generated.keypair=false
timely.ssl.trust.store.file=
timely.ssl.use.openssl=true
timely.ssl.use.ciphers=
timely.session.max.age=86400
timely.http.host=
timely.allow.anonymous.access=false
timely.web.socket.timeout=60
timely.ws.subscription.lag=120
timely.http.redirect.path=/secure-me
timely.hsts.max.age=608400
+58
View File
@@ -0,0 +1,58 @@
timely:
metrics-table: timely.metrics
meta-table: timely.meta
metric-age-off-days:
default: 7
metrics-report-ignored-tags:
accumulo:
instance-name:
zookeepers:
username:
password:
write:
latency: 5s
threads: 3
bufferSize: 52428800
scan:
threads: 4
security:
session-max-age: 86400
allow-anonymous-access: false
ssl:
certificate-file:
key-file:
key-password:
use-generated-keypair: false
trust-store-file:
use-openssl: true
#use-ciphers:
server:
ip:
tcp-port:
udp-port:
http:
host:
ip:
port:
redirect-path: /secure-me
strict-transport-max-age: 608400
cors:
allow-any-origin: false
allow-null-origin: false
allow-credentials: true
allowed-origins:
allowed-methods: DELETE,GET,HEAD,OPTIONS,PUT,POST
allowed-headers: content-type
websocket:
ip:
port:
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
+4 -2
View File
@@ -11,7 +11,7 @@ services:
- ${PWD}/:/timely-server-src
command: /timely-server-src/bin/docker/deploy-startup-standalone.sh
environment:
- TIMELY_VERSION=0.0.2-SNAPSHOT
- TIMELY_VERSION=0.0.3-SNAPSHOT
ingest:
image: timely
entrypoint: /timely-server-src/bin/docker/deploy-wait-and-insert.sh
@@ -22,6 +22,7 @@ services:
environment:
- TIMELY_HOST=timely
- TIMELY_PORT=54321
- TIMELY_VERSION=0.0.3-SNAPSHOT
grafana:
image: grafana/grafana
ports:
@@ -29,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
@@ -39,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.
+74 -215
View File
@@ -5,9 +5,20 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>0.0.2</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,20 +39,28 @@
<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>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.github.lukehutch</groupId>
<artifactId>fast-classpath-scanner</artifactId>
<version>1.10.4</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
@@ -88,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>
@@ -115,6 +138,34 @@
<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>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test-autoconfigure</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
@@ -134,14 +185,12 @@
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>assemble</id>
@@ -161,7 +210,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
@@ -200,241 +248,53 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19</version>
<configuration>
<argLine>${failsafeArgLine} -Djava.library.path=${project.build.dir}/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>
<version>2.19</version>
<configuration>
<argLine>${sureFireArgLine} -Djava.library.path=${project.build.dir}/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>
<version>0.7.6.201602180812</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>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>0.5.2</version>
<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>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings
only. It has no influence on the Maven build itself. -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>net.revelc.code</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<versionRange>[0.5.2,)</versionRange>
<goals>
<goal>format</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<versionRange>[2.10,)</versionRange>
<goals>
<goal>copy-dependencies</goal>
<goal>unpack</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>rpm</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>rpm-maven-plugin</artifactId>
<version>2.1.4</version>
<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>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.3</version>
<version>${version.findbugs-maven}</version>
<configuration>
<effort>Max</effort>
<threshold>Medium</threshold>
@@ -443,7 +303,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.6</version>
<configuration>
<targetJdk>1.8</targetJdk>
</configuration>
@@ -451,7 +310,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.6.201602180812</version>
<version>${version.jacoco}</version>
<reportSets>
<reportSet>
<id>JaCoCo Unit Test Coverage</id>
@@ -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;
}
}
+608 -166
View File
@@ -1,196 +1,638 @@
package timely;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.apache.accumulo.core.client.BatchWriterConfig;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
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 com.google.common.collect.Lists;
@Component
@ConfigurationProperties(prefix = "timely")
public class Configuration {
public static final String IP = "timely.ip";
public static final String PUT_PORT = "timely.port.put";
public static final String QUERY_PORT = "timely.port.query";
public static final String WEBSOCKET_PORT = "timely.port.websocket";
public static final String ZOOKEEPERS = "timely.zookeepers";
public static final String INSTANCE_NAME = "timely.instance_name";
public static final String USERNAME = "timely.username";
public static final String PASSWORD = "timely.password";
public static final String METRICS_TABLE = "timely.table";
private static final String METRICS_TABLE_DEFAULT = "timely.metrics";
public static final String META_TABLE = "timely.meta";
private static final String META_TABLE_DEFAULT = "timely.meta";
public static final String METRICS_AGEOFF_DAYS = "timely.metric.age.off.days";
private static final String METRICS_AGEOFF_DAYS_DEFAULT = "7";
private String metricsTable = "timely.metrics";
private String metaTable = "timely.meta";
private HashMap<String, Integer> metricAgeOffDays = new HashMap<>();
private List<String> metricsReportIgnoredTags = new ArrayList<>();
public static final String MAX_LATENCY = "timely.write.latency";
private static final String MAX_LATENCY_DEFAULT = "5s";
public static final String WRITE_THREADS = "timely.write.threads";
public static final String WRITE_BUFFER_SIZE = "timely.write.buffer.size";
public static final String SCANNER_THREADS = "timely.scanner.threads";
public static final String CORS_ALLOW_ANY_ORIGIN = "timely.cors.allow.any.origin";
private static final String CORS_ALLOW_ANY_ORIGIN_DEFAULT = "false";
public static final String CORS_ALLOW_NULL_ORIGIN = "timely.cors.allow.null.origin";
private static final String CORS_ALLOW_NULL_ORIGIN_DEFAULT = "false";
public static final String CORS_ALLOWED_ORIGINS = "timely.cors.allowed.origins";
private static final String CORS_ALLOWED_ORIGINS_DEFAULT = "";
public static final String CORS_ALLOWED_METHODS = "timely.cors.allowed.methods";
private static final String CORS_ALLOWED_METHODS_DEFAULT = "DELETE,GET,HEAD,OPTIONS,PUT,POST";
public static final String CORS_ALLOWED_HEADERS = "timely.cors.allowed.headers";
private static final String CORS_ALLOWED_HEADERS_DEFAULT = "content-type";
public static final String CORS_ALLOW_CREDENTIALS = "timely.cors.allow.credentials";
private static final String CORS_ALLOW_CREDENTIALS_DEFAULT = "true";
public static final String METRICS_IGNORED_TAGS = "timely.metrics.report.tags.ignored";
public static final String META_CACHE_EXPIRATION = "timely.meta.cache.expiration.minutes";
public static final Long META_CACHE_EXPIRATION_DEFAULT = 60L;
public static final String META_CACHE_INITIAL_CAPACITY = "timely.meta.cache.initial.capacity";
public static final Integer META_CACHE_INITIAL_CAPACITY_DEFAULT = 2000;
public static final String META_CACHE_MAX_CAPACITY = "timely.meta.cache.max.capacity";
public static final Integer META_CACHE_MAX_CAPACITY_DEFAULT = 10000;
public static final String VISIBILITY_CACHE_EXPIRATION = "timely.visibility.cache.expiration.minutes";
public static final Long VISIBILITY_EXPIRATION_DEFAULT = 60L;
public static final String VISIBILITY_CACHE_INITIAL_CAPACITY = "timely.visibility.cache.initial.capacity";
public static final Integer VISIBILITY_CACHE_INITIAL_CAPACITY_DEFAULT = 2000;
public static final String VISIBILITY_CACHE_MAX_CAPACITY = "timely.visibility.cache.max.capacity";
public static final Integer VISIBILITY_CACHE_MAX_CAPACITY_DEFAULT = 10000;
/** Security properties */
public static final String SSL_CERTIFICATE_FILE = "timely.ssl.certificate.file";
public static final String SSL_PRIVATE_KEY_FILE = "timely.ssl.key.file";
public static final String SSL_PRIVATE_KEY_PASS = "timely.ssl.key.pass";
public static final String SSL_USE_GENERATED_KEYPAIR = "timely.ssl.use.generated.keypair";
private static final String SSL_USE_GENERATED_KEYPAIR_DEFAULT = "false";
public static final String SSL_TRUST_STORE_FILE = "timely.ssl.trust.store.file";
public static final String SSL_USE_OPENSSL = "timely.ssl.use.openssl";
private static final String SSL_USE_OPENSSL_DEFAULT = "true";
public static final String SSL_USE_CIPHERS = "timely.ssl.use.ciphers";
private static final String SSL_USE_CIPHERS_DEFAULT = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:"
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:TLS_RSA_WITH_AES_128_GCM_SHA256:"
+ "TLS_RSA_WITH_AES_128_CBC_SHA:SSL_RSA_WITH_3DES_EDE_CBC_SHA";
public static final String SESSION_MAX_AGE = "timely.session.max.age";
public static final long SESSION_MAX_AGE_DEFAULT = 86400;
public static final String TIMELY_HTTP_HOST = "timely.http.host";
public static final String ALLOW_ANONYMOUS_ACCESS = "timely.allow.anonymous.access";
private static final String ALLOW_ANONYMOUS_ACCESS_DEFAULT = "false";
public static final String WS_TIMEOUT_SECONDS = "timely.web.socket.timeout";
private static final String WS_TIMEOUT_SECONDS_DEFAULT = "60";
public static final String WS_SUBSCRIPTION_LAG = "timely.ws.subscription.lag";
private static final String WS_SUBSCRIPTION_LAG_DEFAULT = "120";
public static final String NON_SECURE_REDIRECT_PATH = "timely.http.redirect.path";
private static final String NON_SECURE_REDIRECT_PATH_DEFAULT = "/secure-me";
public static final String STRICT_TRANSPORT_MAX_AGE = "timely.hsts.max.age";
private static final String STRICT_TRANSPORT_MAX_AGE_DEFAULT = "604800";
private static final List<String> REQUIRED_PROPERTIES = new ArrayList<>();
static {
REQUIRED_PROPERTIES.add(IP);
REQUIRED_PROPERTIES.add(PUT_PORT);
REQUIRED_PROPERTIES.add(QUERY_PORT);
REQUIRED_PROPERTIES.add(WEBSOCKET_PORT);
REQUIRED_PROPERTIES.add(ZOOKEEPERS);
REQUIRED_PROPERTIES.add(INSTANCE_NAME);
REQUIRED_PROPERTIES.add(USERNAME);
REQUIRED_PROPERTIES.add(PASSWORD);
REQUIRED_PROPERTIES.add(TIMELY_HTTP_HOST);
};
private final Properties props = new Properties();
public Configuration(Path path) throws IOException {
org.apache.hadoop.conf.Configuration hadoopConf = new org.apache.hadoop.conf.Configuration();
try (FileSystem fs = FileSystem.get(hadoopConf)) {
try (InputStream inputStream = fs.open(path)) {
init(inputStream);
}
}
@Valid
@NestedConfigurationProperty
private Accumulo accumulo = new Accumulo();
@Valid
@NestedConfigurationProperty
private Security security = new Security();
@Valid
@NestedConfigurationProperty
private Server server = new Server();
@Valid
@NestedConfigurationProperty
private Http http = new Http();
@Valid
@NestedConfigurationProperty
private MetaCache metaCache = new MetaCache();
@Valid
@NestedConfigurationProperty
private VisibilityCache visibilityCache = new VisibilityCache();
@Valid
@NestedConfigurationProperty
private Websocket websocket = new Websocket();
public String getMetricsTable() {
return metricsTable;
}
public Configuration(File conf) throws IOException {
try (InputStream inputStream = new FileInputStream(conf)) {
init(inputStream);
public Configuration setMetricsTable(String metricsTable) {
this.metricsTable = metricsTable;
return this;
}
public String getMetaTable() {
return metaTable;
}
public Configuration setMetaTable(String metaTable) {
this.metaTable = metaTable;
return this;
}
public HashMap<String, Integer> getMetricAgeOffDays() {
return metricAgeOffDays;
}
public void setMetricAgeOffDays(HashMap<String, Integer> metricAgeOffDays) {
this.metricAgeOffDays = metricAgeOffDays;
}
public List<String> getMetricsReportIgnoredTags() {
return metricsReportIgnoredTags;
}
public Configuration setMetricsReportIgnoredTags(List<String> metricsReportIgnoredTags) {
this.metricsReportIgnoredTags = metricsReportIgnoredTags;
return this;
}
public Accumulo getAccumulo() {
return accumulo;
}
public Security getSecurity() {
return security;
}
public Server getServer() {
return server;
}
public Http getHttp() {
return http;
}
public Websocket getWebsocket() {
return websocket;
}
public MetaCache getMetaCache() {
return metaCache;
}
public VisibilityCache getVisibilityCache() {
return visibilityCache;
}
public class Accumulo {
@NotBlank
private String zookeepers;
@NotBlank
private String instanceName;
@NotBlank
private String username;
@NotBlank
private String password;
@Valid
@NestedConfigurationProperty
private Write write = new Write();
@Valid
@NestedConfigurationProperty
private Scan scan = new Scan();
public String getInstanceName() {
return instanceName;
}
public String getZookeepers() {
return zookeepers;
}
public Configuration setZookeepers(String zookeepers) {
this.zookeepers = zookeepers;
return Configuration.this;
}
public Write getWrite() {
return write;
}
public Scan getScan() {
return scan;
}
public Configuration setInstanceName(String instanceName) {
this.instanceName = instanceName;
return Configuration.this;
}
public String getUsername() {
return username;
}
public Configuration setUsername(String username) {
this.username = username;
return Configuration.this;
}
public String getPassword() {
return password;
}
public Configuration setPassword(String password) {
this.password = password;
return Configuration.this;
}
}
private void init(InputStream configStream) throws IOException {
// Add defaults
props.setProperty(METRICS_TABLE, METRICS_TABLE_DEFAULT);
props.setProperty(META_TABLE, META_TABLE_DEFAULT);
props.setProperty(MAX_LATENCY, MAX_LATENCY_DEFAULT);
props.setProperty(METRICS_AGEOFF_DAYS, METRICS_AGEOFF_DAYS_DEFAULT);
final BatchWriterConfig defaults = new BatchWriterConfig();
props.setProperty(WRITE_BUFFER_SIZE, "" + defaults.getMaxMemory());
props.setProperty(WRITE_THREADS, "" + defaults.getMaxWriteThreads());
props.setProperty(SCANNER_THREADS, "" + 4);
props.setProperty(CORS_ALLOW_ANY_ORIGIN, CORS_ALLOW_ANY_ORIGIN_DEFAULT);
props.setProperty(CORS_ALLOW_NULL_ORIGIN, CORS_ALLOW_NULL_ORIGIN_DEFAULT);
props.setProperty(CORS_ALLOWED_ORIGINS, CORS_ALLOWED_ORIGINS_DEFAULT);
props.setProperty(CORS_ALLOWED_METHODS, CORS_ALLOWED_METHODS_DEFAULT);
props.setProperty(CORS_ALLOWED_HEADERS, CORS_ALLOWED_HEADERS_DEFAULT);
props.setProperty(CORS_ALLOW_CREDENTIALS, CORS_ALLOW_CREDENTIALS_DEFAULT);
props.setProperty(META_CACHE_EXPIRATION, "" + META_CACHE_EXPIRATION_DEFAULT);
props.setProperty(META_CACHE_INITIAL_CAPACITY, "" + META_CACHE_INITIAL_CAPACITY_DEFAULT);
props.setProperty(META_CACHE_MAX_CAPACITY, "" + META_CACHE_MAX_CAPACITY_DEFAULT);
props.setProperty(SSL_USE_GENERATED_KEYPAIR, SSL_USE_GENERATED_KEYPAIR_DEFAULT);
props.setProperty(SSL_USE_OPENSSL, SSL_USE_OPENSSL_DEFAULT);
props.setProperty(SSL_USE_CIPHERS, SSL_USE_CIPHERS_DEFAULT);
props.setProperty(ALLOW_ANONYMOUS_ACCESS, ALLOW_ANONYMOUS_ACCESS_DEFAULT);
props.setProperty(SESSION_MAX_AGE, SESSION_MAX_AGE_DEFAULT + "");
public class Write {
props.setProperty(VISIBILITY_CACHE_EXPIRATION, VISIBILITY_EXPIRATION_DEFAULT + "");
props.setProperty(VISIBILITY_CACHE_INITIAL_CAPACITY, VISIBILITY_CACHE_INITIAL_CAPACITY_DEFAULT + "");
props.setProperty(VISIBILITY_CACHE_MAX_CAPACITY, VISIBILITY_CACHE_MAX_CAPACITY_DEFAULT + "");
private String latency = "5s";
private int threads;
private String bufferSize;
props.setProperty(WS_TIMEOUT_SECONDS, WS_TIMEOUT_SECONDS_DEFAULT);
props.setProperty(WS_SUBSCRIPTION_LAG, WS_SUBSCRIPTION_LAG_DEFAULT);
public Write() {
BatchWriterConfig config = new BatchWriterConfig();
threads = config.getMaxWriteThreads();
bufferSize = Long.toString(config.getMaxMemory());
}
props.setProperty(NON_SECURE_REDIRECT_PATH, NON_SECURE_REDIRECT_PATH_DEFAULT);
props.setProperty(STRICT_TRANSPORT_MAX_AGE, STRICT_TRANSPORT_MAX_AGE_DEFAULT);
public String getLatency() {
return latency;
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(configStream, StandardCharsets.UTF_8))) {
props.load(reader);
validate();
public Configuration setLatency(String latency) {
this.latency = latency;
return Configuration.this;
}
public int getThreads() {
return threads;
}
public Configuration setThreads(int threads) {
this.threads = threads;
return Configuration.this;
}
public String getBufferSize() {
return bufferSize;
}
public Configuration setBufferSize(String bufferSize) {
this.bufferSize = bufferSize;
return Configuration.this;
}
}
protected void validate() {
REQUIRED_PROPERTIES.forEach(p -> {
if (!props.containsKey(p) || StringUtils.isEmpty(props.getProperty(p))) {
throw new IllegalArgumentException("Required property " + p + " must be specified.");
}
});
if (!getBoolean(Configuration.SSL_USE_GENERATED_KEYPAIR)) {
if (StringUtils.isEmpty(get(Configuration.SSL_CERTIFICATE_FILE))) {
throw new IllegalArgumentException(Configuration.SSL_CERTIFICATE_FILE + "must be specified.");
}
if (StringUtils.isEmpty(get(Configuration.SSL_PRIVATE_KEY_FILE))) {
throw new IllegalArgumentException(Configuration.SSL_PRIVATE_KEY_FILE + "must be specified.");
}
public class Scan {
private int threads = 4;
public int getThreads() {
return threads;
}
public Configuration setThreads(int threads) {
this.threads = threads;
return Configuration.this;
}
}
public String get(String property) {
return props.getProperty(property);
public class Security {
private boolean allowAnonymousAccess = false;
private int sessionMaxAge = 86400;
@Valid
@NestedConfigurationProperty
private Ssl ssl = new Ssl();
public boolean isAllowAnonymousAccess() {
return allowAnonymousAccess;
}
public Configuration setAllowAnonymousAccess(boolean allowAnonymousAccess) {
this.allowAnonymousAccess = allowAnonymousAccess;
return Configuration.this;
}
public int getSessionMaxAge() {
return sessionMaxAge;
}
public Configuration setSessionMaxAge(int sessionMaxAge) {
this.sessionMaxAge = sessionMaxAge;
return Configuration.this;
}
public Ssl getSsl() {
return ssl;
}
}
public boolean getBoolean(String property) {
return Boolean.parseBoolean(get(property));
@NotEmptyIfFieldSet.List({
@NotEmptyIfFieldSet(fieldName = "useGeneratedKeypair", fieldValue = "false", notNullFieldName = "certificateFile", message = "must be set if timely.security.ssl.use-generated-keypair is false"),
@NotEmptyIfFieldSet(fieldName = "useGeneratedKeypair", fieldValue = "false", notNullFieldName = "keyFile", message = "must be set if timely.security.ssl.use-generated-keypair is false") })
public class Ssl {
private String certificateFile;
private String keyFile;
private String keyPassword;
private String trustStoreFile;
private boolean useGeneratedKeypair = false;
private boolean useOpenssl = true;
private List<String> useCiphers = Lists.newArrayList("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_GCM_SHA256",
"TLS_RSA_WITH_AES_128_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA");
public String getCertificateFile() {
return certificateFile;
}
public Configuration setCertificateFile(String certificateFile) {
this.certificateFile = certificateFile;
return Configuration.this;
}
public String getKeyFile() {
return keyFile;
}
public Configuration setKeyFile(String keyFile) {
this.keyFile = keyFile;
return Configuration.this;
}
public String getKeyPassword() {
return keyPassword;
}
public Configuration setKeyPassword(String keyPassword) {
this.keyPassword = keyPassword;
return Configuration.this;
}
public String getTrustStoreFile() {
return trustStoreFile;
}
public Configuration setTrustStoreFile(String trustStoreFile) {
this.trustStoreFile = trustStoreFile;
return Configuration.this;
}
public boolean isUseGeneratedKeypair() {
return useGeneratedKeypair;
}
public Configuration setUseGeneratedKeypair(boolean useGeneratedKeypair) {
this.useGeneratedKeypair = useGeneratedKeypair;
return Configuration.this;
}
public boolean isUseOpenssl() {
return useOpenssl;
}
public Configuration setUseOpenssl(boolean useOpenssl) {
this.useOpenssl = useOpenssl;
return Configuration.this;
}
public List<String> getUseCiphers() {
return useCiphers;
}
public Configuration setUseCiphers(List<String> useCiphers) {
this.useCiphers = useCiphers;
return Configuration.this;
}
}
public class Server {
@NotBlank
private String ip;
@NotNull
private Integer tcpPort;
@NotNull
private Integer udpPort;
private Integer shutdownQuietPeriod = 5;
@NotNull
public String getIp() {
return ip;
}
public Configuration setIp(String ip) {
this.ip = ip;
return Configuration.this;
}
public int getTcpPort() {
return tcpPort;
}
public Configuration setTcpPort(int tcpPort) {
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 {
@NotBlank
private String ip;
@NotNull
private Integer port;
@NotNull
private String host;
private String redirectPath = "/secure-me";
private long strictTransportMaxAge = 604800;
@Valid
@NestedConfigurationProperty
private Cors cors = new Cors();
public String getIp() {
return ip;
}
public Configuration setIp(String ip) {
this.ip = ip;
return Configuration.this;
}
public int getPort() {
return port;
}
public Configuration setPort(int port) {
this.port = port;
return Configuration.this;
}
public String getHost() {
return host;
}
public Configuration setHost(String host) {
this.host = host;
return Configuration.this;
}
public String getRedirectPath() {
return redirectPath;
}
public Configuration setRedirectPath(String redirectPath) {
this.redirectPath = redirectPath;
return Configuration.this;
}
public long getStrictTransportMaxAge() {
return strictTransportMaxAge;
}
public Configuration setStrictTransportMaxAge(long strictTransportMaxAge) {
this.strictTransportMaxAge = strictTransportMaxAge;
return Configuration.this;
}
public Cors getCors() {
return cors;
}
}
public class Cors {
private boolean allowAnyOrigin = false;
private boolean allowNullOrigin = false;
private Set<String> allowedOrigins = new HashSet<>();
private List<String> allowedMethods = Lists.newArrayList("DELETE", "GET", "HEAD", "OPTIONS", "PUT", "POST");
private List<String> allowedHeaders = Lists.newArrayList("content-type");
private boolean allowCredentials = true;
public boolean isAllowAnyOrigin() {
return allowAnyOrigin;
}
public Configuration setAllowAnyOrigin(boolean allowAnyOrigin) {
this.allowAnyOrigin = allowAnyOrigin;
return Configuration.this;
}
public boolean isAllowNullOrigin() {
return allowNullOrigin;
}
public Configuration setAllowNullOrigin(boolean allowNullOrigin) {
this.allowNullOrigin = allowNullOrigin;
return Configuration.this;
}
public Set<String> getAllowedOrigins() {
return allowedOrigins;
}
public Configuration setAllowedOrigins(Set<String> allowedOrigins) {
this.allowedOrigins = allowedOrigins;
return Configuration.this;
}
public List<String> getAllowedMethods() {
return allowedMethods;
}
public Configuration setAllowedMethods(List<String> allowedMethods) {
this.allowedMethods = allowedMethods;
return Configuration.this;
}
public List<String> getAllowedHeaders() {
return allowedHeaders;
}
public Configuration setAllowedHeaders(List<String> allowedHeaders) {
this.allowedHeaders = allowedHeaders;
return Configuration.this;
}
public boolean isAllowCredentials() {
return allowCredentials;
}
public Configuration setAllowCredentials(boolean allowCredentials) {
this.allowCredentials = allowCredentials;
return Configuration.this;
}
}
public class Websocket {
@NotBlank
private String ip;
@NotNull
private Integer port;
public int timeout = 60;
public int subscriptionLag = 120;
public String getIp() {
return ip;
}
public Configuration setIp(String ip) {
this.ip = ip;
return Configuration.this;
}
public int getPort() {
return port;
}
public Configuration setPort(int port) {
this.port = port;
return Configuration.this;
}
public int getTimeout() {
return timeout;
}
public Configuration setTimeout(int timeout) {
this.timeout = timeout;
return Configuration.this;
}
public int getSubscriptionLag() {
return subscriptionLag;
}
public Configuration setSubscriptionLag(int subscriptionLag) {
this.subscriptionLag = subscriptionLag;
return Configuration.this;
}
}
public class MetaCache {
private long expirationMinutes = 60;
private int initialCapacity = 2000;
private long maxCapacity = 10000;
public long getExpirationMinutes() {
return expirationMinutes;
}
public Configuration setExpirationMinutes(long expirationMinutes) {
this.expirationMinutes = expirationMinutes;
return Configuration.this;
}
public int getInitialCapacity() {
return initialCapacity;
}
public Configuration setInitialCapacity(int initialCapacity) {
this.initialCapacity = initialCapacity;
return Configuration.this;
}
public long getMaxCapacity() {
return maxCapacity;
}
public Configuration setMaxCapacity(long maxCapacity) {
this.maxCapacity = maxCapacity;
return Configuration.this;
}
}
public class VisibilityCache {
private long expirationMinutes = 60;
private int initialCapacity = 2000;
private long maxCapacity = 10000;
public long getExpirationMinutes() {
return expirationMinutes;
}
public Configuration setExpirationMinutes(long expirationMinutes) {
this.expirationMinutes = expirationMinutes;
return Configuration.this;
}
public int getInitialCapacity() {
return initialCapacity;
}
public Configuration setInitialCapacity(int initialCapacity) {
this.initialCapacity = initialCapacity;
return Configuration.this;
}
public long getMaxCapacity() {
return maxCapacity;
}
public Configuration setMaxCapacity(long maxCapacity) {
this.maxCapacity = maxCapacity;
return Configuration.this;
}
}
}
+229 -133
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,13 +40,17 @@ import io.netty.util.internal.SystemPropertyUtil;
import java.io.File;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
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.apache.commons.lang3.StringUtils;
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;
@@ -64,11 +68,15 @@ 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;
import timely.netty.websocket.WebSocketRequestDecoder;
import timely.netty.websocket.subscription.WSAddSubscriptionRequestHandler;
import timely.netty.websocket.subscription.WSCloseSubscriptionRequestHandler;
@@ -94,17 +102,21 @@ public class Server {
private static final String WS_PATH = "/websocket";
protected static final CountDownLatch LATCH = new CountDownLatch(1);
static ConfigurableApplicationContext applicationContext;
private Configuration config = null;
private final Configuration config;
private EventLoopGroup tcpWorkerGroup = null;
private EventLoopGroup tcpBossGroup = null;
private EventLoopGroup httpWorkerGroup = null;
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;
@@ -125,11 +137,7 @@ public class Server {
return true;
} else if (minor == EPOLL_MIN_MINOR_VERSION) {
final int patch = Integer.parseInt(version[2].substring(0, 2));
if (patch >= EPOLL_MIN_PATCH_VERSION) {
return true;
} else {
return false;
}
return patch >= EPOLL_MIN_PATCH_VERSION;
} else {
return false;
}
@@ -141,11 +149,6 @@ public class Server {
}
}
private static String usage() {
return "Server <configFile>";
}
public static void fatal(String msg, Throwable t) {
LOG.error(msg, t);
LATCH.countDown();
@@ -153,32 +156,35 @@ public class Server {
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.err.println(usage());
}
final File conf = new File(args[0]);
if (!conf.canRead()) {
throw new RuntimeException("Configuration file does not exist or cannot be read");
}
Configuration conf = initializeConfiguration(args);
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);
}
}
}
protected static Configuration initializeConfiguration(String[] args) {
applicationContext = new SpringApplicationBuilder(SpringBootstrap.class).web(false).run(args);
return applicationContext.getBean(Configuration.class);
}
private void shutdownHook() {
final Runnable shutdownRunner = new Runnable() {
@Override
public void run() {
if (!shutdown) {
shutdown();
}
final Runnable shutdownRunner = () -> {
if (!shutdown) {
shutdown();
}
};
final Thread hook = new Thread(shutdownRunner, "shutdown-hook-thread");
@@ -186,65 +192,127 @@ 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;
LOG.info("Server shut down.");
}
public Server(File conf) throws Exception {
public Server(Configuration conf) throws Exception {
this.config = conf;
}
public void run() throws Exception {
config = new Configuration(conf);
int nettyThreads = Math.max(1,
SystemPropertyUtil.getInt("io.netty.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2));
dataStore = DataStoreFactory.create(config, nettyThreads);
@@ -255,7 +323,8 @@ public class Server {
// Initialize the VisibilityCache
VisibilityCache.init(config);
final boolean useEpoll = useEpoll();
Class<? extends ServerSocketChannel> channelClass = null;
Class<? extends ServerSocketChannel> channelClass;
Class<? extends Channel> datagramChannelClass;
if (useEpoll) {
tcpWorkerGroup = new EpollEventLoopGroup();
tcpBossGroup = new EpollEventLoopGroup();
@@ -263,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();
@@ -271,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 = Integer.parseInt(config.get(Configuration.PUT_PORT));
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 = Integer.parseInt(config.get(Configuration.QUERY_PORT));
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(Integer.parseInt(config.get(Configuration.SESSION_MAX_AGE)));
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 = Integer.parseInt(config.get(Configuration.WEBSOCKET_PORT));
final int wsPort = config.getWebsocket().getPort();
final String wsIp = config.getWebsocket().getIp();
final ServerBootstrap wsServer = new ServerBootstrap();
wsServer.group(wsBossGroup, wsWorkerGroup);
wsServer.channel(channelClass);
@@ -319,19 +396,30 @@ 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 {
Boolean generate = config.getBoolean(Configuration.SSL_USE_GENERATED_KEYPAIR);
SslContextBuilder ssl = null;
Configuration.Ssl sslCfg = config.getSecurity().getSsl();
Boolean generate = sslCfg.isUseGeneratedKeypair();
SslContextBuilder ssl;
if (generate) {
LOG.warn("Using generated self signed server certificate");
Date begin = new Date();
@@ -339,30 +427,31 @@ public class Server {
SelfSignedCertificate ssc = new SelfSignedCertificate("localhost", begin, end);
ssl = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey());
} else {
String cert = config.get(Configuration.SSL_CERTIFICATE_FILE);
String key = config.get(Configuration.SSL_PRIVATE_KEY_FILE);
String keyPass = config.get(Configuration.SSL_PRIVATE_KEY_PASS);
String cert = sslCfg.getCertificateFile();
String key = sslCfg.getKeyFile();
String keyPass = sslCfg.getKeyPassword();
if (null == cert || null == key) {
throw new IllegalArgumentException("Check your SSL properties, something is wrong.");
}
ssl = SslContextBuilder.forServer(new File(cert), new File(key), keyPass);
}
String ciphers = config.get(Configuration.SSL_USE_CIPHERS);
ssl.ciphers(Arrays.asList(ciphers.split(":")));
ssl.ciphers(sslCfg.getUseCiphers());
// Can't set to REQUIRE because the CORS pre-flight requests will fail.
ssl.clientAuth(ClientAuth.OPTIONAL);
Boolean useOpenSSL = config.getBoolean(Configuration.SSL_USE_OPENSSL);
Boolean useOpenSSL = sslCfg.isUseOpenssl();
if (useOpenSSL) {
ssl.sslProvider(SslProvider.OPENSSL);
} else {
ssl.sslProvider(SslProvider.JDK);
}
String trustStore = config.get(Configuration.SSL_TRUST_STORE_FILE);
String trustStore = sslCfg.getTrustStoreFile();
if (null != trustStore) {
ssl.trustManager(new File(trustStore));
if (!trustStore.isEmpty()) {
ssl.trustManager(new File(trustStore));
}
}
return ssl.build();
}
@@ -382,30 +471,21 @@ public class Server {
ch.pipeline().addLast("decompressor", new HttpContentDecompressor());
ch.pipeline().addLast("aggregator", new HttpObjectAggregator(8192));
ch.pipeline().addLast("chunker", new ChunkedWriteHandler());
final Configuration.Cors corsCfg = config.getHttp().getCors();
final CorsConfig.Builder ccb;
if (config.getBoolean(Configuration.CORS_ALLOW_ANY_ORIGIN)) {
if (corsCfg.isAllowAnyOrigin()) {
ccb = new CorsConfig.Builder();
} else {
String origins = config.get(Configuration.CORS_ALLOWED_ORIGINS);
ccb = new CorsConfig.Builder(origins.split(","));
ccb = new CorsConfig.Builder(corsCfg.getAllowedOrigins().stream().toArray(String[]::new));
}
if (config.getBoolean(Configuration.CORS_ALLOW_NULL_ORIGIN)) {
if (corsCfg.isAllowNullOrigin()) {
ccb.allowNullOrigin();
}
if (config.getBoolean(Configuration.CORS_ALLOW_CREDENTIALS)) {
if (corsCfg.isAllowCredentials()) {
ccb.allowCredentials();
}
if (!StringUtils.isEmpty(config.get(Configuration.CORS_ALLOWED_METHODS))) {
String[] methods = config.get(Configuration.CORS_ALLOWED_METHODS).split(",");
HttpMethod[] m = new HttpMethod[methods.length];
for (int i = 0; i < methods.length; i++) {
m[i] = HttpMethod.valueOf(methods[i]);
}
ccb.allowedRequestMethods(m);
}
if (!StringUtils.isEmpty(config.get(Configuration.CORS_ALLOWED_HEADERS))) {
ccb.allowedRequestHeaders(config.get(Configuration.CORS_ALLOWED_HEADERS).split(","));
}
corsCfg.getAllowedMethods().stream().map(HttpMethod::valueOf).forEach(ccb::allowedRequestMethods);
corsCfg.getAllowedHeaders().forEach(ccb::allowedRequestHeaders);
CorsConfig cors = ccb.build();
LOG.trace("Cors configuration: {}", cors);
ch.pipeline().addLast("cors", new CorsHandler(cors));
@@ -426,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));
@@ -447,8 +543,8 @@ public class Server {
ch.pipeline().addLast("ssl", sslCtx.newHandler(ch.alloc()));
ch.pipeline().addLast("httpServer", new HttpServerCodec());
ch.pipeline().addLast("aggregator", new HttpObjectAggregator(8192));
ch.pipeline().addLast("idle-handler",
new IdleStateHandler(Integer.parseInt(conf.get(Configuration.WS_TIMEOUT_SECONDS)), 0, 0));
ch.pipeline().addLast("sessionExtractor", new WebSocketHttpCookieHandler(config));
ch.pipeline().addLast("idle-handler", new IdleStateHandler(conf.getWebsocket().getTimeout(), 0, 0));
ch.pipeline().addLast("ws-protocol", new WebSocketServerProtocolHandler(WS_PATH, null, true));
ch.pipeline().addLast("wsDecoder", new WebSocketRequestDecoder(config));
ch.pipeline().addLast("aggregators", new WSAggregatorsRequestHandler());
@@ -0,0 +1,7 @@
package timely;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackageClasses = { Configuration.class })
public class SpringBootstrap {
}
@@ -21,7 +21,7 @@ public class StandaloneServer extends Server {
private static MiniAccumuloCluster mac = null;
public StandaloneServer(File conf) throws Exception {
public StandaloneServer(Configuration conf) throws Exception {
super(conf);
}
@@ -38,22 +38,21 @@ public class StandaloneServer extends Server {
}
private static String usage() {
return "StandaloneServer <configFile> <directory>";
return "StandaloneServer <directory>";
}
public static void main(String[] args) {
if (args.length != 2) {
if (args.length < 1) {
System.err.println(usage());
}
final File conf = new File(args[0]);
if (!conf.canRead()) {
throw new RuntimeException("Configuration file does not exist or cannot be read");
}
File tmp = new File(args[1]);
File tmp = new File(args[0]);
if (!tmp.canWrite()) {
System.err.println("Unable to write to directory: " + tmp);
System.exit(1);
}
Configuration conf = initializeConfiguration(args);
File accumuloDir = new File(tmp, "accumulo");
MiniAccumuloConfig macConfig = new MiniAccumuloConfig(accumuloDir, "secret");
macConfig.setInstanceName("TimelyStandalone");
@@ -83,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();
@@ -95,5 +95,4 @@ public class StandaloneServer extends Server {
LOG.info("Server shutting down.");
}
}
}
@@ -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,231 +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() {
MetricResponse response = new MetricResponse();
response.setMetric(this.metric);
response.setTimestamp(this.timestamp);
response.setTags(this.tags);
response.setValue(this.value);
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;
@@ -4,10 +4,9 @@ import java.util.Map;
import java.util.Optional;
import timely.api.annotation.WebSocket;
import timely.api.request.AuthenticatedWebSocketRequest;
@WebSocket(operation = "add")
public class AddSubscription extends AuthenticatedWebSocketRequest {
public class AddSubscription extends SubscriptionRequest {
private String metric = null;
private Optional<Map<String, String>> tags = Optional.empty();
@@ -1,8 +1,7 @@
package timely.api.request.subscription;
import timely.api.annotation.WebSocket;
import timely.api.request.AuthenticatedWebSocketRequest;
@WebSocket(operation = "close")
public class CloseSubscription extends AuthenticatedWebSocketRequest {
public class CloseSubscription extends SubscriptionRequest {
}
@@ -1,8 +1,7 @@
package timely.api.request.subscription;
import timely.api.annotation.WebSocket;
import timely.api.request.AuthenticatedWebSocketRequest;
@WebSocket(operation = "create")
public class CreateSubscription extends AuthenticatedWebSocketRequest {
public class CreateSubscription extends SubscriptionRequest {
}
@@ -1,10 +1,9 @@
package timely.api.request.subscription;
import timely.api.annotation.WebSocket;
import timely.api.request.AuthenticatedWebSocketRequest;
@WebSocket(operation = "remove")
public class RemoveSubscription extends AuthenticatedWebSocketRequest {
public class RemoveSubscription extends SubscriptionRequest {
private String metric = null;
@@ -0,0 +1,24 @@
package timely.api.request.subscription;
import timely.api.request.AuthenticatedWebSocketRequest;
public class SubscriptionRequest extends AuthenticatedWebSocketRequest {
private String subscriptionId = null;
public String getSubscriptionId() {
return subscriptionId;
}
public void setSubscriptionId(String subscriptionId) {
this.subscriptionId = subscriptionId;
}
@Override
public void validate() {
if (null == subscriptionId) {
throw new IllegalArgumentException("Subscription ID is required.");
}
}
}
@@ -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 {
@@ -14,6 +15,7 @@ public class MetricResponse {
private long timestamp;
private double value;
private List<Tag> tags;
private String subscriptionId;
public String getMetric() {
return metric;
@@ -47,6 +49,24 @@ public class MetricResponse {
this.tags = tags;
}
public String getSubscriptionId() {
return subscriptionId;
}
public void setSubscriptionId(String subscriptionId) {
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();
@@ -54,6 +74,7 @@ public class MetricResponse {
hash.append(this.timestamp);
hash.append(this.value);
hash.append(this.tags);
hash.append(this.subscriptionId);
return hash.hashCode();
}
@@ -74,6 +95,7 @@ public class MetricResponse {
equals.append(this.timestamp, other.timestamp);
equals.append(this.value, other.value);
equals.append(this.tags, other.tags);
equals.append(this.subscriptionId, other.subscriptionId);
return equals.isEquals();
}
@@ -84,6 +106,7 @@ public class MetricResponse {
tsb.append("timestamp", this.timestamp);
tsb.append("value", this.value);
tsb.append("tags", this.tags);
tsb.append("subscriptionId", this.subscriptionId);
return tsb.toString();
}
@@ -18,12 +18,12 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
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;
@@ -40,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";
@@ -62,20 +63,16 @@ public class MetricsResponse {
private static final String TD_END = "</td>\n";
private Set<String> ignoredTags = Collections.emptySet();
private Configuration conf = null;
private final Configuration conf;
public MetricsResponse() {
conf = null;
}
public MetricsResponse(Configuration conf) {
String tagsToIgnore = conf.get(Configuration.METRICS_IGNORED_TAGS);
if (!StringUtils.isEmpty(tagsToIgnore)) {
this.ignoredTags = new HashSet<>();
for (String tag : tagsToIgnore.split(",")) {
ignoredTags.add(tag);
}
}
this.conf = conf;
ignoredTags = new HashSet<>(conf.getMetricsReportIgnoredTags());
ignoredTags.add(MetricAdapter.VISIBILITY_TAG);
}
public TextWebSocketFrame toWebSocketResponse(String acceptHeader) throws Exception {
@@ -23,20 +23,20 @@ public class AuthCache {
private static Cache<String, Authentication> CACHE = null;
private static Long sessionMaxAge = -1L;
private static int sessionMaxAge = -1;
/**
* For tests only
*/
public static void resetSessionMaxAge() {
sessionMaxAge = -1L;
sessionMaxAge = -1;
}
public static void setSessionMaxAge(Configuration config) {
if (-1 != sessionMaxAge) {
throw new IllegalStateException("Cache session max age already configured.");
}
sessionMaxAge = Long.parseLong(config.get(Configuration.SESSION_MAX_AGE));
sessionMaxAge = config.getSecurity().getSessionMaxAge();
}
public static Cache<String, Authentication> getCache() {
@@ -56,9 +56,7 @@ public class AuthCache {
Collection<? extends GrantedAuthority> authorities = CACHE.asMap().get(sessionId).getAuthorities();
String[] auths = new String[authorities.size()];
final AtomicInteger i = new AtomicInteger(0);
authorities.forEach(a -> {
auths[i.getAndIncrement()] = a.getAuthority();
});
authorities.forEach(a -> auths[i.getAndIncrement()] = a.getAuthority());
return new Authorizations(auths);
} else {
return null;
@@ -69,7 +67,7 @@ public class AuthCache {
}
public static void enforceAccess(Configuration conf, Request r) throws Exception {
if (!conf.getBoolean(Configuration.ALLOW_ANONYMOUS_ACCESS) && (r instanceof AuthenticatedRequest)) {
if (!conf.getSecurity().isAllowAnonymousAccess() && (r instanceof AuthenticatedRequest)) {
AuthenticatedRequest ar = (AuthenticatedRequest) r;
if (StringUtils.isEmpty(ar.getSessionId())) {
throw new TimelyException(HttpResponseStatus.UNAUTHORIZED.code(), "User must log in",
@@ -11,22 +11,11 @@ public class VisibilityCache {
private static volatile Cache<String, ColumnVisibility> CACHE = null;
/** Used for testing */
public static synchronized void init() {
if (CACHE == null) {
long defaultExpiration = Configuration.VISIBILITY_EXPIRATION_DEFAULT;
int initialCapacity = Configuration.VISIBILITY_CACHE_INITIAL_CAPACITY_DEFAULT;
long maxCapacity = Configuration.VISIBILITY_CACHE_MAX_CAPACITY_DEFAULT;
CACHE = Caffeine.newBuilder().expireAfterAccess(defaultExpiration, TimeUnit.MINUTES)
.initialCapacity(initialCapacity).maximumSize(maxCapacity).build();
}
}
public static synchronized void init(Configuration config) {
if (CACHE == null) {
long expireMinutes = Long.parseLong(config.get(Configuration.VISIBILITY_CACHE_EXPIRATION));
int initialCapacity = Integer.parseInt(config.get(Configuration.VISIBILITY_CACHE_INITIAL_CAPACITY));
long maxCapacity = Long.parseLong(config.get(Configuration.VISIBILITY_CACHE_MAX_CAPACITY));
long expireMinutes = config.getVisibilityCache().getExpirationMinutes();
int initialCapacity = config.getVisibilityCache().getInitialCapacity();
long maxCapacity = config.getVisibilityCache().getMaxCapacity();
CACHE = Caffeine.newBuilder().expireAfterAccess(expireMinutes, TimeUnit.MINUTES)
.initialCapacity(initialCapacity).maximumSize(maxCapacity).build();
}
@@ -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);
@@ -40,8 +40,28 @@ public class HttpRequestDecoder extends MessageToMessageDecoder<FullHttpRequest>
public HttpRequestDecoder(Configuration config) {
this.conf = config;
this.anonymousAccessAllowed = conf.getBoolean(Configuration.ALLOW_ANONYMOUS_ACCESS);
this.nonSecureRedirectAddress = conf.get(Configuration.NON_SECURE_REDIRECT_PATH);
this.anonymousAccessAllowed = conf.getSecurity().isAllowAnonymousAccess();
this.nonSecureRedirectAddress = conf.getHttp().getRedirectPath();
}
public static String getSessionId(FullHttpRequest msg, boolean anonymousAccessAllowed) {
final StringBuilder buf = new StringBuilder();
msg.headers().getAll(Names.COOKIE).forEach(h -> {
ServerCookieDecoder.STRICT.decode(h).forEach(c -> {
if (c.name().equals(Constants.COOKIE_NAME)) {
if (buf.length() == 0) {
buf.append(c.value());
}
}
});
});
String sessionId = buf.toString();
if (sessionId.length() == 0 && anonymousAccessAllowed) {
sessionId = NO_AUTHORIZATIONS;
} else if (sessionId.length() == 0) {
sessionId = null;
}
return sessionId;
}
@Override
@@ -56,27 +76,10 @@ public class HttpRequestDecoder extends MessageToMessageDecoder<FullHttpRequest>
return;
}
final StringBuilder buf = new StringBuilder();
msg.headers().getAll(Names.COOKIE).forEach(h -> {
ServerCookieDecoder.STRICT.decode(h).forEach(c -> {
if (c.name().equals(Constants.COOKIE_NAME)) {
if (buf.length() == 0) {
buf.append(c.value());
}
}
});
});
String sId = buf.toString();
if (sId.length() == 0 && this.anonymousAccessAllowed) {
sId = NO_AUTHORIZATIONS;
} else if (sId.length() == 0) {
sId = null;
}
final String sessionId = sId;
final String sessionId = getSessionId(msg, this.anonymousAccessAllowed);
LOG.trace("SessionID: " + sessionId);
Request request = null;
Request request;
try {
if (msg.getMethod().equals(HttpMethod.GET)) {
HttpGetRequest get = AnnotationResolver.getClassForHttpGet(decoder.path());
Loaded 100 of 173 files, more files were not shown because too many files have changed in this diff. Show more