Compare commits

..
Author SHA1 Message Date
Bill Oley 69203cda3b Changes to support accumulo2 2023-10-16 16:49:43 -04:00
Bill Oley eb286bb33b Delete grafana-auth module 2023-10-16 16:48:55 -04:00
51 changed files with 1730 additions and 1423 deletions

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>2.0.0</version>
<version>1.3.7-SNAPSHOT</version>
</parent>
<artifactId>timely-analytics</artifactId>
<!--
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>2.0.0</version>
<version>1.3.7-SNAPSHOT</version>
</parent>
<artifactId>timely-balancer</artifactId>
<dependencies>
+2 -2
View File
@@ -4,13 +4,13 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>2.0.0</version>
<version>1.3.7-SNAPSHOT</version>
</parent>
<artifactId>timely-client</artifactId>
<properties>
<!-- PEP 440 compliant version gets substituted into src/main/python/template/setup.py -->
<!-- use .dev0 instead of -SNAPSHOT -->
<python.client.version>2.0.0</python.client.version>
<python.client.version>1.3.7.dev0</python.client.version>
</properties>
<dependencies>
<dependency>
@@ -6,9 +6,7 @@ import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.logging.Logger;
/**
* A simple interface that objects can implement to return the object size.
@@ -48,7 +46,7 @@ public interface ObjectSizeOf {
public static class Sizer {
private static final Logger LOG = LoggerFactory.getLogger(Sizer.class);
private static final Logger log = Logger.getLogger(Sizer.class.getCanonicalName());
public static final short OBJECT_OVERHEAD = 8;
public static final short ARRAY_OVERHEAD = 12;
public static final short REFERENCE = 4;
@@ -152,7 +150,7 @@ public interface ObjectSizeOf {
}
}
} catch (Throwable t) {
LOG.warn("Unable to determine object size for " + o, t);
log.warning("Unable to determine object size for " + o);
}
if (debug) {
System.out.println(o.getClass().getCanonicalName() + "=" + size);
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>2.0.0</version>
<version>1.3.7-SNAPSHOT</version>
</parent>
<artifactId>collectd-nsq-plugin</artifactId>
<dependencies>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>2.0.0</version>
<version>1.3.7-SNAPSHOT</version>
</parent>
<artifactId>collectd-plugin-parent</artifactId>
<dependencies>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>2.0.0</version>
<version>1.3.7-SNAPSHOT</version>
</parent>
<artifactId>collectd-timely-plugin</artifactId>
<dependencies>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>2.0.0</version>
<version>1.3.7-SNAPSHOT</version>
</parent>
<artifactId>timely-common</artifactId>
<dependencies>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>2.0.0</version>
<version>1.3.7-SNAPSHOT</version>
</parent>
<artifactId>timely-app</artifactId>
<packaging>pom</packaging>
+2 -2
View File
@@ -28,8 +28,8 @@
}
],
"screenshots": [],
"version": "2.0.0",
"updated": "2024-01-17"
"version": "1.3.7-SNAPSHOT",
"updated": "2023-10-13"
},
"dependencies": {
"classnames": "2.2.6",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "timely-datasource",
"version": "2.0.0",
"version": "1.3.7-SNAPSHOT",
"description": "Timely",
"backend": true,
"alerting": true,
+3 -15
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>2.0.0</version>
<version>1.3.7-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Timely</name>
<description>A secure and scalable time series database based on Apache Accumulo</description>
@@ -45,13 +45,12 @@
<version.caffeine>3.1.6</version.caffeine>
<version.collectd>5.7.1</version.collectd>
<version.commons-collections4>4.3</version.commons-collections4>
<version.commons-lang3>3.13.0</version.commons-lang3>
<version.commons-lang3>3.8.1</version.commons-lang3>
<version.commons-logging>1.1.1</version.commons-logging>
<version.commons-pool2>2.6.1</version.commons-pool2>
<version.commons-text>1.10.0</version.commons-text>
<version.compression.gorilla>2.1.1</version.compression.gorilla>
<version.curator>4.1.0</version.curator>
<version.datawave-in-memory-accumulo>2.1.1</version.datawave-in-memory-accumulo>
<version.disruptor>3.4.2</version.disruptor>
<version.easymock>4.0.2</version.easymock>
<version.eclipse-lifecycle>1.0.0</version.eclipse-lifecycle>
@@ -181,17 +180,6 @@
<artifactId>compression-gorilla</artifactId>
<version>${version.compression.gorilla}</version>
</dependency>
<dependency>
<groupId>gov.nsa.datawave.contrib</groupId>
<artifactId>datawave-in-memory-accumulo</artifactId>
<version>${version.datawave-in-memory-accumulo}</version>
<exclusions>
<exclusion>
<groupId>org.apache.accumulo</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.github.lukehutch</groupId>
<artifactId>fast-classpath-scanner</artifactId>
@@ -586,7 +574,7 @@
<include>**/*.java</include>
</includes>
<groups>timely.test.IntegrationTest</groups>
<redirectTestOutputToFile>false</redirectTestOutputToFile>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
</configuration>
<executions>
<execution>
+1 -5
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>timely</groupId>
<artifactId>timely</artifactId>
<version>2.0.0</version>
<version>1.3.7-SNAPSHOT</version>
</parent>
<artifactId>timely-server</artifactId>
<dependencies>
@@ -44,10 +44,6 @@
<groupId>fi.iki.yak</groupId>
<artifactId>compression-gorilla</artifactId>
</dependency>
<dependency>
<groupId>gov.nsa.datawave.contrib</groupId>
<artifactId>datawave-in-memory-accumulo</artifactId>
</dependency>
<dependency>
<groupId>io.github.lukehutch</groupId>
<artifactId>fast-classpath-scanner</artifactId>
+15 -41
View File
@@ -12,7 +12,6 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@@ -62,8 +61,6 @@ import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.NettyRuntime;
import io.netty.util.internal.SystemPropertyUtil;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.conf.ClientProperty;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
@@ -84,7 +81,6 @@ import org.springframework.context.ConfigurableApplicationContext;
import timely.auth.AuthCache;
import timely.auth.JWTTokenHandler;
import timely.auth.VisibilityCache;
import timely.configuration.Accumulo;
import timely.configuration.Configuration;
import timely.configuration.Cors;
import timely.configuration.ServerSsl;
@@ -145,7 +141,6 @@ public class Server {
static ConfigurableApplicationContext applicationContext;
private final Configuration config;
private AccumuloClient accumuloClient;
private EventLoopGroup tcpWorkerGroup = null;
private EventLoopGroup tcpBossGroup = null;
private EventLoopGroup httpWorkerGroup = null;
@@ -308,11 +303,9 @@ public class Server {
// wait for the channels to shutdown
channelFutures.forEach(f -> {
try {
if (!f.isDone()) {
f.get();
}
f.get();
} catch (final Exception e) {
LOG.error("Channel:" + f.channel().config() + " -> " + e.getMessage());
LOG.error("Channel:" + f.channel().config() + " -> " + e.getMessage(), e);
}
});
@@ -420,40 +413,17 @@ public class Server {
LOG.info("Server shut down.");
}
public Server(Configuration conf, AccumuloClient accumuloClient, int eventLoopThreads) {
public Server(Configuration conf, int eventLoopThreads) throws Exception {
DEFAULT_EVENT_LOOP_THREADS = eventLoopThreads;
this.config = conf;
if (accumuloClient == null) {
this.accumuloClient = createAccumuloClient((conf));
} else {
this.accumuloClient = accumuloClient;
}
}
public Server(Configuration conf, AccumuloClient accumuloClient) {
this(conf, accumuloClient, Math.max(1,
SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2)));
}
public Server(Configuration conf) throws Exception {
public Server(Configuration conf) {
this(conf, null);
}
private AccumuloClient createAccumuloClient(Configuration conf) {
Properties properties = new Properties();
Accumulo accumuloConf = conf.getAccumulo();
properties.put(ClientProperty.INSTANCE_NAME.getKey(), accumuloConf.getInstanceName());
properties.put(ClientProperty.INSTANCE_ZOOKEEPERS.getKey(), accumuloConf.getZookeepers());
properties.put(ClientProperty.INSTANCE_ZOOKEEPERS_TIMEOUT.getKey(), accumuloConf.getZookeeperTimeout());
properties.put(ClientProperty.AUTH_PRINCIPAL.getKey(), accumuloConf.getUsername());
properties.put(ClientProperty.AUTH_TOKEN.getKey(), accumuloConf.getPassword());
properties.put(ClientProperty.AUTH_TYPE.getKey(), "password");
return org.apache.accumulo.core.client.Accumulo.newClient().from(properties).build();
}
public void setAccumuloClient(AccumuloClient accumuloClient) {
this.accumuloClient = accumuloClient;
DEFAULT_EVENT_LOOP_THREADS = Math.max(1,
SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
this.config = conf;
}
private void ensureZkPaths(CuratorFramework curatorFramework, String[] paths) {
@@ -503,7 +473,7 @@ public class Server {
int nettyThreads = Math.max(1,
SystemPropertyUtil.getInt("io.netty.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2));
dataStore = DataStoreFactory.create(config, accumuloClient, nettyThreads);
dataStore = DataStoreFactory.create(config, nettyThreads);
if (config.getCache().isEnabled()) {
dataStoreCache = new DataStoreCache(curatorFramework, config);
dataStoreCache.setInternalMetrics(dataStore.getInternalMetrics());
@@ -513,7 +483,7 @@ public class Server {
MetaCacheFactory.getCache(config);
AuthCache.configure(config.getSecurity());
VisibilityCache.init(config);
JWTTokenHandler.init(config.getSecurity(), accumuloClient);
JWTTokenHandler.init(config.getSecurity(), config.getAccumulo());
final boolean useEpoll = useEpoll();
Class<? extends ServerSocketChannel> channelClass;
Class<? extends Channel> datagramChannelClass;
@@ -549,6 +519,7 @@ public class Server {
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();
@@ -573,6 +544,7 @@ public class Server {
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();
@@ -585,7 +557,9 @@ public class Server {
wsServer.childHandler(setupWSChannel(sslCtx, config));
wsServer.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
wsServer.option(ChannelOption.SO_BACKLOG, 128);
/* Not sure if next line is necessary */
wsServer.option(ChannelOption.SO_KEEPALIVE, true);
/* Not sure if next two lines are necessary */
wsServer.option(ChannelOption.SO_SNDBUF, 1048576);
wsServer.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(620145, 838860));
wsChannelHandle = wsServer.bind(wsIp, wsPort).sync().channel();
final String wsAddress = ((InetSocketAddress) wsChannelHandle.localAddress()).getAddress().getHostAddress();
@@ -616,7 +590,7 @@ public class Server {
Boolean generate = sslCfg.isUseGeneratedKeypair();
SslContextBuilder ssl;
if (generate) {
LOG.info("Using generated self signed server certificate");
LOG.warn("Using generated self signed server certificate");
Date begin = new Date();
Date end = new Date(begin.getTime() + TimeUnit.DAYS.toMillis(7));
SelfSignedCertificate ssc = new SelfSignedCertificate("localhost", begin, end);
@@ -14,11 +14,13 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.guava.GuavaModule;
import io.jsonwebtoken.*;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.conf.ClientProperty;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import timely.configuration.Accumulo;
import timely.configuration.Security;
/**
@@ -32,7 +34,7 @@ public class JWTTokenHandler {
private static ObjectMapper objectMapper;
private static Collection<String> accumuloAuths = new TreeSet<>();
public static void init(Security security, AccumuloClient accumuloClient) {
public static void init(Security security, Accumulo accumuloConfiguration) {
if (StringUtils.isNotBlank(security.getJwtCheckKeyStore())) {
try {
String type = security.getJwtCheckKeyType();
@@ -56,13 +58,23 @@ public class JWTTokenHandler {
}
JWTTokenHandler.objectMapper = new ObjectMapper();
JWTTokenHandler.objectMapper.registerModule(new GuavaModule());
if (accumuloClient != null) {
if (accumuloConfiguration != null) {
try {
Authorizations currentAccumuloAuths = accumuloClient.securityOperations()
.getUserAuthorizations(accumuloClient.whoami());
currentAccumuloAuths.iterator()
.forEachRemaining(a -> accumuloAuths.add(new String(a, Charset.forName("UTF-8"))));
final Properties properties = new Properties();
properties.put(ClientProperty.INSTANCE_NAME.getKey(), accumuloConfiguration.getInstanceName());
properties.put(ClientProperty.INSTANCE_ZOOKEEPERS.getKey(), accumuloConfiguration.getZookeepers());
properties.put(ClientProperty.INSTANCE_ZOOKEEPERS_TIMEOUT.getKey(),
accumuloConfiguration.getZookeeperTimeout());
properties.put(ClientProperty.AUTH_PRINCIPAL.getKey(), accumuloConfiguration.getUsername());
properties.put(ClientProperty.AUTH_TOKEN.getKey(), accumuloConfiguration.getPassword());
properties.put(ClientProperty.AUTH_TYPE.getKey(), "password");
try (AccumuloClient accumuloClient = org.apache.accumulo.core.client.Accumulo.newClient()
.from(properties).build()) {
Authorizations currentAccumuloAuths = accumuloClient.securityOperations()
.getUserAuthorizations(accumuloClient.whoami());
currentAccumuloAuths.iterator()
.forEachRemaining(a -> accumuloAuths.add(new String(a, Charset.forName("UTF-8"))));
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
@@ -3,7 +3,6 @@ package timely.configuration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
@@ -19,7 +18,7 @@ public class Configuration {
private String metricsTable = "timely.metrics";
private String metaTable = "timely.meta";
private Map<String, Integer> metricAgeOffDays = new HashMap<>();
private HashMap<String, Integer> metricAgeOffDays = new HashMap<>();
private List<String> metricsReportIgnoredTags = new ArrayList<>();
private String instance = null;
private String defaultVisibility = null;
@@ -83,11 +82,11 @@ public class Configuration {
this.defaultVisibility = defaultVisibility;
}
public Map<String, Integer> getMetricAgeOffDays() {
public HashMap<String, Integer> getMetricAgeOffDays() {
return metricAgeOffDays;
}
public void setMetricAgeOffDays(Map<String, Integer> metricAgeOffDays) {
public void setMetricAgeOffDays(HashMap<String, Integer> metricAgeOffDays) {
this.metricAgeOffDays = metricAgeOffDays;
}
@@ -22,7 +22,7 @@ public class TcpDecoder extends ByteToMessageDecoder {
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
ByteBuf buf = in.readBytes(in.readableBytes());
String input = null;
String input = "";
try {
if (buf == Unpooled.EMPTY_BUFFER) {
return;
@@ -22,11 +22,11 @@ public class UdpDecoder extends ByteToMessageDecoder {
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
ByteBuf buf = in.readBytes(in.readableBytes());
String input = null;
try {
if (buf == Unpooled.EMPTY_BUFFER) {
return;
}
final String input;
if (buf.hasArray()) {
input = new String(buf.array(), UTF_8);
} else {
@@ -58,8 +58,6 @@ public class UdpDecoder extends ByteToMessageDecoder {
tcp.parse(input);
out.add(tcp);
LOG.trace("Converted {} to {}", input, tcp);
} catch (Exception e) {
LOG.error("{} parsing line:[{}]", e.getMessage(), input);
} finally {
buf.release();
}
@@ -80,7 +80,7 @@ public class DownsampleIterator extends WrappingIterator {
@Override
public boolean hasTop() {
if (last == null && super.hasTop()) {
if (super.hasTop()) {
while (super.hasTop()) {
Key topKey = super.getTopKey();
Value topValue = super.getTopValue();
@@ -89,12 +89,12 @@ public class DownsampleIterator extends WrappingIterator {
long timestamp = metric.getValue().getTimestamp();
if (memoryEstimator.shouldReturnBasedOnMemoryUsage(timestamp, value)) {
LOG.trace("returning current values - memory usage > " + memoryEstimator.maxDownsampleMemory
+ " for metric=" + metric);
+ " for metric=" + metric.toString());
break;
}
last = topKey;
Set<Tag> tags = new HashSet<>(metric.getTags());
Set<Tag> tags = new HashSet<Tag>(metric.getTags());
Downsample sample = value.get(tags);
if (sample == null) {
try {
@@ -113,8 +113,10 @@ public class DownsampleIterator extends WrappingIterator {
throw new RuntimeException("Downstream next() failed", e);
}
}
return last != null;
} else {
return false;
}
return last != null;
}
@Override
@@ -1,14 +1,12 @@
package timely.store;
import org.apache.accumulo.core.client.AccumuloClient;
import timely.api.response.TimelyException;
import timely.configuration.Configuration;
public class DataStoreFactory {
public static DataStore create(Configuration conf, AccumuloClient accumuloClient, int numWriteThreads)
throws TimelyException {
public static DataStore create(Configuration conf, int numWriteThreads) throws TimelyException {
return new DataStoreImpl(conf, accumuloClient, numWriteThreads);
return new DataStoreImpl(conf, numWriteThreads);
}
}
@@ -19,6 +19,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -44,6 +45,7 @@ import org.apache.accumulo.core.client.Scanner;
import org.apache.accumulo.core.client.ScannerBase;
import org.apache.accumulo.core.client.TableExistsException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.conf.ClientProperty;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Mutation;
import org.apache.accumulo.core.data.PartialKey;
@@ -136,12 +138,18 @@ public class DataStoreImpl implements DataStore {
private DataStoreCache cache = null;
private final String defaultVisibility;
public DataStoreImpl(Configuration conf, AccumuloClient accumuloClient, int numWriteThreads)
throws TimelyException {
public DataStoreImpl(Configuration conf, int numWriteThreads) throws TimelyException {
try {
this.accumuloClient = accumuloClient;
final Properties properties = new Properties();
Accumulo accumuloConf = conf.getAccumulo();
properties.put(ClientProperty.INSTANCE_NAME.getKey(), accumuloConf.getInstanceName());
properties.put(ClientProperty.INSTANCE_ZOOKEEPERS.getKey(), accumuloConf.getZookeepers());
properties.put(ClientProperty.INSTANCE_ZOOKEEPERS_TIMEOUT.getKey(), accumuloConf.getZookeeperTimeout());
properties.put(ClientProperty.AUTH_PRINCIPAL.getKey(), accumuloConf.getUsername());
properties.put(ClientProperty.AUTH_TOKEN.getKey(), accumuloConf.getPassword());
properties.put(ClientProperty.AUTH_TYPE.getKey(), "password");
accumuloClient = org.apache.accumulo.core.client.Accumulo.newClient().from(properties).build();
bwConfig = new BatchWriterConfig();
bwConfig.setMaxLatency(getTimeInMillis(accumuloConf.getWrite().getLatency()), TimeUnit.MILLISECONDS);
bwConfig.setMaxMemory(getMemoryAsBytes(accumuloConf.getWrite().getBufferSize()) / numWriteThreads);
@@ -207,14 +207,18 @@ public class DataStoreCache {
testIPRWLock(curatorFramework, nonCachedMetricsIPRWLock, NON_CACHED_METRICS_LOCK_PATH);
nonCachedMetricsIP = new DistributedAtomicValue(curatorFramework, NON_CACHED_METRICS, new RetryForever(1000));
try {
nonCachedMetricsIP.forceSet(SerializationUtils.serialize(new TreeSet<>()));
nonCachedMetricsIP.initialize(SerializationUtils.serialize(new TreeSet<>()));
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
TreeCacheListener nonCachedMetricsListener = (cf, event) -> {
if (event.getType().equals(TreeCacheEvent.Type.NODE_UPDATED)) {
LOG.info("Handling nonCachedMetricsIP event {}", event.getType().toString());
readNonCachedMetricsIP();
TreeCacheListener nonCachedMetricsListener = new TreeCacheListener() {
@Override
public void childEvent(CuratorFramework curatorFramework, TreeCacheEvent event) throws Exception {
if (event.getType().equals(TreeCacheEvent.Type.NODE_UPDATED)) {
LOG.info("Handling nonCachedMetricsIP event {}", event.getType().toString());
readNonCachedMetricsIP();
}
}
};
@@ -34,15 +34,17 @@ public class GetMetricTableSplitPoints {
properties.put(ClientProperty.AUTH_PRINCIPAL.getKey(), accumuloConf.getUsername());
properties.put(ClientProperty.AUTH_TOKEN.getKey(), accumuloConf.getPassword());
properties.put(ClientProperty.AUTH_TYPE.getKey(), "password");
try (AccumuloClient accumuloClient = org.apache.accumulo.core.client.Accumulo.newClient().from(properties)
AccumuloClient accumuloClient = org.apache.accumulo.core.client.Accumulo.newClient().from(properties)
.build();
Scanner s = accumuloClient.createScanner(conf.getMetaTable(),
accumuloClient.securityOperations().getUserAuthorizations(accumuloClient.whoami()))) {
Scanner s = accumuloClient.createScanner(conf.getMetaTable(),
accumuloClient.securityOperations().getUserAuthorizations(accumuloClient.whoami()));
try {
s.setRange(new Range(Meta.METRIC_PREFIX, true, Meta.TAG_PREFIX, false));
for (Entry<Key, Value> e : s) {
System.out.println(e.getKey().getRow().toString().substring(Meta.METRIC_PREFIX.length()));
}
} finally {
s.close();
}
}
}
+2 -3
View File
@@ -11,7 +11,6 @@ import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import org.apache.accumulo.core.client.AccumuloClient;
import timely.configuration.Configuration;
import timely.netty.http.NonSslRedirectHandler;
import timely.netty.tcp.MetricsBufferDecoder;
@@ -26,8 +25,8 @@ public class TestServer extends Server {
private final TestCaptureRequestHandler httpRequests = new TestCaptureRequestHandler();
private final TestCaptureRequestHandler udpRequests = new TestCaptureRequestHandler();
public TestServer(Configuration conf, AccumuloClient accumuloClient) {
super(conf, accumuloClient, 1);
public TestServer(Configuration conf) throws Exception {
super(conf, 1);
}
@Override
@@ -1,14 +1,12 @@
package timely.api.response.timeseries;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import timely.api.request.timeseries.SearchLookupRequest;
import timely.api.response.timeseries.SearchLookupResponse.Result;
import timely.model.Tag;
import timely.util.JsonUtil;
public class SearchLookupResponseTest {
@@ -44,11 +42,14 @@ public class SearchLookupResponseTest {
}
@Test
public void testMetricRequest() throws Exception {
String r = "{\"operation\":\"lookup\", \"metric\":\"testmetric\", \"tags\":[{\"host\":\".*\"}]}";
SearchLookupRequest req = JsonUtil.getObjectMapper().readValue(r, SearchLookupRequest.class);
Assert.assertEquals("testmetric", req.getQuery());
Assert.assertEquals(Collections.singletonList(new Tag("host", ".*")), req.getTags());
public void testMetricRequest() {
try {
String r = "{\"operation\":\"lookup\", \"metric\":\"testmetric\", \"tags\":[{\"host\":\".*\"}]}";
SearchLookupRequest req = JsonUtil.getObjectMapper().readValue(r, SearchLookupRequest.class);
System.out.println(req);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -252,7 +252,7 @@ public class DownsampleIteratorTest {
iter.seek(new Range(), Collections.emptyList(), true);
boolean hasTop = iter.hasTop();
assertTrue(hasTop);
Key key;
Key key = null;
Map<Set<Tag>, Downsample> samples = new HashMap<>();
do {
Map<Set<Tag>, Downsample> currentSamples = DownsampleIterator.decodeValue(iter.getTopValue());
@@ -269,7 +269,6 @@ public class DownsampleIteratorTest {
}
}
key = iter.getTopKey();
iter.next();
} while (iter.hasTop());
assertEquals(testData.lastKey(), key);
+26 -11
View File
@@ -1,7 +1,5 @@
package timely.store.cache;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -22,24 +20,37 @@ public class TestGorillaStore {
}
@Test
public void testGorillaStore() {
public void testOne() {
GorillaStore gStore = new GorillaStore("", Long.MAX_VALUE);
Double[] valueArray = new Double[] { 1.123, 2.314, 3.856, 4.7678, 5.8966, 6.0976, 1.2345, 2.3456, 3.4567 };
List<Double> values = new ArrayList<>(Arrays.asList(valueArray));
long now = System.currentTimeMillis();
for (Double d : values) {
gStore.addValue(now += 100, d);
}
gStore.addValue(now += 100, 1.123);
gStore.addValue(now += 100, 2.314);
gStore.addValue(now += 100, 3.856);
gStore.addValue(now += 100, 4.7678);
gStore.addValue(now += 100, 5.8966);
gStore.addValue(now += 100, 6.0976);
gStore.addValue(now += 100, 1.2345);
List<WrappedGorillaDecompressor> decompressorList = gStore.getDecompressors(0, Long.MAX_VALUE);
Pair pair;
int x = 0;
for (WrappedGorillaDecompressor w : decompressorList) {
while ((pair = w.readPair()) != null) {
Assert.assertEquals(values.get(x++).doubleValue(), pair.getDoubleValue(), 0);
System.out.println(pair.getTimestamp() + " --> " + pair.getDoubleValue());
}
}
System.out.println("---------------");
gStore.addValue(now += 100, 2.3456);
gStore.addValue(now += 100, 3.4567);
decompressorList = gStore.getDecompressors(0, Long.MAX_VALUE);
pair = null;
for (WrappedGorillaDecompressor w : decompressorList) {
while ((pair = w.readPair()) != null) {
System.out.println(pair.getTimestamp() + " --> " + pair.getDoubleValue());
}
}
}
@@ -57,6 +68,7 @@ public class TestGorillaStore {
for (int x = 1; x <= 100; x++) {
System.out.println("adding value x:" + x);
gStore.addValue(timestamp, 2.0);
timestamp = timestamp + 1000;
@@ -67,6 +79,7 @@ public class TestGorillaStore {
continue;
}
System.out.println("fetching values x:" + x);
long totalObservations = 0;
List<WrappedGorillaDecompressor> decompressorList = gStore.getDecompressors(start, timestamp);
@@ -75,7 +88,9 @@ public class TestGorillaStore {
totalObservations++;
}
}
Assert.assertEquals("Unexpected number of total observations", x, totalObservations);
}
}
@@ -10,6 +10,7 @@ import timely.api.response.TimelyException;
import timely.api.response.timeseries.QueryResponse;
import timely.configuration.Configuration;
import timely.model.Metric;
import timely.model.ObjectSizeOf;
import timely.model.Tag;
import timely.model.Value;
@@ -55,6 +56,7 @@ public class TestMemoryDataStore {
}
mmStore.flushCaches(-1);
return mmStore;
}
private DataStoreCache getMetricMemoryStore2(long baseTimestamp) throws TimelyException {
@@ -67,20 +69,26 @@ public class TestMemoryDataStore {
tags.put("rack", "r01n01");
tags.put("instance", "sample");
boolean debug = false;
System.out.println("bytesUsed=" + ObjectSizeOf.Sizer.getObjectSize(mmStore, true, debug));
Random r = new Random();
long timestamp = baseTimestamp;
for (int x = 0; x <= 60 * 24; x++) {
mmStore.store(createMetric("metric.number.1", tags, r.nextInt(1000), timestamp + (x * 1000)));
if (x == 0) {
System.out.println("bytesUsed=" + ObjectSizeOf.Sizer.getObjectSize(mmStore, true, debug));
}
}
System.out.println("bytesUsed=" + ObjectSizeOf.Sizer.getObjectSize(mmStore, true, debug));
mmStore.flushCaches(-1);
return mmStore;
}
@Test
public void testFiveSecondDownsample() throws TimelyException {
public void testOne() throws TimelyException {
// 5 second boundary so that we know how many downsamples to expect
long now = (System.currentTimeMillis() / 5000) * 5000;
long now = System.currentTimeMillis();
DataStoreCache mmStore = getMetricMemoryStore1(now);
QueryRequest query = new QueryRequest();
@@ -93,21 +101,20 @@ public class TestMemoryDataStore {
subQuery.addTag("host", ".*");
query.setQueries(Collections.singleton(subQuery));
List<QueryResponse> responseList = mmStore.query(query);
Assert.assertEquals(3, responseList.size());
int downsamples = 0;
for (QueryResponse r : responseList) {
Assert.assertEquals("mymetric", r.getMetric());
downsamples += r.getDps().size();
try {
List<QueryResponse> responseList = mmStore.query(query);
for (QueryResponse response : responseList) {
System.out.println(response.toString());
}
} catch (TimelyException e) {
e.printStackTrace();
}
Assert.assertEquals(8, downsamples);
}
@Test
public void testFiveMinuteDownsample() throws TimelyException {
public void testStorage() throws TimelyException {
// 5 minute boundary so that we know how many downsamples to expect
long now = (System.currentTimeMillis() / 300000) * 300000;
long now = System.currentTimeMillis();
DataStoreCache mmStore = getMetricMemoryStore2(now);
QueryRequest query = new QueryRequest();
@@ -120,20 +127,16 @@ public class TestMemoryDataStore {
subQuery.addTag("host", ".*");
query.setQueries(Collections.singleton(subQuery));
List<QueryResponse> responseList = mmStore.query(query);
Assert.assertEquals(1, responseList.size());
QueryResponse r = responseList.get(0);
Assert.assertEquals("metric.number.1", r.getMetric());
Assert.assertEquals(5, r.getDps().size());
try {
List<QueryResponse> responseList = mmStore.query(query);
for (QueryResponse response : responseList) {
System.out.println(response.toString());
}
} catch (TimelyException e) {
e.printStackTrace();
}
}
/*
* timely.api.response.timeseries.QueryResponse@4263b080[metric=metric.number.1,
* tags={host=r01n01},aggregatedTags=[],dps={1700008200000=484.239837398374,
* 1700008500000=469.02666666666664, 1700008800000=499.17,
* 1700009100000=504.14666666666665, 1700009400000=469.8576271186441}]
*/
private Metric createMetric(String metric, Map<String, String> tags, double value, long timestamp) {
Metric m = new Metric();
m.setName(metric);
@@ -18,13 +18,9 @@ import org.apache.hadoop.fs.Path;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestWrappedGorillaCompressor {
private static final Logger LOG = LoggerFactory.getLogger(TestWrappedGorillaCompressor.class);
@Test
public void testSerialization() throws IOException, ClassNotFoundException {
@@ -86,13 +82,13 @@ public class TestWrappedGorillaCompressor {
GorillaDecompressor d = new GorillaDecompressor(new LongArrayInput(c.getCompressorOutput()));
LinkedList<Pair> q = new LinkedList<>();
Pair p;
Pair p = null;
while ((p = d.readPair()) != null) {
q.add(p);
}
}
} catch (Exception e) {
LOG.error(e.getMessage(), e);
System.out.println(e.getMessage());
}
}
}
@@ -34,7 +34,7 @@ public class TimeSeriesGroupingIteratorTest extends IteratorTestBase {
@Before
public void setup() {
table.clear();
long ts = ((System.currentTimeMillis() / 1000) * 1000);
long ts = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
ts += 1000;
Metric m = new Metric("sys.cpu.user", ts, i * 1.0D, tags);
@@ -80,7 +80,7 @@ public class TimeSeriesGroupingIteratorTest extends IteratorTestBase {
@Test
public void testMultipleTimeSeriesMovingAverage() throws Exception {
table.clear();
long ts = ((System.currentTimeMillis() / 1000) * 1000);
long ts = System.currentTimeMillis();
List<Tag> tags1 = new ArrayList<>();
tags1.add(new Tag("host", "r01n01"));
List<Tag> tags2 = new ArrayList<>();
@@ -122,7 +122,7 @@ public class TimeSeriesGroupingIteratorTest extends IteratorTestBase {
@Test
public void testTimeSeriesDropOff() throws Exception {
table.clear();
long ts = ((System.currentTimeMillis() / 1000) * 1000);
long ts = System.currentTimeMillis();
List<Tag> tags1 = new ArrayList<>();
tags1.add(new Tag("host", "r01n01"));
List<Tag> tags2 = new ArrayList<>();
@@ -167,7 +167,7 @@ public class TimeSeriesGroupingIteratorTest extends IteratorTestBase {
@Test
public void testAdditionalTimeSeries() throws Exception {
table.clear();
long ts = ((System.currentTimeMillis() / 1000) * 1000);
long ts = System.currentTimeMillis();
List<Tag> tags1 = new ArrayList<>();
tags1.add(new Tag("host", "r01n01"));
List<Tag> tags2 = new ArrayList<>();
@@ -213,7 +213,7 @@ public class TimeSeriesGroupingIteratorTest extends IteratorTestBase {
@Test
public void testManySparseTimeSeries() throws Exception {
table.clear();
long ts = ((System.currentTimeMillis() / 1000) * 1000);
long ts = System.currentTimeMillis();
List<Tag> tags1 = new ArrayList<>();
tags1.add(new Tag("host", "r01n01"));
List<Tag> tags2 = new ArrayList<>();
@@ -3,19 +3,19 @@ package timely.test.integration;
import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterruptibly;
import static org.junit.Assert.assertEquals;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import timely.Server;
import timely.api.request.timeseries.QueryRequest;
import timely.api.request.timeseries.QueryRequest.SubQuery;
import timely.api.response.timeseries.QueryResponse;
import timely.configuration.Configuration;
import timely.store.MetricAgeOffIterator;
import timely.store.cache.DataStoreCache;
import timely.test.IntegrationTest;
@@ -25,27 +25,18 @@ public class DataStoreIT extends OneWaySSLBase {
private static final long ONE_DAY = TimeUnit.DAYS.toMillis(1);
private static final long ONE_HOUR = TimeUnit.HOURS.toMillis(1);
private static final Long TEST_TIME = ((System.currentTimeMillis() / 1000) * 1000) - ONE_DAY;
@After
public void shutdown() {
stopServer();
}
private static final long TEST_TIME = System.currentTimeMillis() - ONE_DAY;
@Test
public void testDefaultAgeOffWithoutCache() throws Exception {
conf.getCache().setEnabled(false);
conf.setMetricAgeOffDays(Collections.singletonMap(MetricAgeOffIterator.DEFAULT_AGEOFF_KEY, 1));
startServer();
testDefaultAgeOff();
testDefaultAgeOff(conf);
}
@Test
public void testDefaultAgeOffWithCache() throws Exception {
conf.getCache().setEnabled(true);
conf.setMetricAgeOffDays(Collections.singletonMap(MetricAgeOffIterator.DEFAULT_AGEOFF_KEY, 1));
startServer();
testDefaultAgeOff();
testDefaultAgeOff(conf);
}
@Test
@@ -59,59 +50,66 @@ public class DataStoreIT extends OneWaySSLBase {
HashMap<String, Integer> ageOffHours = new HashMap<>();
ageOffHours.put(DataStoreCache.DEFAULT_AGEOFF_KEY, 23);
conf.getCache().setMetricAgeOffHours(ageOffHours);
conf.setMetricAgeOffDays(Collections.singletonMap(MetricAgeOffIterator.DEFAULT_AGEOFF_KEY, 1));
startServer();
testDefaultAgeOff();
testDefaultAgeOff(conf);
}
public void testDefaultAgeOff() throws Exception {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + ONE_HOUR) + " 3.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + (ONE_HOUR * 2)) + " 2.0 tag1=value1 tag3=value3");
// Latency in TestConfiguration is 2s, wait for it
sleepUninterruptibly(4, TimeUnit.SECONDS);
QueryRequest request = new QueryRequest();
request.setStart(TEST_TIME);
request.setEnd(TEST_TIME + (24 * ONE_HOUR));
SubQuery subQuery = new SubQuery();
subQuery.setMetric("sys.cpu.user");
subQuery.addTag("tag1", ".*");
subQuery.setDownsample(Optional.of("1s-max"));
request.addQuery(subQuery);
List<QueryResponse> response = query("https://127.0.0.1:54322/api/query", request);
public void testDefaultAgeOff(Configuration conf) throws Exception {
HashMap<String, Integer> ageOffSettings = new HashMap<>();
ageOffSettings.put(MetricAgeOffIterator.DEFAULT_AGEOFF_KEY, 1);
conf.setMetricAgeOffDays(ageOffSettings);
assertEquals(1, response.size());
Map<String, String> tags = response.get(0).getTags();
assertEquals(1, tags.size());
assertEquals("value1", tags.get("tag1"));
Map<String, Object> dps = response.get(0).getDps();
assertEquals(2, dps.size());
final Server s = new Server(conf);
s.run();
try {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + ONE_HOUR) + " 3.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + (ONE_HOUR * 2)) + " 2.0 tag1=value1 tag3=value3");
// Latency in TestConfiguration is 2s, wait for it
sleepUninterruptibly(4, TimeUnit.SECONDS);
QueryRequest request = new QueryRequest();
request.setStart(TEST_TIME);
request.setEnd(TEST_TIME + (24 * ONE_HOUR));
SubQuery subQuery = new SubQuery();
subQuery.setMetric("sys.cpu.user");
subQuery.addTag("tag1", ".*");
subQuery.setDownsample(Optional.of("1s-max"));
request.addQuery(subQuery);
List<QueryResponse> response = query("https://127.0.0.1:54322/api/query", request);
assertEquals(1, response.size());
Map<String, String> tags = response.get(0).getTags();
assertEquals(1, tags.size());
assertEquals("value1", tags.get("tag1"));
Map<String, Object> dps = response.get(0).getDps();
assertEquals(2, dps.size());
} finally {
s.shutdown();
}
}
@Test
public void testMultipleAgeOffWithoutCache() throws Exception {
conf.getCache().setEnabled(false);
conf.setMetricAgeOffDays(Collections.singletonMap(MetricAgeOffIterator.DEFAULT_AGEOFF_KEY, 1));
startServer();
testDefaultAgeOff();
testMultipleAgeOff(conf);
}
@Test
public void testMultipleAgeOffWithCache() throws Exception {
conf.getCache().setEnabled(true);
testMultipleAgeOff(conf);
}
public void testMultipleAgeOff(Configuration conf) throws Exception {
HashMap<String, Integer> ageOffSettings = new HashMap<>();
ageOffSettings.put(MetricAgeOffIterator.DEFAULT_AGEOFF_KEY, 1);
ageOffSettings.put("sys.cpu.user", 1);
conf.setMetricAgeOffDays(ageOffSettings);
startServer();
testMultipleAgeOff();
}
public void testMultipleAgeOff() throws Exception {
final Server s = new Server(conf);
s.run();
// @formatter:off
/*
* TEST_TIME = ((System.currentTimeMillis() / 1000) * 1000) - ONE_DAY
* TEST_TIME = System.currentTimeMillis() - ONE_DAY
* Age off for all metrics is one day = 24 hours
*
* lines 1, 2, 3 will age off immediately as they are >= 2 days old
@@ -121,41 +119,46 @@ public class DataStoreIT extends OneWaySSLBase {
*
*/
// @formatter:on
put("sys.cpu.idle " + (TEST_TIME - ONE_DAY - (2 * ONE_HOUR)) + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.idle " + (TEST_TIME - ONE_DAY - ONE_HOUR) + " 3.0 tag1=value1 tag2=value2",
"sys.cpu.idle " + (TEST_TIME - ONE_DAY) + " 2.0 tag1=value1 tag3=value3",
"sys.cpu.idle " + (TEST_TIME + (ONE_DAY * 2)) + " 2.0 tag1=value1 tag3=value3",
"sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + ONE_HOUR) + " 3.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + (ONE_HOUR * 2)) + " 2.0 tag1=value1 tag3=value3");
// Latency in TestConfiguration is 2s, wait for it
sleepUninterruptibly(4, TimeUnit.SECONDS);
QueryRequest request = new QueryRequest();
request.setStart(TEST_TIME - ONE_DAY - (2 * ONE_HOUR));
request.setEnd(TEST_TIME + (24 * ONE_HOUR));
SubQuery subQuery = new SubQuery();
subQuery.setMetric("sys.cpu.user");
subQuery.addTag("tag1", ".*");
subQuery.setDownsample(Optional.of("1s-max"));
request.addQuery(subQuery);
List<QueryResponse> response = query("https://127.0.0.1:54322/api/query", request);
assertEquals(1, response.size());
Map<String, String> tags = response.get(0).getTags();
assertEquals(1, tags.size());
assertEquals("value1", tags.get("tag1"));
Map<String, Object> dps = response.get(0).getDps();
assertEquals(2, dps.size());
try {
put("sys.cpu.idle " + (TEST_TIME - ONE_DAY - (2 * ONE_HOUR)) + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.idle " + (TEST_TIME - ONE_DAY - ONE_HOUR) + " 3.0 tag1=value1 tag2=value2",
"sys.cpu.idle " + (TEST_TIME - ONE_DAY) + " 2.0 tag1=value1 tag3=value3",
"sys.cpu.idle " + (TEST_TIME + (ONE_DAY * 2)) + " 2.0 tag1=value1 tag3=value3",
"sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + ONE_HOUR) + " 3.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + (ONE_HOUR * 2)) + " 2.0 tag1=value1 tag3=value3");
// Latency in TestConfiguration is 2s, wait for it
sleepUninterruptibly(4, TimeUnit.SECONDS);
QueryRequest request = new QueryRequest();
request.setStart(TEST_TIME - ONE_DAY - (2 * ONE_HOUR));
request.setEnd(TEST_TIME + (24 * ONE_HOUR));
SubQuery subQuery = new SubQuery();
subQuery.setMetric("sys.cpu.user");
subQuery.addTag("tag1", ".*");
subQuery.setDownsample(Optional.of("1s-max"));
request.addQuery(subQuery);
List<QueryResponse> response = query("https://127.0.0.1:54322/api/query", request);
assertEquals(1, response.size());
Map<String, String> tags = response.get(0).getTags();
assertEquals(1, tags.size());
assertEquals("value1", tags.get("tag1"));
Map<String, Object> dps = response.get(0).getDps();
assertEquals(2, dps.size());
QueryRequest request2 = new QueryRequest();
request2.setStart(TEST_TIME - ONE_DAY - (2 * ONE_HOUR));
request2.setEnd(TEST_TIME + (24 * ONE_HOUR));
SubQuery subQuery2 = new SubQuery();
subQuery2.setMetric("sys.cpu.idle");
subQuery2.addTag("tag1", ".*");
subQuery2.setDownsample(Optional.of("1s-max"));
request2.addQuery(subQuery2);
List<QueryResponse> response2 = query("https://127.0.0.1:54322/api/query", request2);
assertEquals(0, response2.size());
QueryRequest request2 = new QueryRequest();
request2.setStart(TEST_TIME - ONE_DAY - (2 * ONE_HOUR));
request2.setEnd(TEST_TIME + (24 * ONE_HOUR));
SubQuery subQuery2 = new SubQuery();
subQuery2.setMetric("sys.cpu.idle");
subQuery2.addTag("tag1", ".*");
subQuery2.setDownsample(Optional.of("1s-max"));
request2.addQuery(subQuery2);
List<QueryResponse> response2 = query("https://127.0.0.1:54322/api/query", request2);
assertEquals(0, response2.size());
} finally {
s.shutdown();
}
}
}
@@ -1,158 +0,0 @@
package timely.test.integration;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Properties;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import datawave.accumulo.inmemory.InMemoryAccumuloClient;
import datawave.accumulo.inmemory.InMemoryInstance;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.hadoop.io.Text;
import org.apache.zookeeper.server.ServerConfig;
import org.apache.zookeeper.server.ZooKeeperServerMain;
import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.Server;
import timely.auth.AuthCache;
import timely.configuration.Configuration;
import timely.store.MetricAgeOffIterator;
import timely.test.TestConfiguration;
/**
* Base class for integration tests using in-memory-accumulo.
*/
public class InMemoryITBase {
private static final Logger LOG = LoggerFactory.getLogger(InMemoryITBase.class);
protected static final String ROOT_USER = "root";
protected static final String ROOT_PASSWORD = "secret";
protected Configuration conf = null;
protected AccumuloClient accumuloClient;
protected Server s;
private ZooKeeperServerMain zookeeper;
private Future zooFuture;
@BeforeClass
public static void setupInMemoryAccumulo() throws Exception {
InMemoryInstance instance = new InMemoryInstance();
try {
AccumuloClient accumuloClient = new InMemoryAccumuloClient(ROOT_USER, instance);
accumuloClient.securityOperations().changeUserAuthorizations(accumuloClient.whoami(),
new Authorizations("PUBLIC", "A", "B", "C"));
} catch (AccumuloSecurityException e) {
LOG.error(e.getMessage(), e);
}
}
@Before
public void startupInMemoryBase() throws Exception {
AuthCache.clear();
clearTablesResetConf();
InMemoryInstance instance = new InMemoryInstance();
accumuloClient = new InMemoryAccumuloClient(ROOT_USER, instance);
File tempDir;
try {
tempDir = Files.createTempDirectory("zookeeper_temp").toFile();
tempDir.deleteOnExit();
} catch (IOException e) {
throw new RuntimeException("Unable to create temp directory for mini accumulo cluster");
}
Properties properties = new Properties();
properties.put("dataDir", tempDir.getAbsolutePath() + "/data");
properties.put("clientPort", "2181");
properties.put("skipACL", "true");
properties.put("leaderServes", "yes");
properties.put("4lw.commands.whitelist", "*");
QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig();
quorumPeerConfig.parseProperties(properties);
zookeeper = new ZooKeeperServerMain();
final ServerConfig config = new ServerConfig();
config.readFrom(quorumPeerConfig);
zooFuture = Executors.newSingleThreadExecutor().submit(() -> {
try {
zookeeper.runFromConfig(config);
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
});
}
protected void stopServer() {
if (s != null) {
s.setAccumuloClient(null);
s.shutdown();
}
}
@After
public void shutdownInMemoryBase() {
if (zookeeper != null) {
zookeeper.close();
}
if (zooFuture != null) {
zooFuture.cancel(true);
}
}
private void clearTablesResetConf() throws Exception {
InMemoryInstance instance = new InMemoryInstance();
AccumuloClient accumuloClient = new InMemoryAccumuloClient(ROOT_USER, instance);
accumuloClient.tableOperations().list().forEach(t -> {
if (t.startsWith("timely")) {
try {
accumuloClient.tableOperations().delete(t);
} catch (Exception e) {
}
}
});
// Reset configuration
conf = TestConfiguration.createMinimalConfigurationForTest();
conf.getAccumulo().setInstanceName(instance.getInstanceName());
conf.getAccumulo().setZookeepers(instance.getZooKeepers());
conf.getSecurity().getServerSsl().setUseOpenssl(false);
conf.getSecurity().getServerSsl().setUseGeneratedKeypair(true);
conf.getWebsocket().setFlushIntervalSeconds(TestConfiguration.WAIT_SECONDS);
HashMap<String, Integer> ageOffSettings = new HashMap<>();
ageOffSettings.put(MetricAgeOffIterator.DEFAULT_AGEOFF_KEY, 7);
conf.setMetricAgeOffDays(ageOffSettings);
// }
}
protected void deleteAccumuloEntries() throws Exception {
InMemoryInstance instance = new InMemoryInstance();
AccumuloClient accumuloClient = new InMemoryAccumuloClient(ROOT_USER, instance);
accumuloClient.tableOperations().list().forEach(t -> {
if (t.startsWith("timely")) {
try {
accumuloClient.tableOperations().deleteRows(t, new Text("#"), new Text("~"));
} catch (Exception e) {
}
}
});
}
protected void startServer() {
try {
s = new Server(conf, accumuloClient);
s.run();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@@ -9,12 +9,10 @@ import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.minicluster.MiniAccumuloCluster;
import org.apache.accumulo.minicluster.MiniAccumuloConfig;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.Server;
import timely.auth.AuthCache;
import timely.configuration.Configuration;
import timely.store.MetricAgeOffIterator;
@@ -41,10 +39,8 @@ public class MacITBase {
tempDir.deleteOnExit();
}
private static MiniAccumuloCluster mac = null;
protected static MiniAccumuloCluster mac = null;
protected static Configuration conf = null;
protected AccumuloClient accumuloClient;
protected Server s;
@BeforeClass
public static void setupMiniAccumulo() throws Exception {
@@ -52,19 +48,22 @@ public class MacITBase {
final MiniAccumuloConfig macConfig = new MiniAccumuloConfig(tempDir, MAC_ROOT_PASSWORD);
mac = new MiniAccumuloCluster(macConfig);
mac.start();
conf = TestConfiguration.createMinimalConfigurationForTest();
conf.getAccumulo().setInstanceName(mac.getInstanceName());
conf.getAccumulo().setZookeepers(mac.getZooKeepers());
conf.getSecurity().getServerSsl().setUseOpenssl(false);
conf.getSecurity().getServerSsl().setUseGeneratedKeypair(true);
conf.getWebsocket().setFlushIntervalSeconds(TestConfiguration.WAIT_SECONDS);
HashMap<String, Integer> ageOffSettings = new HashMap<>();
ageOffSettings.put(MetricAgeOffIterator.DEFAULT_AGEOFF_KEY, 7);
conf.setMetricAgeOffDays(ageOffSettings);
} else {
LOG.info("Mini Accumulo already running.");
}
}
@Before
public void setupMacITBase() {
AuthCache.clear();
clearTablesResetConf();
accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER, new PasswordToken(MAC_ROOT_PASSWORD));
}
private void clearTablesResetConf() {
public void clearTablesResetConf() throws Exception {
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.tableOperations().list().forEach(t -> {
@@ -88,26 +87,8 @@ public class MacITBase {
conf.setMetricAgeOffDays(ageOffSettings);
}
protected void startServer() throws Exception {
s = new Server(conf, accumuloClient);
s.run();
}
protected void stopServer() {
if (s != null) {
s.shutdown();
}
}
@After
public void shutdown() {
if (accumuloClient != null) {
accumuloClient.close();
accumuloClient = null;
}
if (s != null) {
s.shutdown();
}
@Before
public void initializeAuthCache() {
AuthCache.clear();
}
}
@@ -16,18 +16,20 @@ import java.util.stream.Collectors;
import com.google.common.collect.Sets;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.IteratorSetting;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.conf.Property;
import org.apache.accumulo.core.iterators.IteratorUtil;
import org.apache.accumulo.tserver.compaction.CompactionStrategy;
import org.apache.accumulo.tserver.compaction.DefaultCompactionStrategy;
import org.apache.hadoop.io.Text;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.auth.AuthCache;
import timely.store.MetricAgeOffIterator;
import timely.store.compaction.MetricCompactionStrategy;
import timely.store.compaction.TabletRowAdapter;
@@ -48,11 +50,20 @@ public class MetricCompactionIT extends MacITBase {
private static final EnumSet<IteratorUtil.IteratorScope> AGEOFF_SCOPES = EnumSet
.allOf(IteratorUtil.IteratorScope.class);
private AccumuloClient accumuloClient;
private MetricConfigurationAdapter adapter;
@BeforeClass
public static void setupClass() throws Exception {
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.instanceOperations().setProperty(Property.TSERV_MAJC_DELAY.getKey(), "3s");
}
}
@Before
public void setup() throws Exception {
accumuloClient.instanceOperations().setProperty(Property.TSERV_MAJC_DELAY.getKey(), "3s");
accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER, new PasswordToken(MAC_ROOT_PASSWORD));
String metricsTable = conf.getMetricsTable();
if (!metricsTable.contains(".")) {
throw new IllegalArgumentException("Expected to find namespace in table name");
@@ -67,15 +78,22 @@ public class MetricCompactionIT extends MacITBase {
accumuloClient.tableOperations().setProperty(conf.getMetricsTable(), Property.TABLE_SPLIT_THRESHOLD.getKey(),
"50K");
adapter.resetState();
startServer();
}
@After
public void teardown() throws Exception {
accumuloClient.instanceOperations().setProperty(Property.TSERV_MAJC_DELAY.getKey(), "30s");
adapter.resetState();
AuthCache.resetConfiguration();
stopServer();
if (accumuloClient != null) {
accumuloClient.close();
}
}
@AfterClass
public static void teardownClass() throws Exception {
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.instanceOperations().setProperty(Property.TSERV_MAJC_DELAY.getKey(), "30s");
}
}
@Test
@@ -131,7 +149,7 @@ public class MetricCompactionIT extends MacITBase {
// check to make sure the table has only one iterator
Map<String, EnumSet<IteratorUtil.IteratorScope>> itrs = accumuloClient.tableOperations()
.listIterators(metricsTable);
assertEquals(2, itrs.size());
assertEquals(1, itrs.size());
assertTrue(itrs.containsKey("vers"));
long timestampMax = System.currentTimeMillis();
@@ -215,7 +233,6 @@ public class MetricCompactionIT extends MacITBase {
ageOffs.put("ageoff.default", Long.toString(ageOff));
IteratorSetting ageOffIteratorSettings = new IteratorSetting(100, AGE_OFF_ITERATOR_NAME,
MetricAgeOffIterator.class, ageOffs);
accumuloClient.tableOperations().removeIterator(tableName, AGE_OFF_ITERATOR_NAME, AGEOFF_SCOPES);
accumuloClient.tableOperations().attachIterator(tableName, ageOffIteratorSettings, AGEOFF_SCOPES);
accumuloClient.tableOperations().setProperty(tableName, Property.TABLE_COMPACTION_STRATEGY.getKey(),
clazz.getName());
@@ -8,10 +8,9 @@ import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import timely.Server;
import timely.api.request.timeseries.QueryRequest;
import timely.api.request.timeseries.QueryRequest.SubQuery;
import timely.api.response.timeseries.QueryResponse;
@@ -26,38 +25,34 @@ import timely.test.TestConfiguration;
@Category(IntegrationTest.class)
public class OneWaySSLAnonAccessIT extends OneWaySSLBase {
private static final Long TEST_TIME = (System.currentTimeMillis() / 1000) * 1000;
@Before
public void startup() {
startServer();
}
@After
public void shutdown() {
stopServer();
}
private static final Long TEST_TIME = System.currentTimeMillis();
@Test
public void testQueryWithVisibility() throws Exception {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 1000) + " 3.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 2000) + " 2.0 tag1=value1 tag3=value3 viz=secret");
// Latency in TestConfiguration is 2s, wait for it
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
QueryRequest request = new QueryRequest();
request.setStart(TEST_TIME);
request.setEnd(TEST_TIME + 6000);
SubQuery subQuery = new SubQuery();
subQuery.setMetric("sys.cpu.user");
subQuery.setDownsample(Optional.of("1s-max"));
request.addQuery(subQuery);
List<QueryResponse> response = query("https://127.0.0.1:54322/api/query", request);
assertEquals(1, response.size());
Map<String, String> tags = response.get(0).getTags();
assertEquals(0, tags.size());
Map<String, Object> dps = response.get(0).getDps();
assertEquals(2, dps.size());
final Server s = new Server(conf);
s.run();
try {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 1000) + " 3.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 2000) + " 2.0 tag1=value1 tag3=value3 viz=secret");
// Latency in TestConfiguration is 2s, wait for it
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
QueryRequest request = new QueryRequest();
request.setStart(TEST_TIME);
request.setEnd(TEST_TIME + 6000);
SubQuery subQuery = new SubQuery();
subQuery.setMetric("sys.cpu.user");
subQuery.setDownsample(Optional.of("1s-max"));
request.addQuery(subQuery);
List<QueryResponse> response = query("https://127.0.0.1:54322/api/query", request);
assertEquals(1, response.size());
Map<String, String> tags = response.get(0).getTags();
assertEquals(0, tags.size());
Map<String, Object> dps = response.get(0).getDps();
assertEquals(2, dps.size());
} finally {
s.shutdown();
}
}
}
@@ -26,16 +26,6 @@ public class OneWaySSLBase extends QueryBase {
protected static File clientTrustStoreFile = null;
@Before
public void setupOneWaySSLBase() throws Exception {
setupSSL(conf);
}
@After
public void shutdownOneWaySSLBase() {
AuthCache.resetConfiguration();
}
protected SSLSocketFactory getSSLSocketFactory() throws Exception {
SslContextBuilder builder = SslContextBuilder.forClient();
builder.applicationProtocolConfig(ApplicationProtocolConfig.DISABLED);
@@ -59,6 +49,11 @@ public class OneWaySSLBase extends QueryBase {
config.getSecurity().setAllowAnonymousHttpAccess(true);
}
@Before
public void configureSSL() throws Exception {
setupSSL(conf);
}
@Override
protected HttpsURLConnection getUrlConnection(String username, String password, URL url) throws Exception {
// No username/password needed for anonymous access
@@ -72,4 +67,10 @@ public class OneWaySSLBase extends QueryBase {
con.setHostnameVerifier((host, session) -> true);
return con;
}
@After
public void tearDown() throws Exception {
AuthCache.resetConfiguration();
}
}
@@ -16,12 +16,15 @@ import javax.net.ssl.HttpsURLConnection;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.cookie.ClientCookieDecoder;
import io.netty.handler.codec.http.cookie.Cookie;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.security.Authorizations;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import timely.Server;
import timely.api.request.auth.BasicAuthLoginRequest;
import timely.api.request.timeseries.QueryRequest;
import timely.api.response.timeseries.QueryResponse;
@@ -39,17 +42,7 @@ import timely.util.JsonUtil;
@Category(IntegrationTest.class)
public class OneWaySSLBasicAuthAccessIT extends OneWaySSLBase {
private static final Long TEST_TIME = (System.currentTimeMillis() / 1000) * 1000;
@Before
public void startup() {
startServer();
}
@After
public void shutdown() {
stopServer();
}
private static final Long TEST_TIME = System.currentTimeMillis();
protected HttpsURLConnection getUrlConnection(URL url) throws Exception {
// Username and password are set in src/test/resources/security.xml
@@ -89,8 +82,11 @@ public class OneWaySSLBasicAuthAccessIT extends OneWaySSLBase {
@Before
public void setup() throws Exception {
AuthCache.clear();
accumuloClient.securityOperations().changeUserAuthorizations("root",
new Authorizations("A", "B", "C", "D", "E", "F"));
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.securityOperations().changeUserAuthorizations("root",
new Authorizations("A", "B", "C", "D", "E", "F"));
}
}
@After
@@ -100,39 +96,57 @@ public class OneWaySSLBasicAuthAccessIT extends OneWaySSLBase {
@Test
public void testBasicAuthLogin() throws Exception {
String metrics = "https://localhost:54322/api/metrics";
query(metrics);
final Server s = new Server(conf);
s.run();
try {
String metrics = "https://localhost:54322/api/metrics";
query(metrics);
} finally {
s.shutdown();
}
}
@Test(expected = UnauthorizedUserException.class)
public void testBasicAuthLoginFailure() throws Exception {
String metrics = "https://localhost:54322/api/metrics";
query("test", "test2", metrics);
final Server s = new Server(conf);
s.run();
try {
String metrics = "https://localhost:54322/api/metrics";
query("test", "test2", metrics);
} finally {
s.shutdown();
}
}
@Test
public void testQueryWithVisibility() throws Exception {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 1000) + " 3.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 2000) + " 2.0 tag1=value1 tag3=value3 viz=A",
"sys.cpu.user " + (TEST_TIME + 3000) + " 2.0 tag1=value1 tag3=value3 viz=D",
"sys.cpu.user " + (TEST_TIME + 3000) + " 2.0 tag1=value1 tag3=value3 viz=G");
// Latency in TestConfiguration is 2s, wait for it
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
QueryRequest request = new QueryRequest();
request.setStart(TEST_TIME);
request.setEnd(TEST_TIME + 6000);
QueryRequest.SubQuery subQuery = new QueryRequest.SubQuery();
subQuery.setMetric("sys.cpu.user");
subQuery.setDownsample(Optional.of("1s-max"));
request.addQuery(subQuery);
String metrics = "https://127.0.0.1:54322/api/query";
List<QueryResponse> response = query("test", "test1", metrics, request);
assertEquals(1, response.size());
Map<String, String> tags = response.get(0).getTags();
assertEquals(0, tags.size());
Map<String, Object> dps = response.get(0).getDps();
// test user only has authorities A,B,C. So it does not see D and G.
assertEquals(3, dps.size());
final Server s = new Server(conf);
s.run();
try {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 1000) + " 3.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 2000) + " 2.0 tag1=value1 tag3=value3 viz=A",
"sys.cpu.user " + (TEST_TIME + 3000) + " 2.0 tag1=value1 tag3=value3 viz=D",
"sys.cpu.user " + (TEST_TIME + 3000) + " 2.0 tag1=value1 tag3=value3 viz=G");
// Latency in TestConfiguration is 2s, wait for it
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
QueryRequest request = new QueryRequest();
request.setStart(TEST_TIME);
request.setEnd(TEST_TIME + 6000);
QueryRequest.SubQuery subQuery = new QueryRequest.SubQuery();
subQuery.setMetric("sys.cpu.user");
subQuery.setDownsample(Optional.of("1s-max"));
request.addQuery(subQuery);
String metrics = "https://127.0.0.1:54322/api/query";
List<QueryResponse> response = query("test", "test1", metrics, request);
assertEquals(1, response.size());
Map<String, String> tags = response.get(0).getTags();
assertEquals(0, tags.size());
Map<String, Object> dps = response.get(0).getDps();
// test user only has authorities A,B,C. So it does not see D and G.
assertEquals(3, dps.size());
} finally {
s.shutdown();
}
}
}
@@ -21,7 +21,7 @@ import timely.api.request.timeseries.QueryRequest;
import timely.api.response.timeseries.QueryResponse;
import timely.util.JsonUtil;
public abstract class QueryBase extends InMemoryITBase {
public abstract class QueryBase extends MacITBase {
public static class NotSuccessfulException extends Exception {
@@ -82,7 +82,7 @@ public abstract class QueryBase extends InMemoryITBase {
assertEquals(expectedResponseCode, responseCode);
if (200 == responseCode) {
String result = IOUtils.toString(con.getInputStream(), UTF_8);
LOG.debug("Result is {}", result);
LOG.info("Result is {}", result);
return result;
} else {
throw new NotSuccessfulException();
@@ -109,7 +109,7 @@ public abstract class QueryBase extends InMemoryITBase {
Assert.assertEquals(expectedResponseCode, responseCode);
if (200 == responseCode) {
String result = IOUtils.toString(con.getInputStream(), UTF_8);
LOG.debug("Result is {}", result);
LOG.info("Result is {}", result);
JavaType type = JsonUtil.getObjectMapper().getTypeFactory().constructCollectionType(List.class,
QueryResponse.class);
return JsonUtil.getObjectMapper().readValue(result, type);
@@ -138,7 +138,7 @@ public abstract class QueryBase extends InMemoryITBase {
Assert.assertEquals(expectedResponseCode, responseCode);
if (200 == responseCode) {
String result = IOUtils.toString(con.getInputStream(), UTF_8);
LOG.debug("Result is {}", result);
LOG.info("Result is {}", result);
JavaType type = JsonUtil.getObjectMapper().getTypeFactory().constructCollectionType(List.class,
QueryResponse.class);
return JsonUtil.getObjectMapper().readValue(result, type);
@@ -2,19 +2,23 @@ package timely.test.integration;
import org.junit.*;
import org.junit.experimental.categories.Category;
import timely.Server;
import timely.test.IntegrationTest;
@Category(IntegrationTest.class)
public class StaticFileServerIT extends OneWaySSLBase {
private static Server s = null;
@Before
public void startup() {
startServer();
public void before() throws Exception {
s = new Server(conf);
s.run();
}
@After
public void shutdown() {
stopServer();
public void after() throws Exception {
s.shutdown();
}
@Test(expected = NotSuccessfulException.class)
@@ -1,113 +0,0 @@
package timely.test.integration;
import java.io.File;
import java.net.URL;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.cookie.ClientCookieDecoder;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.ssl.ApplicationProtocolConfig;
import io.netty.handler.ssl.JdkSslContext;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import org.junit.Assert;
import org.junit.Before;
import timely.configuration.Configuration;
import timely.netty.Constants;
/**
* Base test class for SSL with anonymous access
*/
public class TwoWaySSLBase extends QueryBase {
private static File clientTrustStoreFile;
private static SelfSignedCertificate serverCert;
static {
try {
serverCert = new SelfSignedCertificate();
clientTrustStoreFile = serverCert.certificate().getAbsoluteFile();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Before
public void startupTwoWaySSLBase() throws Exception {
setupSSL(conf);
}
public SelfSignedCertificate getServerCert() {
return serverCert;
}
protected File getClientTrustStoreFile() {
return clientTrustStoreFile;
}
protected SSLSocketFactory getSSLSocketFactory() throws Exception {
SelfSignedCertificate serverCert = getServerCert();
File clientTrustStoreFile = getClientTrustStoreFile();
SslContextBuilder builder = SslContextBuilder.forClient();
builder.applicationProtocolConfig(ApplicationProtocolConfig.DISABLED);
// Use server cert / key on client side.
builder.keyManager(serverCert.key(), (String) null, serverCert.cert());
builder.sslProvider(SslProvider.JDK);
builder.trustManager(clientTrustStoreFile); // Trust the server cert
SslContext ctx = builder.build();
Assert.assertTrue(ctx.isClient());
Assert.assertTrue(ctx instanceof JdkSslContext);
JdkSslContext jdk = (JdkSslContext) ctx;
SSLContext jdkSslContext = jdk.context();
return jdkSslContext.getSocketFactory();
}
protected void setupSSL(Configuration config) {
SelfSignedCertificate serverCert = getServerCert();
config.getSecurity().getServerSsl().setCertificateFile(serverCert.certificate().getAbsolutePath());
config.getSecurity().getServerSsl().setKeyFile(serverCert.privateKey().getAbsolutePath());
// Needed for 2way SSL
config.getSecurity().getServerSsl().setTrustStoreFile(serverCert.certificate().getAbsolutePath());
config.getSecurity().getServerSsl().setUseOpenssl(false);
config.getSecurity().getServerSsl().setUseGeneratedKeypair(false);
config.getSecurity().setAllowAnonymousHttpAccess(false);
}
@Override
protected HttpsURLConnection getUrlConnection(URL url) throws Exception {
// Username and password not used in 2way SSL case
return getUrlConnection(null, null, url);
}
@Override
protected HttpsURLConnection getUrlConnection(String username, String password, URL url) throws Exception {
HttpsURLConnection.setDefaultSSLSocketFactory(getSSLSocketFactory());
URL loginURL = new URL(url.getProtocol() + "://" + url.getHost() + ":" + url.getPort() + "/login");
HttpsURLConnection con = (HttpsURLConnection) loginURL.openConnection();
con.setHostnameVerifier((arg0, arg1) -> true);
con.setRequestMethod("GET");
con.setDoOutput(true);
con.setRequestProperty("Content-Type", "application/json");
con.connect();
int responseCode = con.getResponseCode();
if (401 == responseCode) {
throw new UnauthorizedUserException();
}
Assert.assertEquals(200, responseCode);
List<String> cookies = con.getHeaderFields().get(HttpHeaderNames.SET_COOKIE.toString());
Assert.assertEquals(1, cookies.size());
Cookie sessionCookie = ClientCookieDecoder.STRICT.decode(cookies.get(0));
Assert.assertEquals(Constants.COOKIE_NAME, sessionCookie.name());
con = (HttpsURLConnection) url.openConnection();
con.setRequestProperty(HttpHeaderNames.COOKIE.toString(), sessionCookie.name() + "=" + sessionCookie.value());
con.setHostnameVerifier((arg0, arg1) -> true);
return con;
}
}
@@ -1,58 +1,178 @@
package timely.test.integration;
import java.io.File;
import java.net.URL;
import java.util.List;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.cookie.ClientCookieDecoder;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.ssl.ApplicationProtocolConfig;
import io.netty.handler.ssl.JdkSslContext;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.minicluster.MiniAccumuloCluster;
import org.apache.accumulo.minicluster.MiniAccumuloConfig;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import timely.Server;
import timely.auth.AuthCache;
import timely.configuration.Configuration;
import timely.netty.Constants;
import timely.test.TestConfiguration;
public class TwoWaySSLFailureIT extends TwoWaySSLBase {
public class TwoWaySSLFailureIT extends QueryBase {
private static File clientTrustStoreFile;
private static SelfSignedCertificate serverCert;
@ClassRule
public static final TemporaryFolder temp = new TemporaryFolder();
private static MiniAccumuloCluster mac = null;
private static Configuration conf = null;
private static SelfSignedCertificate serverCert = null;
private static File clientTrustStoreFile = null;
static {
try {
// This fqdn does not match what is in security.xml
serverCert = new SelfSignedCertificate("CN=bad.example.com");
clientTrustStoreFile = serverCert.certificate().getAbsoluteFile();
} catch (Exception e) {
throw new RuntimeException(e);
throw new RuntimeException("Error creating self signed certificate", e);
}
}
public SelfSignedCertificate getServerCert() {
return serverCert;
protected SSLSocketFactory getSSLSocketFactory() throws Exception {
SslContextBuilder builder = SslContextBuilder.forClient();
builder.applicationProtocolConfig(ApplicationProtocolConfig.DISABLED);
// Use server cert / key on client side
builder.keyManager(serverCert.key(), (String) null, serverCert.cert());
builder.sslProvider(SslProvider.JDK);
builder.trustManager(clientTrustStoreFile); // Trust the server cert
SslContext ctx = builder.build();
Assert.assertTrue(ctx.isClient());
Assert.assertTrue(ctx instanceof JdkSslContext);
JdkSslContext jdk = (JdkSslContext) ctx;
SSLContext jdkSslContext = jdk.context();
return jdkSslContext.getSocketFactory();
}
protected File getClientTrustStoreFile() {
return clientTrustStoreFile;
protected static void setupSSL(Configuration config) throws Exception {
config.getSecurity().getServerSsl().setCertificateFile(serverCert.certificate().getAbsolutePath());
config.getSecurity().getServerSsl().setKeyFile(serverCert.privateKey().getAbsolutePath());
// Needed for 2way SSL
config.getSecurity().getServerSsl().setTrustStoreFile(serverCert.certificate().getAbsolutePath());
config.getSecurity().getServerSsl().setUseOpenssl(false);
config.getSecurity().getServerSsl().setUseGeneratedKeypair(false);
config.getSecurity().setAllowAnonymousHttpAccess(false);
}
@Override
protected HttpsURLConnection getUrlConnection(URL url) throws Exception {
// Username and password not used in 2way SSL case
return getUrlConnection(null, null, url);
}
@Override
protected HttpsURLConnection getUrlConnection(String username, String password, URL url) throws Exception {
HttpsURLConnection.setDefaultSSLSocketFactory(getSSLSocketFactory());
URL loginURL = new URL(url.getProtocol() + "://" + url.getHost() + ":" + url.getPort() + "/login");
HttpsURLConnection con = (HttpsURLConnection) loginURL.openConnection();
con.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
con.setRequestMethod("GET");
con.setDoOutput(true);
con.setRequestProperty("Content-Type", "application/json");
con.connect();
int responseCode = con.getResponseCode();
if (401 == responseCode) {
throw new UnauthorizedUserException();
}
Assert.assertEquals(200, responseCode);
List<String> cookies = con.getHeaderFields().get(HttpHeaderNames.SET_COOKIE.toString());
Assert.assertEquals(1, cookies.size());
Cookie sessionCookie = ClientCookieDecoder.STRICT.decode(cookies.get(0));
Assert.assertEquals(Constants.COOKIE_NAME, sessionCookie.name());
con = (HttpsURLConnection) url.openConnection();
con.setRequestProperty(HttpHeaderNames.COOKIE.toString(), sessionCookie.name() + "=" + sessionCookie.value());
con.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
return con;
}
@BeforeClass
public static void beforeClass() throws Exception {
temp.create();
final MiniAccumuloConfig macConfig = new MiniAccumuloConfig(temp.newFolder("mac"), "secret");
mac = new MiniAccumuloCluster(macConfig);
mac.start();
conf = TestConfiguration.createMinimalConfigurationForTest();
conf.getAccumulo().setInstanceName(mac.getInstanceName());
conf.getAccumulo().setZookeepers(mac.getZooKeepers());
setupSSL(conf);
}
@AfterClass
public static void afterClass() throws Exception {
mac.stop();
}
@Before
public void setup() throws Exception {
accumuloClient.tableOperations().list().forEach(t -> {
if (t.startsWith("timely")) {
try {
accumuloClient.tableOperations().delete(t);
} catch (Exception e) {
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.tableOperations().list().forEach(t -> {
if (t.startsWith("timely")) {
try {
accumuloClient.tableOperations().delete(t);
} catch (Exception e) {
}
}
}
});
startServer();
});
}
}
@After
public void tearDown() throws Exception {
AuthCache.resetConfiguration();
stopServer();
}
@Test(expected = UnauthorizedUserException.class)
public void testBasicAuthLoginFailure() throws Exception {
String metrics = "https://localhost:54322/api/metrics";
query(metrics);
final Server s = new Server(conf);
s.run();
try {
String metrics = "https://localhost:54322/api/metrics";
query(metrics);
} finally {
s.shutdown();
}
}
}
@@ -3,20 +3,46 @@ package timely.test.integration;
import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterruptibly;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.cookie.ClientCookieDecoder;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.ssl.ApplicationProtocolConfig;
import io.netty.handler.ssl.JdkSslContext;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.minicluster.MiniAccumuloCluster;
import org.apache.accumulo.minicluster.MiniAccumuloConfig;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;
import timely.Server;
import timely.api.request.timeseries.QueryRequest;
import timely.api.response.timeseries.QueryResponse;
import timely.auth.AuthCache;
import timely.configuration.Configuration;
import timely.netty.Constants;
import timely.test.IntegrationTest;
import timely.test.TestConfiguration;
@@ -26,22 +52,115 @@ import timely.test.TestConfiguration;
*
*/
@Category(IntegrationTest.class)
public class TwoWaySSLIT extends TwoWaySSLBase {
public class TwoWaySSLIT extends QueryBase {
private static final Long TEST_TIME = (System.currentTimeMillis() / 1000) * 1000;
private static final Long TEST_TIME = System.currentTimeMillis();
@ClassRule
public static final TemporaryFolder temp = new TemporaryFolder();
private static MiniAccumuloCluster mac = null;
private static Configuration conf = null;
protected static SelfSignedCertificate serverCert = null;
protected static File clientTrustStoreFile = null;
static {
try {
serverCert = new SelfSignedCertificate();
clientTrustStoreFile = serverCert.certificate().getAbsoluteFile();
} catch (Exception e) {
throw new RuntimeException("Error creating self signed certificate", e);
}
}
protected SSLSocketFactory getSSLSocketFactory() throws Exception {
SslContextBuilder builder = SslContextBuilder.forClient();
builder.applicationProtocolConfig(ApplicationProtocolConfig.DISABLED);
// Use server cert / key on client side.
builder.keyManager(serverCert.key(), (String) null, serverCert.cert());
builder.sslProvider(SslProvider.JDK);
builder.trustManager(clientTrustStoreFile); // Trust the server cert
SslContext ctx = builder.build();
Assert.assertTrue(ctx.isClient());
Assert.assertTrue(ctx instanceof JdkSslContext);
JdkSslContext jdk = (JdkSslContext) ctx;
SSLContext jdkSslContext = jdk.context();
return jdkSslContext.getSocketFactory();
}
protected static void setupSSL(Configuration config) throws Exception {
config.getSecurity().getServerSsl().setCertificateFile(serverCert.certificate().getAbsolutePath());
config.getSecurity().getServerSsl().setKeyFile(serverCert.privateKey().getAbsolutePath());
// Needed for 2way SSL
config.getSecurity().getServerSsl().setTrustStoreFile(serverCert.certificate().getAbsolutePath());
config.getSecurity().getServerSsl().setUseOpenssl(false);
config.getSecurity().getServerSsl().setUseGeneratedKeypair(false);
config.getSecurity().setAllowAnonymousHttpAccess(false);
}
@Override
protected HttpsURLConnection getUrlConnection(URL url) throws Exception {
// Username and password not used in 2way SSL case
return getUrlConnection(null, null, url);
}
@Override
protected HttpsURLConnection getUrlConnection(String username, String password, URL url) throws Exception {
HttpsURLConnection.setDefaultSSLSocketFactory(getSSLSocketFactory());
URL loginURL = new URL(url.getProtocol() + "://" + url.getHost() + ":" + url.getPort() + "/login");
HttpsURLConnection con = (HttpsURLConnection) loginURL.openConnection();
con.setHostnameVerifier((host, session) -> true);
con.setRequestMethod("GET");
con.setDoOutput(true);
con.setRequestProperty("Content-Type", "application/json");
con.connect();
int responseCode = con.getResponseCode();
if (401 == responseCode) {
throw new UnauthorizedUserException();
}
Assert.assertEquals(200, responseCode);
List<String> cookies = con.getHeaderFields().get(HttpHeaderNames.SET_COOKIE.toString());
Assert.assertEquals(1, cookies.size());
Cookie sessionCookie = ClientCookieDecoder.STRICT.decode(cookies.get(0));
Assert.assertEquals(Constants.COOKIE_NAME, sessionCookie.name());
con = (HttpsURLConnection) url.openConnection();
con.setRequestProperty(HttpHeaderNames.COOKIE.toString(), sessionCookie.name() + "=" + sessionCookie.value());
con.setHostnameVerifier((host, session) -> true);
return con;
}
@BeforeClass
public static void beforeClass() throws Exception {
final MiniAccumuloConfig macConfig = new MiniAccumuloConfig(temp.newFolder("mac"), "secret");
mac = new MiniAccumuloCluster(macConfig);
mac.start();
conf = TestConfiguration.createMinimalConfigurationForTest();
conf.getAccumulo().setInstanceName(mac.getInstanceName());
conf.getAccumulo().setZookeepers(mac.getZooKeepers());
setupSSL(conf);
}
@AfterClass
public static void afterClass() throws Exception {
mac.stop();
}
@Before
public void setup() throws Exception {
accumuloClient.securityOperations().changeUserAuthorizations("root",
new Authorizations("A", "B", "C", "D", "E", "F"));
accumuloClient.tableOperations().list().forEach(t -> {
if (t.startsWith("timely")) {
try {
accumuloClient.tableOperations().delete(t);
} catch (Exception e) {
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.securityOperations().changeUserAuthorizations("root",
new Authorizations("A", "B", "C", "D", "E", "F"));
accumuloClient.tableOperations().list().forEach(t -> {
if (t.startsWith("timely")) {
try {
accumuloClient.tableOperations().delete(t);
} catch (Exception e) {
}
}
}
});
});
}
}
@After
@@ -51,52 +170,58 @@ public class TwoWaySSLIT extends TwoWaySSLBase {
@Test
public void testBasicAuthLogin() throws Exception {
startServer();
String metrics = "https://localhost:54322/api/metrics";
query(metrics);
stopServer();
final Server s = new Server(conf);
s.run();
try {
String metrics = "https://localhost:54322/api/metrics";
query(metrics);
} finally {
s.shutdown();
}
}
@Test
public void testQueryWithVisibilityWithoutCache() throws Exception {
conf.getCache().setEnabled(false);
startServer();
testQueryWithVisibility(conf);
stopServer();
}
@Test
public void testQueryWithVisibilityWithCache() throws Exception {
conf.getCache().setEnabled(true);
startServer();
testQueryWithVisibility(conf);
stopServer();
}
public void testQueryWithVisibility(Configuration conf) throws Exception {
// @formatter:off
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 1000) + " 2.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 2000) + " 3.0 tag1=value1 tag3=value3 viz=A",
"sys.cpu.user " + (TEST_TIME + 3000) + " 4.0 tag1=value1 tag3=value3 viz=D",
"sys.cpu.user " + (TEST_TIME + 3000) + " 5.0 tag1=value1 tag3=value3 viz=G");
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
QueryRequest request = new QueryRequest();
request.setStart(TEST_TIME);
request.setEnd(TEST_TIME + 6000);
QueryRequest.SubQuery subQuery = new QueryRequest.SubQuery();
subQuery.setMetric("sys.cpu.user");
subQuery.setDownsample(Optional.of("1s-max"));
request.addQuery(subQuery);
// @formatter:on
final Server s = new Server(conf);
s.run();
try {
// @formatter:off
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 1000) + " 2.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 2000) + " 3.0 tag1=value1 tag3=value3 viz=A",
"sys.cpu.user " + (TEST_TIME + 3000) + " 4.0 tag1=value1 tag3=value3 viz=D",
"sys.cpu.user " + (TEST_TIME + 3000) + " 5.0 tag1=value1 tag3=value3 viz=G");
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
QueryRequest request = new QueryRequest();
request.setStart(TEST_TIME);
request.setEnd(TEST_TIME + 6000);
QueryRequest.SubQuery subQuery = new QueryRequest.SubQuery();
subQuery.setMetric("sys.cpu.user");
subQuery.setDownsample(Optional.of("1s-max"));
request.addQuery(subQuery);
// @formatter:on
String metrics = "https://127.0.0.1:54322/api/query";
List<QueryResponse> response = query(metrics, request);
assertEquals(1, response.size());
Map<String, String> tags = response.get(0).getTags();
assertEquals(0, tags.size());
Map<String, Object> dps = response.get(0).getDps();
assertEquals(3, dps.size());
String metrics = "https://127.0.0.1:54322/api/query";
List<QueryResponse> response = query(metrics, request);
assertEquals(1, response.size());
Map<String, String> tags = response.get(0).getTags();
assertEquals(0, tags.size());
Map<String, Object> dps = response.get(0).getDps();
assertEquals(3, dps.size());
} finally {
s.shutdown();
}
}
}
@@ -3,19 +3,42 @@ package timely.test.integration;
import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterruptibly;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.cookie.ClientCookieDecoder;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.ssl.ApplicationProtocolConfig;
import io.netty.handler.ssl.JdkSslContext;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.security.Authorizations;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import timely.Server;
import timely.api.request.timeseries.QueryRequest;
import timely.api.response.timeseries.QueryResponse;
import timely.auth.AuthCache;
import timely.configuration.Configuration;
import timely.netty.Constants;
import timely.test.IntegrationTest;
import timely.test.TestConfiguration;
@@ -26,51 +49,149 @@ import timely.test.TestConfiguration;
*
*/
@Category(IntegrationTest.class)
public class TwoWaySSLOpenSSLIT extends TwoWaySSLBase {
public class TwoWaySSLOpenSSLIT extends QueryBase {
private static final Long TEST_TIME = (System.currentTimeMillis() / 1000) * 1000;
private static final Long TEST_TIME = System.currentTimeMillis();
protected static SelfSignedCertificate serverCert = null;
protected static File clientTrustStoreFile = null;
static {
try {
serverCert = new SelfSignedCertificate();
clientTrustStoreFile = serverCert.certificate().getAbsoluteFile();
} catch (Exception e) {
throw new RuntimeException("Error creating self signed certificate", e);
}
}
protected SSLSocketFactory getSSLSocketFactory() throws Exception {
SslContextBuilder builder = SslContextBuilder.forClient();
builder.applicationProtocolConfig(ApplicationProtocolConfig.DISABLED);
// Use server cert / key on client side.
builder.keyManager(serverCert.key(), (String) null, serverCert.cert());
builder.sslProvider(SslProvider.JDK);
builder.trustManager(clientTrustStoreFile); // Trust the server cert
SslContext ctx = builder.build();
Assert.assertTrue(ctx.isClient());
Assert.assertTrue(ctx instanceof JdkSslContext);
JdkSslContext jdk = (JdkSslContext) ctx;
SSLContext jdkSslContext = jdk.context();
return jdkSslContext.getSocketFactory();
}
protected static void setupSSL(Configuration config) throws Exception {
config.getSecurity().getServerSsl().setCertificateFile(serverCert.certificate().getAbsolutePath());
config.getSecurity().getServerSsl().setKeyFile(serverCert.privateKey().getAbsolutePath());
// Needed for 2way SSL
config.getSecurity().getServerSsl().setTrustStoreFile(serverCert.certificate().getAbsolutePath());
config.getSecurity().getServerSsl().setUseOpenssl(false);
config.getSecurity().getServerSsl().setUseGeneratedKeypair(false);
config.getSecurity().setAllowAnonymousHttpAccess(false);
}
@Before
public void configureSSL() throws Exception {
setupSSL(conf);
}
@Override
protected HttpsURLConnection getUrlConnection(URL url) throws Exception {
// Username and password not used in 2way SSL case
return getUrlConnection(null, null, url);
}
@Override
protected HttpsURLConnection getUrlConnection(String username, String password, URL url) throws Exception {
HttpsURLConnection.setDefaultSSLSocketFactory(getSSLSocketFactory());
URL loginURL = new URL(url.getProtocol() + "://" + url.getHost() + ":" + url.getPort() + "/login");
HttpsURLConnection con = (HttpsURLConnection) loginURL.openConnection();
con.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
con.setRequestMethod("GET");
con.setDoOutput(true);
con.setRequestProperty("Content-Type", "application/json");
con.connect();
int responseCode = con.getResponseCode();
if (401 == responseCode) {
throw new UnauthorizedUserException();
}
Assert.assertEquals(200, responseCode);
List<String> cookies = con.getHeaderFields().get(HttpHeaderNames.SET_COOKIE.toString());
Assert.assertEquals(1, cookies.size());
Cookie sessionCookie = ClientCookieDecoder.STRICT.decode(cookies.get(0));
Assert.assertEquals(Constants.COOKIE_NAME, sessionCookie.name());
con = (HttpsURLConnection) url.openConnection();
con.setRequestProperty(HttpHeaderNames.COOKIE.toString(), sessionCookie.name() + "=" + sessionCookie.value());
con.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
return con;
}
@Before
public void setup() throws Exception {
accumuloClient.securityOperations().changeUserAuthorizations("root",
new Authorizations("A", "B", "C", "D", "E", "F"));
startServer();
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.securityOperations().changeUserAuthorizations("root",
new Authorizations("A", "B", "C", "D", "E", "F"));
}
}
@After
public void tearDown() throws Exception {
AuthCache.resetConfiguration();
stopServer();
}
@Test
public void testBasicAuthLogin() throws Exception {
String metrics = "https://localhost:54322/api/metrics";
query(metrics);
final Server s = new Server(conf);
s.run();
try {
String metrics = "https://localhost:54322/api/metrics";
query(metrics);
} finally {
s.shutdown();
}
}
@Test
public void testQueryWithVisibility() throws Exception {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 1000) + " 3.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 2000) + " 2.0 tag1=value1 tag3=value3 viz=A",
"sys.cpu.user " + (TEST_TIME + 3000) + " 2.0 tag1=value1 tag3=value3 viz=D",
"sys.cpu.user " + (TEST_TIME + 3000) + " 2.0 tag1=value1 tag3=value3 viz=G");
// Latency in TestConfiguration is 2s, wait for it
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
QueryRequest request = new QueryRequest();
request.setStart(TEST_TIME);
request.setEnd(TEST_TIME + 6000);
QueryRequest.SubQuery subQuery = new QueryRequest.SubQuery();
subQuery.setMetric("sys.cpu.user");
subQuery.setDownsample(Optional.of("1s-max"));
request.addQuery(subQuery);
String metrics = "https://127.0.0.1:54322/api/query";
List<QueryResponse> response = query(metrics, request);
assertEquals(1, response.size());
Map<String, String> tags = response.get(0).getTags();
assertEquals(0, tags.size());
Map<String, Object> dps = response.get(0).getDps();
assertEquals(3, dps.size());
final Server s = new Server(conf);
s.run();
try {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 1000) + " 3.0 tag1=value1 tag2=value2",
"sys.cpu.user " + (TEST_TIME + 2000) + " 2.0 tag1=value1 tag3=value3 viz=A",
"sys.cpu.user " + (TEST_TIME + 3000) + " 2.0 tag1=value1 tag3=value3 viz=D",
"sys.cpu.user " + (TEST_TIME + 3000) + " 2.0 tag1=value1 tag3=value3 viz=G");
// Latency in TestConfiguration is 2s, wait for it
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
QueryRequest request = new QueryRequest();
request.setStart(TEST_TIME);
request.setEnd(TEST_TIME + 6000);
QueryRequest.SubQuery subQuery = new QueryRequest.SubQuery();
subQuery.setMetric("sys.cpu.user");
subQuery.setDownsample(Optional.of("1s-max"));
request.addQuery(subQuery);
String metrics = "https://127.0.0.1:54322/api/query";
List<QueryResponse> response = query(metrics, request);
assertEquals(1, response.size());
Map<String, String> tags = response.get(0).getTags();
assertEquals(0, tags.size());
Map<String, Object> dps = response.get(0).getDps();
assertEquals(3, dps.size());
} finally {
s.shutdown();
}
}
}
@@ -11,6 +11,8 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
@@ -21,6 +23,7 @@ import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.Server;
import timely.TestServer;
import timely.api.request.MetricRequest;
import timely.auth.AuthCache;
@@ -34,7 +37,7 @@ import timely.test.integration.OneWaySSLBase;
public class TcpClientIT extends OneWaySSLBase {
private static final Logger LOG = LoggerFactory.getLogger(TcpClientIT.class);
private static final Long TEST_TIME = (System.currentTimeMillis() / 1000) * 1000;
private static final Long TEST_TIME = System.currentTimeMillis();
@After
public void tearDown() throws Exception {
@@ -43,7 +46,7 @@ public class TcpClientIT extends OneWaySSLBase {
@Test
public void testPut() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
try (TcpClient client = new TcpClient("127.0.0.1", 54321)) {
client.open();
@@ -74,7 +77,7 @@ public class TcpClientIT extends OneWaySSLBase {
@Test
public void testPutMultiple() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
try (TcpClient client = new TcpClient("127.0.0.1", 54321)) {
client.open();
@@ -118,7 +121,7 @@ public class TcpClientIT extends OneWaySSLBase {
@Test
public void testPutInvalidTimestamp() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
try (TcpClient client = new TcpClient("127.0.0.1", 54321)) {
client.open();
@@ -133,12 +136,18 @@ public class TcpClientIT extends OneWaySSLBase {
@Test
public void testPersistence() throws Exception {
startServer();
final Server s = new Server(conf);
s.run();
try {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.idle " + (TEST_TIME + 1) + " 1.0 tag3=value3 tag4=value4",
"sys.cpu.idle " + (TEST_TIME + 2) + " 1.0 tag3=value3 tag4=value4");
sleepUninterruptibly(WAIT_SECONDS, TimeUnit.SECONDS);
} finally {
s.shutdown();
}
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
assertTrue(accumuloClient.namespaceOperations().exists("timely"));
assertTrue(accumuloClient.tableOperations().exists("timely.metrics"));
assertTrue(accumuloClient.tableOperations().exists("timely.meta"));
@@ -167,19 +176,23 @@ public class TcpClientIT extends OneWaySSLBase {
count++;
}
assertEquals(15, count);
} finally {
stopServer();
}
}
@Test
public void testPersistenceWithVisibility() throws Exception {
startServer();
final Server s = new Server(conf);
s.run();
try {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.idle " + (TEST_TIME + 1) + " 1.0 tag3=value3 tag4=value4 viz=(a|b)",
"sys.cpu.idle " + (TEST_TIME + 2) + " 1.0 tag3=value3 tag4=value4 viz=(c&b)");
sleepUninterruptibly(WAIT_SECONDS, TimeUnit.SECONDS);
} finally {
s.shutdown();
}
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.securityOperations().changeUserAuthorizations("root", new Authorizations("a", "b", "c"));
int count = 0;
@@ -209,8 +222,6 @@ public class TcpClientIT extends OneWaySSLBase {
count++;
}
assertEquals(6, count);
} finally {
stopServer();
}
}
@@ -10,6 +10,8 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
@@ -21,6 +23,7 @@ import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.Server;
import timely.TestServer;
import timely.api.request.MetricRequest;
import timely.auth.AuthCache;
@@ -29,24 +32,27 @@ import timely.model.Metric;
import timely.model.Tag;
import timely.test.IntegrationTest;
import timely.test.TestConfiguration;
import timely.test.integration.InMemoryITBase;
import timely.test.integration.MacITBase;
@Category(IntegrationTest.class)
public class UdpClientIT extends InMemoryITBase {
public class UdpClientIT extends MacITBase {
private static final Logger LOG = LoggerFactory.getLogger(UdpClientIT.class);
private static final Long TEST_TIME = (System.currentTimeMillis() / 1000) * 1000;
private static final Long TEST_TIME = System.currentTimeMillis();
@Before
public void setup() throws Exception {
accumuloClient.tableOperations().list().forEach(t -> {
if (t.startsWith("timely")) {
try {
accumuloClient.tableOperations().delete(t);
} catch (Exception e) {
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.tableOperations().list().forEach(t -> {
if (t.startsWith("timely")) {
try {
accumuloClient.tableOperations().delete(t);
} catch (Exception e) {
}
}
}
});
});
}
}
@After
@@ -56,7 +62,7 @@ public class UdpClientIT extends InMemoryITBase {
@Test
public void testPut() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
try (UdpClient client = new UdpClient("127.0.0.1", 54325)) {
client.open();
@@ -86,7 +92,7 @@ public class UdpClientIT extends InMemoryITBase {
@Test
public void testPutMultiple() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
try (UdpClient client = new UdpClient("127.0.0.1", 54325)) {
client.open();
@@ -128,7 +134,7 @@ public class UdpClientIT extends InMemoryITBase {
@Test
public void testPutInvalidTimestamp() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
try (UdpClient client = new UdpClient("127.0.0.1", 54325)) {
client.open();
@@ -142,17 +148,24 @@ public class UdpClientIT extends InMemoryITBase {
@Test
public void testPersistence() throws Exception {
startServer();
final Server s = new Server(conf);
s.run();
try {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.idle " + (TEST_TIME + 1) + " 1.0 tag3=value3 tag4=value4",
"sys.cpu.idle " + (TEST_TIME + 2) + " 1.0 tag3=value3 tag4=value4");
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
} finally {
s.shutdown();
}
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
assertTrue(accumuloClient.namespaceOperations().exists("timely"));
assertTrue(accumuloClient.tableOperations().exists("timely.metrics"));
assertTrue(accumuloClient.tableOperations().exists("timely.meta"));
int count = 0;
for (final Entry<Key, Value> entry : accumuloClient.createScanner("timely.metrics", Authorizations.EMPTY)) {
LOG.info("Entry: " + entry);
final double value = ByteBuffer.wrap(entry.getValue().get()).getDouble();
assertEquals(1.0, value, 1e-9);
count++;
@@ -160,6 +173,7 @@ public class UdpClientIT extends InMemoryITBase {
assertEquals(6, count);
count = 0;
for (final Entry<Key, Value> entry : accumuloClient.createScanner("timely.meta", Authorizations.EMPTY)) {
LOG.info("Meta entry: " + entry);
count++;
}
assertEquals(10, count);
@@ -170,27 +184,33 @@ public class UdpClientIT extends InMemoryITBase {
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
count = 0;
for (final Entry<Key, Value> entry : accumuloClient.createScanner("timely.meta", Authorizations.EMPTY)) {
LOG.info("Meta no vers iter: " + entry);
count++;
}
assertEquals(15, count);
} finally {
stopServer();
}
}
@Test
public void testPersistenceWithVisibility() throws Exception {
startServer();
final Server s = new Server(conf);
s.run();
try {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.idle " + (TEST_TIME + 1) + " 1.0 tag3=value3 tag4=value4 viz=(a|b)",
"sys.cpu.idle " + (TEST_TIME + 2) + " 1.0 tag3=value3 tag4=value4 viz=(c&b)");
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
} finally {
s.shutdown();
}
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.securityOperations().changeUserAuthorizations("root", new Authorizations("a", "b", "c"));
int count = 0;
for (final Map.Entry<Key, Value> entry : accumuloClient.createScanner("timely.metrics",
Authorizations.EMPTY)) {
LOG.info("Entry: " + entry);
final double value = ByteBuffer.wrap(entry.getValue().get()).getDouble();
assertEquals(1.0, value, 1e-9);
count++;
@@ -199,6 +219,7 @@ public class UdpClientIT extends InMemoryITBase {
count = 0;
Authorizations auth1 = new Authorizations("a");
for (final Map.Entry<Key, Value> entry : accumuloClient.createScanner("timely.metrics", auth1)) {
LOG.info("Entry: " + entry);
final double value = ByteBuffer.wrap(entry.getValue().get()).getDouble();
assertEquals(1.0, value, 1e-9);
count++;
@@ -207,13 +228,12 @@ public class UdpClientIT extends InMemoryITBase {
count = 0;
Authorizations auth2 = new Authorizations("b", "c");
for (final Map.Entry<Key, Value> entry : accumuloClient.createScanner("timely.metrics", auth2)) {
LOG.info("Entry: " + entry);
final double value = ByteBuffer.wrap(entry.getValue().get()).getDouble();
assertEquals(1.0, value, 1e-9);
count++;
}
assertEquals(6, count);
} finally {
stopServer();
}
}
@@ -17,6 +17,8 @@ import io.netty.handler.ssl.JdkSslContext;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.http.client.HttpResponseException;
import org.junit.After;
@@ -26,6 +28,7 @@ import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.Server;
import timely.api.response.MetricResponses;
import timely.auth.AuthCache;
import timely.client.websocket.ClientHandler;
@@ -39,9 +42,10 @@ import timely.test.integration.OneWaySSLBase;
public class WebSocketClientIT extends OneWaySSLBase {
private final static Logger LOG = LoggerFactory.getLogger(WebSocketClientIT.class);
private static final Long TEST_TIME = ((System.currentTimeMillis() / 1000) * 1000) - (240 * 1000);
private static final Long TEST_TIME = System.currentTimeMillis() - (240 * 1000);
private static SSLContext sslCtx = null;
private Server s = null;
private void setupSslCtx() throws Exception {
Assert.assertNotNull(clientTrustStoreFile);
@@ -58,16 +62,21 @@ public class WebSocketClientIT extends OneWaySSLBase {
@Before
public void setup() throws Exception {
accumuloClient.securityOperations().changeUserAuthorizations("root",
new Authorizations("A", "B", "C", "D", "E", "F"));
setupSslCtx();
startServer();
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.securityOperations().changeUserAuthorizations("root",
new Authorizations("A", "B", "C", "D", "E", "F"));
s = new Server(conf);
s.run();
setupSslCtx();
}
}
@Override
@After
public void tearDown() throws Exception {
s.shutdown();
AuthCache.resetConfiguration();
stopServer();
}
public void testWorkflow(WebSocketSubscriptionClient client) throws Exception {
@@ -138,8 +147,12 @@ public class WebSocketClientIT extends OneWaySSLBase {
public void testClientAnonymousAccess() throws Exception {
WebSocketSubscriptionClient client = new WebSocketSubscriptionClient(sslCtx, "localhost", 54322, 54323, false,
false, null, null, false, 65536);
conf.getSecurity().setAllowAnonymousWsAccess(true);
testWorkflow(client);
try {
conf.getSecurity().setAllowAnonymousWsAccess(true);
testWorkflow(client);
} finally {
conf.getSecurity().setAllowAnonymousWsAccess(false);
}
}
@Test
@@ -8,10 +8,9 @@ import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import io.netty.handler.codec.http.HttpHeaderNames;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.*;
import org.junit.experimental.categories.Category;
import timely.Server;
import timely.netty.http.StrictTransportHandler;
import timely.test.IntegrationTest;
import timely.test.integration.OneWaySSLBase;
@@ -19,14 +18,17 @@ import timely.test.integration.OneWaySSLBase;
@Category(IntegrationTest.class)
public class HTTPStrictTransportSecurityIT extends OneWaySSLBase {
private static Server s = null;
@Before
public void startup() {
startServer();
public void before() throws Exception {
s = new Server(conf);
s.run();
}
@After
public void shutdown() {
stopServer();
public void after() throws Exception {
s.shutdown();
}
@Test
File diff suppressed because it is too large. Load diff
@@ -17,16 +17,17 @@ import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import com.google.flatbuffers.FlatBufferBuilder;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
import org.apache.accumulo.core.security.Authorizations;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.junit.*;
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.Server;
import timely.TestServer;
import timely.api.request.MetricRequest;
import timely.api.request.VersionRequest;
@@ -34,16 +35,16 @@ import timely.auth.AuthCache;
import timely.model.Metric;
import timely.model.Tag;
import timely.test.IntegrationTest;
import timely.test.integration.InMemoryITBase;
import timely.test.integration.MacITBase;
/**
* Integration tests for the operations available over the TCP transport
*/
@Category(IntegrationTest.class)
public class TimelyTcpIT extends InMemoryITBase {
public class TimelyTcpIT extends MacITBase {
private static final Logger LOG = LoggerFactory.getLogger(TimelyTcpIT.class);
private static final Long TEST_TIME = (System.currentTimeMillis() / 1000) * 1000;
private static final Long TEST_TIME = System.currentTimeMillis();
@After
public void tearDown() throws Exception {
@@ -52,7 +53,7 @@ public class TimelyTcpIT extends InMemoryITBase {
@Test
public void testVersion() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
try (Socket sock = new Socket("127.0.0.1", 54321);
PrintWriter writer = new PrintWriter(sock.getOutputStream(), true);) {
@@ -72,7 +73,7 @@ public class TimelyTcpIT extends InMemoryITBase {
@Test
public void testPut() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
try (Socket sock = new Socket("127.0.0.1", 54321);
PrintWriter writer = new PrintWriter(sock.getOutputStream(), true);) {
@@ -103,7 +104,7 @@ public class TimelyTcpIT extends InMemoryITBase {
@Test
public void testPutMultiple() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
try (Socket sock = new Socket("127.0.0.1", 54321);
PrintWriter writer = new PrintWriter(sock.getOutputStream(), true)) {
@@ -186,7 +187,7 @@ public class TimelyTcpIT extends InMemoryITBase {
binary.get(data, 0, binary.remaining());
LOG.debug("Sending {} bytes", data.length);
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
try (Socket sock = new Socket("127.0.0.1", 54321);) {
sock.getOutputStream().write(data);
@@ -229,7 +230,7 @@ public class TimelyTcpIT extends InMemoryITBase {
@Test
public void testPutInvalidTimestamp() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
try (Socket sock = new Socket("127.0.0.1", 54321);
PrintWriter writer = new PrintWriter(sock.getOutputStream(), true);
@@ -245,12 +246,18 @@ public class TimelyTcpIT extends InMemoryITBase {
@Test
public void testPersistence() throws Exception {
startServer();
final Server s = new Server(conf);
s.run();
try {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.idle " + (TEST_TIME + 1) + " 1.0 tag3=value3 tag4=value4",
"sys.cpu.idle " + (TEST_TIME + 2) + " 1.0 tag3=value3 tag4=value4");
sleepUninterruptibly(WAIT_SECONDS, TimeUnit.SECONDS);
} finally {
s.shutdown();
}
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
assertTrue(accumuloClient.namespaceOperations().exists("timely"));
assertTrue(accumuloClient.tableOperations().exists("timely.metrics"));
assertTrue(accumuloClient.tableOperations().exists("timely.meta"));
@@ -279,19 +286,23 @@ public class TimelyTcpIT extends InMemoryITBase {
count++;
}
assertEquals(15, count);
} finally {
stopServer();
}
}
@Test
public void testPersistenceWithVisibility() throws Exception {
startServer();
final Server s = new Server(conf);
s.run();
try {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.idle " + (TEST_TIME + 1) + " 1.0 tag3=value3 tag4=value4 viz=(a|b)",
"sys.cpu.idle " + (TEST_TIME + 2) + " 1.0 tag3=value3 tag4=value4 viz=(c&b)");
sleepUninterruptibly(WAIT_SECONDS, TimeUnit.SECONDS);
} finally {
s.shutdown();
}
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.securityOperations().changeUserAuthorizations("root", new Authorizations("a", "b", "c"));
int count = 0;
@@ -321,8 +332,6 @@ public class TimelyTcpIT extends InMemoryITBase {
count++;
}
assertEquals(6, count);
} finally {
stopServer();
}
}
@@ -16,6 +16,8 @@ import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import com.google.flatbuffers.FlatBufferBuilder;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
@@ -27,6 +29,7 @@ import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import timely.Server;
import timely.TestServer;
import timely.api.request.MetricRequest;
import timely.auth.AuthCache;
@@ -34,27 +37,29 @@ import timely.model.Metric;
import timely.model.Tag;
import timely.test.IntegrationTest;
import timely.test.TestConfiguration;
import timely.test.integration.InMemoryITBase;
import timely.test.integration.MacITBase;
/**
* Integration tests for the operations available over the UDP transport
*/
@Category(IntegrationTest.class)
public class TimelyUdpIT extends InMemoryITBase {
public class TimelyUdpIT extends MacITBase {
private static final Logger LOG = LoggerFactory.getLogger(TimelyUdpIT.class);
private static final Long TEST_TIME = (System.currentTimeMillis() / 1000) * 1000;
private static final Long TEST_TIME = System.currentTimeMillis();
@Before
public void setup() throws Exception {
accumuloClient.tableOperations().list().forEach(t -> {
if (t.startsWith("timely")) {
try {
accumuloClient.tableOperations().delete(t);
} catch (Exception e) {
try (AccumuloClient accumuloClient = mac.createAccumuloClient("root", new PasswordToken("secret"))) {
accumuloClient.tableOperations().list().forEach(t -> {
if (t.startsWith("timely")) {
try {
accumuloClient.tableOperations().delete(t);
} catch (Exception e) {
}
}
}
});
});
}
}
@After
@@ -64,7 +69,7 @@ public class TimelyUdpIT extends InMemoryITBase {
@Test
public void testPut() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 54325);
DatagramPacket packet = new DatagramPacket("".getBytes(UTF_8), 0, 0, address.getAddress(), 54325);
@@ -95,7 +100,8 @@ public class TimelyUdpIT extends InMemoryITBase {
@Test
public void testPutMultiple() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 54325);
DatagramPacket packet = new DatagramPacket("".getBytes(UTF_8), 0, 0, address.getAddress(), 54325);
@@ -178,7 +184,7 @@ public class TimelyUdpIT extends InMemoryITBase {
binary.get(data, 0, binary.remaining());
LOG.debug("Sending {} bytes", data.length);
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 54325);
DatagramPacket packet = new DatagramPacket("".getBytes(UTF_8), 0, 0, address.getAddress(), 54325);
@@ -222,7 +228,7 @@ public class TimelyUdpIT extends InMemoryITBase {
@Test
public void testPutInvalidTimestamp() throws Exception {
final TestServer m = new TestServer(conf, accumuloClient);
final TestServer m = new TestServer(conf);
m.run();
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 54325);
DatagramPacket packet = new DatagramPacket("".getBytes(UTF_8), 0, 0, address.getAddress(), 54325);
@@ -238,12 +244,17 @@ public class TimelyUdpIT extends InMemoryITBase {
@Test
public void testPersistence() throws Exception {
startServer();
final Server s = new Server(conf);
s.run();
try {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.idle " + (TEST_TIME + 1) + " 1.0 tag3=value3 tag4=value4",
"sys.cpu.idle " + (TEST_TIME + 2) + " 1.0 tag3=value3 tag4=value4");
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
} finally {
s.shutdown();
}
try (AccumuloClient accumuloClient = mac.createAccumuloClient("root", new PasswordToken("secret"))) {
assertTrue(accumuloClient.namespaceOperations().exists("timely"));
assertTrue(accumuloClient.tableOperations().exists("timely.metrics"));
assertTrue(accumuloClient.tableOperations().exists("timely.meta"));
@@ -272,19 +283,22 @@ public class TimelyUdpIT extends InMemoryITBase {
count++;
}
assertEquals(15, count);
} finally {
stopServer();
}
}
@Test
public void testPersistenceWithVisibility() throws Exception {
startServer();
final Server s = new Server(conf);
s.run();
try {
put("sys.cpu.user " + TEST_TIME + " 1.0 tag1=value1 tag2=value2",
"sys.cpu.idle " + (TEST_TIME + 1) + " 1.0 tag3=value3 tag4=value4 viz=(a|b)",
"sys.cpu.idle " + (TEST_TIME + 2) + " 1.0 tag3=value3 tag4=value4 viz=(c&b)");
sleepUninterruptibly(TestConfiguration.WAIT_SECONDS, TimeUnit.SECONDS);
} finally {
s.shutdown();
}
try (AccumuloClient accumuloClient = mac.createAccumuloClient("root", new PasswordToken("secret"))) {
accumuloClient.securityOperations().changeUserAuthorizations("root", new Authorizations("a", "b", "c"));
int count = 0;
@@ -314,8 +328,6 @@ public class TimelyUdpIT extends InMemoryITBase {
count++;
}
assertEquals(6, count);
} finally {
stopServer();
}
}
@@ -40,8 +40,10 @@ import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
import org.apache.accumulo.core.security.Authorizations;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -49,6 +51,7 @@ import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import timely.Server;
import timely.api.request.VersionRequest;
import timely.api.request.subscription.AddSubscription;
import timely.api.request.subscription.CloseSubscription;
@@ -78,7 +81,7 @@ import timely.util.JsonUtil;
public class WebSocketIT extends OneWaySSLBase {
private static final Logger LOG = LoggerFactory.getLogger(WebSocketIT.class);
private static final Long TEST_TIME = ((System.currentTimeMillis() / 1000) * 1000) - (240 * 1000);
private static final Long TEST_TIME = System.currentTimeMillis() - (240 * 1000);
private static final int WS_PORT = 54323;
private static final URI LOCATION;
static {
@@ -172,19 +175,30 @@ public class WebSocketIT extends OneWaySSLBase {
}
@AfterClass
public static void after() {
AuthCache.resetConfiguration();
}
private EventLoopGroup group = null;
private Channel ch = null;
private ClientHandler handler = null;
private Server s = null;
private String sessionId = null;
private UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("test", "test1");
@Before
public void setup() throws Exception {
accumuloClient.securityOperations().changeUserAuthorizations("root",
new Authorizations("A", "B", "C", "D", "E", "F"));
s = new Server(conf);
s.run();
try (AccumuloClient accumuloClient = mac.createAccumuloClient(MAC_ROOT_USER,
new PasswordToken(MAC_ROOT_PASSWORD))) {
accumuloClient.securityOperations().changeUserAuthorizations("root",
new Authorizations("A", "B", "C", "D", "E", "F"));
}
this.sessionId = UUID.randomUUID().toString();
startServer();
AuthCache.put(sessionId, TimelyPrincipal.anonymousPrincipal());
group = new NioEventLoopGroup();
SslContext ssl = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
@@ -215,11 +229,6 @@ public class WebSocketIT extends OneWaySSLBase {
}
}
@After
public void shutdown() {
stopServer();
}
@Test
public void testClientDisappears() throws Exception {
try {
@@ -266,6 +275,7 @@ public class WebSocketIT extends OneWaySSLBase {
}
} finally {
ch.close().sync();
s.shutdown();
group.shutdownGracefully();
}
}
@@ -338,6 +348,15 @@ public class WebSocketIT extends OneWaySSLBase {
second = Metric.newBuilder().name("sys.cpu.user").value(TEST_TIME + 500, 7.0D).tag(new Tag("rack", "r2"))
.tag(new Tag("tag3", "value3")).build();
int x = 1;
for (String r : response) {
responses = JsonUtil.getObjectMapper().readValue(r, MetricResponses.class);
for (MetricResponse r1 : responses.getResponses()) {
System.out.println(x + " -- " + r1.toString());
}
x++;
}
Assert.assertEquals(1, response.size());
responses = JsonUtil.getObjectMapper().readValue(response.get(0), MetricResponses.class);
Assert.assertEquals(2, responses.size());
@@ -761,6 +780,7 @@ public class WebSocketIT extends OneWaySSLBase {
response = handler.getResponses();
}
assertEquals(1, response.size());
System.out.println(response.get(0));
SuggestResponse r = JsonUtil.getObjectMapper().readValue(response.get(0), SuggestResponse.class);
assertEquals(1, r.getSuggestions().size());
assertEquals("sys.cpu.user", r.getSuggestions().get(0));