mirror of
https://github.com/NationalSecurityAgency/timely.git
synced 2026-11-09 17:36:01 -10:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc7326fc19 | ||
|
|
0d2b6e61c8 | ||
|
|
b7cd8765c5 | ||
|
|
a9d27d5b1b | ||
|
|
7d67eb218d | ||
|
|
5fb7e3dd2b | ||
|
|
5a89861cec | ||
|
|
a3bc9a01ee |
No files matched your search
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
<artifactId>timely-analytics</artifactId>
|
||||
<!--
|
||||
|
||||
@@ -46,9 +46,12 @@
|
||||
<user-service id="usernamePasswordService">
|
||||
<user name="test" password="test1" authorities="A,B,C" />
|
||||
</user-service>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
|
||||
<beans:bean id="noOpPasswordEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder"/>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
<beans:property name="userDetailsService" ref="usernamePasswordService"/>
|
||||
<beans:property name="passwordEncoder" ref="noOpPasswordEncoder"/>
|
||||
</beans:bean>
|
||||
|
||||
<authentication-manager alias="authenticationManager">
|
||||
|
||||
@@ -8,6 +8,8 @@ timely-balancer:
|
||||
assignmentFile: /timely/balancer/assignments.csv
|
||||
security:
|
||||
session-max-age: 86400
|
||||
cache-expiration-minutes: 60
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
serverSsl:
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
<artifactId>timely-balancer</artifactId>
|
||||
<dependencies>
|
||||
|
||||
@@ -64,6 +64,7 @@ import org.apache.zookeeper.CreateMode;
|
||||
import org.apache.zookeeper.data.Stat;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import timely.auth.AuthCache;
|
||||
@@ -143,7 +144,7 @@ public class Balancer {
|
||||
}
|
||||
|
||||
protected static ConfigurableApplicationContext initializeConfiguration(String[] args) {
|
||||
return new SpringApplicationBuilder(SpringBootstrap.class).web(false).run(args);
|
||||
return new SpringApplicationBuilder(SpringBootstrap.class).web(WebApplicationType.NONE).run(args);
|
||||
}
|
||||
|
||||
private void shutdownHook() {
|
||||
@@ -363,7 +364,7 @@ public class Balancer {
|
||||
curatorFramework.start();
|
||||
ensureZkPaths(curatorFramework, zkPaths);
|
||||
|
||||
AuthCache.setSessionMaxAge(balancerConfig.getSecurity());
|
||||
AuthCache.configure(balancerConfig.getSecurity());
|
||||
final boolean useEpoll = useEpoll();
|
||||
Class<? extends ServerSocketChannel> channelClass;
|
||||
Class<? extends Channel> datagramChannelClass;
|
||||
|
||||
@@ -5,8 +5,10 @@ import javax.validation.Valid;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import timely.configuration.Cache;
|
||||
|
||||
@Validated
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "timely-balancer")
|
||||
public class BalancerConfiguration {
|
||||
|
||||
+2
-2
@@ -4,12 +4,12 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
<artifactId>timely-client</artifactId>
|
||||
<properties>
|
||||
<!-- PEP 440 compliant version gets substituted into src/main/python/template/setup.py -->
|
||||
<python.client.version>1.2.1.dev0</python.client.version>
|
||||
<python.client.version>1.2.2.dev0</python.client.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
<artifactId>collectd-nsq-plugin</artifactId>
|
||||
<dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
<artifactId>collectd-plugin-parent</artifactId>
|
||||
<dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
<artifactId>collectd-timely-plugin</artifactId>
|
||||
<dependencies>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
<artifactId>timely-common</artifactId>
|
||||
<dependencies>
|
||||
|
||||
@@ -4,6 +4,8 @@ grafana-auth:
|
||||
port: 3001
|
||||
security:
|
||||
session-max-age: 86400
|
||||
cache-expiration-minutes: 60
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
serverSsl:
|
||||
|
||||
@@ -46,9 +46,12 @@
|
||||
<user-service id="usernamePasswordService">
|
||||
<user name="test" password="test1" authorities="A,B,C" />
|
||||
</user-service>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
|
||||
<beans:bean id="noOpPasswordEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder"/>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
<beans:property name="userDetailsService" ref="usernamePasswordService"/>
|
||||
<beans:property name="passwordEncoder" ref="noOpPasswordEncoder"/>
|
||||
</beans:bean>
|
||||
|
||||
<authentication-manager alias="authenticationManager">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
<artifactId>grafana-auth</artifactId>
|
||||
<dependencies>
|
||||
|
||||
@@ -43,6 +43,7 @@ import io.netty.handler.stream.ChunkedWriteHandler;
|
||||
import io.netty.util.internal.SystemPropertyUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import timely.auth.AuthCache;
|
||||
@@ -81,7 +82,7 @@ public class GrafanaAuth {
|
||||
}
|
||||
|
||||
protected static ConfigurableApplicationContext initializeConfiguration(String[] args) {
|
||||
return new SpringApplicationBuilder(SpringBootstrap.class).web(false).run(args);
|
||||
return new SpringApplicationBuilder(SpringBootstrap.class).web(WebApplicationType.NONE).run(args);
|
||||
}
|
||||
|
||||
private void shutdownHook() {
|
||||
@@ -225,7 +226,7 @@ public class GrafanaAuth {
|
||||
|
||||
public void run() throws Exception {
|
||||
|
||||
AuthCache.setSessionMaxAge(grafanaAuthConfig.getSecurity());
|
||||
AuthCache.configure(grafanaAuthConfig.getSecurity());
|
||||
final boolean useEpoll = useEpoll();
|
||||
Class<? extends ServerSocketChannel> channelClass;
|
||||
if (useEpoll) {
|
||||
|
||||
+2
@@ -5,9 +5,11 @@ import javax.validation.Valid;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import timely.balancer.configuration.BalancerHttp;
|
||||
import timely.balancer.configuration.BalancerSecurity;
|
||||
|
||||
@Validated
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "grafana-auth")
|
||||
public class GrafanaAuthConfiguration {
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
<artifactId>timely-app</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
Vendored
+2
-2
@@ -23,8 +23,8 @@
|
||||
{"name": "Project site", "url": "https://github.com/NationalSecurityAgency/timely"},
|
||||
{"name": "License & Terms", "url": "https://raw.githubusercontent.com/NationalSecurityAgency/timely/master/LICENSE"}
|
||||
],
|
||||
"version": "1.1.0",
|
||||
"updated": "2019-01-15"
|
||||
"version": "1.2.2",
|
||||
"updated": "2019-04-12"
|
||||
},
|
||||
|
||||
"includes": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "timely-app",
|
||||
"private": true,
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.2",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
{"name": "Project site", "url": "https://github.com/NationalSecurityAgency/timely"},
|
||||
{"name": "License & Terms", "url": "https://raw.githubusercontent.com/NationalSecurityAgency/timely/master/LICENSE"}
|
||||
],
|
||||
"version": "1.1.0",
|
||||
"updated": "2019-01-15"
|
||||
"version": "1.2.2",
|
||||
"updated": "2019-04-12"
|
||||
},
|
||||
|
||||
"includes": [
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.2</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Timely</name>
|
||||
<description>A secure and scalable time series database based on Apache Accumulo</description>
|
||||
@@ -43,31 +43,29 @@
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<version.accumulo>1.9.2</version.accumulo>
|
||||
<version.buildnumber-maven>1.4</version.buildnumber-maven>
|
||||
<version.caffeine>2.3.3</version.caffeine>
|
||||
<version.caffeine>2.6.2</version.caffeine>
|
||||
<version.collectd>5.7.1</version.collectd>
|
||||
<version.commons-collections4>4.1</version.commons-collections4>
|
||||
<version.commons-configuration>1.10</version.commons-configuration>
|
||||
<version.commons-io>2.6</version.commons-io>
|
||||
<version.commons-lang3>3.5</version.commons-lang3>
|
||||
<version.commons-pool2>2.6.0</version.commons-pool2>
|
||||
<version.curator>2.11.1</version.curator>
|
||||
<version.disruptor>3.3.6</version.disruptor>
|
||||
<version.commons-collections4>4.3</version.commons-collections4>
|
||||
<version.commons-lang3>3.8.1</version.commons-lang3>
|
||||
<version.commons-pool2>2.6.1</version.commons-pool2>
|
||||
<version.curator>4.1.0</version.curator>
|
||||
<version.disruptor>3.4.2</version.disruptor>
|
||||
<version.eclipse-lifecycle>1.0.0</version.eclipse-lifecycle>
|
||||
<version.fast-classpath-scanner>2.0.5</version.fast-classpath-scanner>
|
||||
<version.fast-classpath-scanner>3.1.13</version.fast-classpath-scanner>
|
||||
<version.flink>1.1.4</version.flink>
|
||||
<version.google-flatbuffers>1.10.0</version.google-flatbuffers>
|
||||
<version.guava>19.0</version.guava>
|
||||
<version.guava>27.1-jre</version.guava>
|
||||
<version.hadoop>2.7.3</version.hadoop>
|
||||
<version.httpcomponents>4.5.2</version.httpcomponents>
|
||||
<version.httpcomponents>4.5.6</version.httpcomponents>
|
||||
<version.impsort>1.2.0</version.impsort>
|
||||
<version.jackson>2.9.8</version.jackson>
|
||||
<version.jacoco>0.7.6.201602180812</version.jacoco>
|
||||
<version.javacsv>2.0</version.javacsv>
|
||||
<version.javassist>3.21.0-GA</version.javassist>
|
||||
<version.javassist>3.24.1-GA</version.javassist>
|
||||
<version.jcip-annotations>1.0</version.jcip-annotations>
|
||||
<version.jsoup>1.9.2</version.jsoup>
|
||||
<version.jsoup>1.11.3</version.jsoup>
|
||||
<version.junit>4.12</version.junit>
|
||||
<version.log4j>2.6.2</version.log4j>
|
||||
<version.log4j>2.11.2</version.log4j>
|
||||
<version.maven-assembly>2.6</version.maven-assembly>
|
||||
<version.maven-build-helper>1.12</version.maven-build-helper>
|
||||
<version.maven-compiler>3.3</version.maven-compiler>
|
||||
@@ -77,14 +75,14 @@
|
||||
<version.maven-rpm>2.1.4</version.maven-rpm>
|
||||
<version.maven-shade>2.4.2</version.maven-shade>
|
||||
<version.maven-surefire>2.19.1</version.maven-surefire>
|
||||
<version.netty>4.0.56.Final</version.netty>
|
||||
<version.netty-tcnative>2.0.7.Final</version.netty-tcnative>
|
||||
<version.netty>4.1.33.Final</version.netty>
|
||||
<version.netty-tcnative>2.0.24.Final</version.netty-tcnative>
|
||||
<version.os-maven>1.5.0.Final</version.os-maven>
|
||||
<version.powermock>1.6.4</version.powermock>
|
||||
<version.slf4j>1.7.21</version.slf4j>
|
||||
<version.slf4j>1.7.26</version.slf4j>
|
||||
<version.spotbugs-maven>3.1.7</version.spotbugs-maven>
|
||||
<version.spring-boot>1.4.1.RELEASE</version.spring-boot>
|
||||
<version.tyrus>1.13</version.tyrus>
|
||||
<version.spring-boot>2.1.3.RELEASE</version.spring-boot>
|
||||
<version.tyrus>1.15</version.tyrus>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
@@ -141,7 +139,7 @@
|
||||
<dependency>
|
||||
<groupId>io.github.lukehutch</groupId>
|
||||
<artifactId>fast-classpath-scanner</artifactId>
|
||||
<version>2.0.5</version>
|
||||
<version>${version.fast-classpath-scanner}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
|
||||
@@ -46,9 +46,12 @@
|
||||
<user-service id="usernamePasswordService">
|
||||
<user name="test" password="test1" authorities="A,B,C" />
|
||||
</user-service>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
|
||||
<beans:bean id="noOpPasswordEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder"/>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
<beans:property name="userDetailsService" ref="usernamePasswordService"/>
|
||||
<beans:property name="passwordEncoder" ref="noOpPasswordEncoder"/>
|
||||
</beans:bean>
|
||||
|
||||
<authentication-manager alias="authenticationManager">
|
||||
|
||||
@@ -18,6 +18,8 @@ timely:
|
||||
max-downsample-memory: 10000000
|
||||
security:
|
||||
session-max-age: 86400
|
||||
cache-expiration-minutes: 60
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
ssl:
|
||||
@@ -50,9 +52,9 @@ timely:
|
||||
timeout: 60
|
||||
subscription-lag: 120
|
||||
meta-cache:
|
||||
expiration-minutes: 60
|
||||
initial-capacity: 2000
|
||||
max-capacity: 10000
|
||||
expiration-minutes: 1440
|
||||
cache-refresh-minutes: 60
|
||||
max-tag-values: 100
|
||||
visibility-cache:
|
||||
expiration-minutes: 60
|
||||
initial-capacity: 2000
|
||||
|
||||
@@ -18,6 +18,8 @@ timely:
|
||||
max-downsample-memory: 10000000
|
||||
security:
|
||||
session-max-age: 86400
|
||||
cache-expiration-minutes: 60
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
ssl:
|
||||
@@ -54,9 +56,9 @@ timely:
|
||||
scanner-read-ahead: 1
|
||||
subscription-batch-size: 5000
|
||||
meta-cache:
|
||||
expiration-minutes: 60
|
||||
initial-capacity: 2000
|
||||
max-capacity: 10000
|
||||
expiration-minutes: 1440
|
||||
cache-refresh-minutes: 60
|
||||
max-tag-values: 100
|
||||
visibility-cache:
|
||||
expiration-minutes: 60
|
||||
initial-capacity: 2000
|
||||
|
||||
@@ -23,6 +23,8 @@ timely:
|
||||
max-downsample-memory: 10000000
|
||||
security:
|
||||
session-max-age: 86400
|
||||
cache-expiration-minutes: 60
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
serverSsl:
|
||||
@@ -60,10 +62,9 @@ timely:
|
||||
scanner-read-ahead: 1
|
||||
subscription-batch-size: 5000
|
||||
meta-cache:
|
||||
expiration-minutes: 60
|
||||
initial-capacity: 2000
|
||||
max-capacity: 10000
|
||||
expiration-minutes: 1440
|
||||
cache-refresh-minutes: 60
|
||||
max-tag-values: 100
|
||||
visibility-cache:
|
||||
expiration-minutes: 60
|
||||
initial-capacity: 2000
|
||||
max-capacity: 10000
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.2</version>
|
||||
</parent>
|
||||
<artifactId>timely-server</artifactId>
|
||||
<dependencies>
|
||||
|
||||
@@ -70,6 +70,7 @@ import org.apache.zookeeper.CreateMode;
|
||||
import org.apache.zookeeper.data.Stat;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import timely.api.response.TimelyException;
|
||||
@@ -250,7 +251,7 @@ public class Server {
|
||||
}
|
||||
|
||||
protected static Configuration initializeConfiguration(String[] args) {
|
||||
applicationContext = new SpringApplicationBuilder(SpringBootstrap.class).web(false).run(args);
|
||||
applicationContext = new SpringApplicationBuilder(SpringBootstrap.class).web(WebApplicationType.NONE).run(args);
|
||||
return applicationContext.getBean(Configuration.class);
|
||||
}
|
||||
|
||||
@@ -430,7 +431,7 @@ public class Server {
|
||||
// Initialize the MetaCache
|
||||
MetaCacheFactory.getCache(config);
|
||||
// initialize the auth cache
|
||||
AuthCache.setSessionMaxAge(config.getSecurity());
|
||||
AuthCache.configure(config.getSecurity());
|
||||
// Initialize the VisibilityCache
|
||||
VisibilityCache.init(config);
|
||||
final boolean useEpoll = useEpoll();
|
||||
|
||||
@@ -56,15 +56,18 @@ public class Meta implements Comparable<Meta> {
|
||||
}
|
||||
|
||||
public static Meta parse(Key k, Value v) {
|
||||
return Meta.parse(k, v, METRIC_PREFIX);
|
||||
}
|
||||
|
||||
public static Meta parse(Key k, Value v, String prefix) {
|
||||
if (k.getColumnQualifier().getLength() > 0) {
|
||||
return new Meta(k.getRow().toString().substring(METRIC_PREFIX.length()), k.getColumnFamily().toString(),
|
||||
return new Meta(k.getRow().toString().substring(prefix.length()), k.getColumnFamily().toString(),
|
||||
k.getColumnQualifier().toString());
|
||||
} else if (k.getColumnFamily().getLength() > 0) {
|
||||
return new Meta(k.getRow().toString().substring(METRIC_PREFIX.length()), k.getColumnFamily().toString(),
|
||||
null);
|
||||
return new Meta(k.getRow().toString().substring(prefix.length()), k.getColumnFamily().toString(), null);
|
||||
|
||||
} else {
|
||||
return new Meta(k.getRow().toString().substring(METRIC_PREFIX.length()), null, null);
|
||||
return new Meta(k.getRow().toString().substring(prefix.length()), null, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,32 +23,67 @@ public class AuthCache {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AuthCache.class);
|
||||
private static Cache<String, TimelyPrincipal> CACHE = null;
|
||||
|
||||
private static int sessionMaxAge = -1;
|
||||
private static int cacheExpirationMinutes = -1;
|
||||
private static int cacheRefreshMinutes = -1;
|
||||
|
||||
/**
|
||||
* For tests only
|
||||
*/
|
||||
public static void resetSessionMaxAge() {
|
||||
sessionMaxAge = -1;
|
||||
public static void resetConfiguration() {
|
||||
cacheExpirationMinutes = -1;
|
||||
cacheRefreshMinutes = -1;
|
||||
}
|
||||
|
||||
public static void setSessionMaxAge(Security security) {
|
||||
if (-1 != sessionMaxAge) {
|
||||
throw new IllegalStateException("Cache session max age already configured.");
|
||||
public static void configure(Security security) {
|
||||
if (-1 != cacheExpirationMinutes || -1 != cacheRefreshMinutes) {
|
||||
throw new IllegalStateException("Cache already configured.");
|
||||
}
|
||||
sessionMaxAge = security.getSessionMaxAge();
|
||||
cacheExpirationMinutes = security.getCacheExpirationMinutes();
|
||||
cacheRefreshMinutes = security.getCacheRefreshMinutes();
|
||||
}
|
||||
|
||||
private static Cache<String, TimelyPrincipal> getCache() {
|
||||
if (-1 == sessionMaxAge) {
|
||||
if (-1 == cacheExpirationMinutes) {
|
||||
throw new IllegalStateException("Cache session max age not configured.");
|
||||
}
|
||||
if (null == CACHE) {
|
||||
CACHE = Caffeine.newBuilder().expireAfterAccess(sessionMaxAge, TimeUnit.SECONDS).build();
|
||||
Caffeine<Object, Object> caffeine = Caffeine.newBuilder();
|
||||
caffeine.expireAfterWrite(cacheExpirationMinutes, TimeUnit.MINUTES);
|
||||
if (cacheRefreshMinutes > 0) {
|
||||
caffeine.refreshAfterWrite(cacheRefreshMinutes, TimeUnit.MINUTES);
|
||||
CACHE = caffeine.build(key -> getTimelyPrincipal(key));
|
||||
} else {
|
||||
CACHE = caffeine.build();
|
||||
}
|
||||
}
|
||||
return CACHE;
|
||||
}
|
||||
|
||||
private static TimelyPrincipal getTimelyPrincipal(String key) {
|
||||
LOG.debug("Refreshing TimelyPrincipal {}", key);
|
||||
TimelyPrincipal timelyPrincipal = null;
|
||||
String[] dnArray = key.split(" -> ");
|
||||
if (dnArray.length == 1) {
|
||||
SubjectIssuerDNPair pair = SubjectIssuerDNPair.parse(dnArray[0]);
|
||||
TimelyAuthenticationToken token = AuthenticationService.getAuthenticationToken(new Object(),
|
||||
pair.subjectDN(), pair.issuerDN());
|
||||
timelyPrincipal = AuthenticationService.authenticate(token, pair, token.getTimelyPrincipal().getName(),
|
||||
false);
|
||||
} else if (dnArray.length > 1) {
|
||||
Collection<TimelyUser> timelyUsers = new ArrayList<>();
|
||||
for (String s : dnArray) {
|
||||
SubjectIssuerDNPair pair = SubjectIssuerDNPair.parse(s);
|
||||
TimelyAuthenticationToken token = AuthenticationService.getAuthenticationToken(new Object(),
|
||||
pair.subjectDN(), pair.issuerDN());
|
||||
TimelyPrincipal p = AuthenticationService.authenticate(token, pair,
|
||||
token.getTimelyPrincipal().getName(), false);
|
||||
timelyUsers.addAll(p.getProxiedUsers());
|
||||
}
|
||||
timelyPrincipal = new TimelyPrincipal(timelyUsers);
|
||||
}
|
||||
return timelyPrincipal;
|
||||
}
|
||||
|
||||
public static boolean containsKey(String key) {
|
||||
return getCache().getIfPresent(key) != null;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.authentication.preauth.x509.SubjectDnX509PrincipalExtractor;
|
||||
import timely.api.request.AuthenticatedRequest;
|
||||
import timely.api.response.TimelyException;
|
||||
import timely.auth.util.DnUtils;
|
||||
@@ -35,7 +34,6 @@ public class AuthenticationService {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AuthenticationService.class);
|
||||
private static ApplicationContext springContext = null;
|
||||
private static AuthenticationManager authManager = null;
|
||||
private static SubjectDnX509PrincipalExtractor x509 = null;
|
||||
private static ConcurrentHashMap<String, Object> fetchingEntity = new ConcurrentHashMap<>();
|
||||
private static ConcurrentHashMap<String, Object> fetchingPrincipal = new ConcurrentHashMap<>();
|
||||
private static Collection<String> requiredRoles;
|
||||
@@ -45,7 +43,6 @@ public class AuthenticationService {
|
||||
try {
|
||||
springContext = new ClassPathXmlApplicationContext("security.xml");
|
||||
authManager = springContext.getBean("authenticationManager", AuthenticationManager.class);
|
||||
x509 = springContext.getBean("x509PrincipalExtractor", SubjectDnX509PrincipalExtractor.class);
|
||||
requiredRoles = springContext.getBean("requiredRoles", List.class);
|
||||
requiredRoles.removeIf(String::isEmpty);
|
||||
requiredAuths = springContext.getBean("requiredAuths", List.class);
|
||||
@@ -65,9 +62,17 @@ public class AuthenticationService {
|
||||
}
|
||||
|
||||
public static TimelyPrincipal authenticate(Authentication authentication, SubjectIssuerDNPair pair, String entity) {
|
||||
return authenticate(authentication, pair, entity, true);
|
||||
}
|
||||
|
||||
public static TimelyPrincipal authenticate(Authentication authentication, SubjectIssuerDNPair pair, String entity,
|
||||
boolean useCache) {
|
||||
|
||||
// only one thread should call the authenticationManager for a given entity
|
||||
TimelyPrincipal principal = AuthCache.get(entity);
|
||||
TimelyPrincipal principal = null;
|
||||
if (useCache) {
|
||||
principal = AuthCache.get(entity);
|
||||
}
|
||||
// once an entity is in the AuthCache, we can bypass all of this
|
||||
if (principal == null) {
|
||||
Object newObj = new Object();
|
||||
@@ -79,12 +84,16 @@ public class AuthenticationService {
|
||||
synchronized (o) {
|
||||
// if multiple threads are waiting on this synchronized, then the 2nd and all
|
||||
// others will get the principal here
|
||||
principal = AuthCache.get(entity);
|
||||
if (useCache) {
|
||||
principal = AuthCache.get(entity);
|
||||
}
|
||||
if (principal == null) {
|
||||
Authentication token = getAuthenticationManager().authenticate(authentication);
|
||||
principal = getTimelyPrincipal(token, pair);
|
||||
LOG.trace("Got entity principal for {} from AuthenticationManager", entity);
|
||||
AuthCache.put(entity, principal);
|
||||
if (useCache) {
|
||||
AuthCache.put(entity, principal);
|
||||
}
|
||||
} else {
|
||||
LOG.trace("Got entity principal for {} from AuthCache on 2nd attempt", entity);
|
||||
}
|
||||
@@ -232,7 +241,7 @@ public class AuthenticationService {
|
||||
return authenticationToken;
|
||||
}
|
||||
|
||||
public static TimelyAuthenticationToken getAuthenticationToken(X509Certificate clientCert, String subjectDn,
|
||||
public static TimelyAuthenticationToken getAuthenticationToken(Object clientCert, String subjectDn,
|
||||
String issuerDn) {
|
||||
TimelyAuthenticationToken authenticationToken = null;
|
||||
try {
|
||||
|
||||
@@ -9,7 +9,9 @@ import javax.validation.Valid;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@Validated
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "timely")
|
||||
public class Configuration {
|
||||
|
||||
@@ -2,9 +2,9 @@ package timely.configuration;
|
||||
|
||||
public class MetaCache {
|
||||
|
||||
private long expirationMinutes = 60;
|
||||
private int initialCapacity = 2000;
|
||||
private long maxCapacity = 10000;
|
||||
private long expirationMinutes = 1440;
|
||||
private int cacheRefreshMinutes = -1;
|
||||
private long maxTagValues = 100;
|
||||
|
||||
public long getExpirationMinutes() {
|
||||
return expirationMinutes;
|
||||
@@ -14,19 +14,19 @@ public class MetaCache {
|
||||
this.expirationMinutes = expirationMinutes;
|
||||
}
|
||||
|
||||
public int getInitialCapacity() {
|
||||
return initialCapacity;
|
||||
public void setCacheRefreshMinutes(int cacheRefreshMinutes) {
|
||||
this.cacheRefreshMinutes = cacheRefreshMinutes;
|
||||
}
|
||||
|
||||
public void setInitialCapacity(int initialCapacity) {
|
||||
this.initialCapacity = initialCapacity;
|
||||
public int getCacheRefreshMinutes() {
|
||||
return cacheRefreshMinutes;
|
||||
}
|
||||
|
||||
public long getMaxCapacity() {
|
||||
return maxCapacity;
|
||||
public long getMaxTagValues() {
|
||||
return maxTagValues;
|
||||
}
|
||||
|
||||
public void setMaxCapacity(long maxCapacity) {
|
||||
this.maxCapacity = maxCapacity;
|
||||
public void setMaxTagValues(long maxTagValues) {
|
||||
this.maxTagValues = maxTagValues;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ public class Security {
|
||||
private boolean allowAnonymousHttpAccess = false;
|
||||
private boolean allowAnonymousWsAccess = false;
|
||||
private int sessionMaxAge = 86400;
|
||||
private int cacheExpirationMinutes = 60;
|
||||
private int cacheRefreshMinutes = 5;
|
||||
@Valid
|
||||
@NestedConfigurationProperty
|
||||
private ServerSsl serverSsl = new ServerSsl();
|
||||
@@ -37,6 +39,22 @@ public class Security {
|
||||
this.sessionMaxAge = sessionMaxAge;
|
||||
}
|
||||
|
||||
public void setCacheExpirationMinutes(int cacheExpirationMinutes) {
|
||||
this.cacheExpirationMinutes = cacheExpirationMinutes;
|
||||
}
|
||||
|
||||
public int getCacheExpirationMinutes() {
|
||||
return cacheExpirationMinutes;
|
||||
}
|
||||
|
||||
public void setCacheRefreshMinutes(int cacheRefreshMinutes) {
|
||||
this.cacheRefreshMinutes = cacheRefreshMinutes;
|
||||
}
|
||||
|
||||
public int getCacheRefreshMinutes() {
|
||||
return cacheRefreshMinutes;
|
||||
}
|
||||
|
||||
public ServerSsl getServerSsl() {
|
||||
return serverSsl;
|
||||
}
|
||||
|
||||
@@ -22,19 +22,20 @@ public class TimelyAuthenticationToken extends PreAuthenticatedAuthenticationTok
|
||||
public static final String PROXIED_ISSUERS_HEADER = "X-ProxiedIssuersChain";
|
||||
|
||||
private Multimap<String, String> httpHeaders = null;
|
||||
private X509Certificate clientCert;
|
||||
private X509Certificate clientCert = null;
|
||||
private TimelyPrincipal timelyPrincipal;
|
||||
|
||||
public TimelyAuthenticationToken(String subjectDn, X509Certificate clientCert,
|
||||
Multimap<String, String> httpHeaders) {
|
||||
public TimelyAuthenticationToken(String subjectDn, Object clientCert, Multimap<String, String> httpHeaders) {
|
||||
super(subjectDn, clientCert);
|
||||
if (httpHeaders == null) {
|
||||
this.httpHeaders = HashMultimap.create();
|
||||
} else {
|
||||
this.httpHeaders = httpHeaders;
|
||||
}
|
||||
this.clientCert = clientCert;
|
||||
String issuerDn = clientCert == null ? null : clientCert.getIssuerDN().getName();
|
||||
if (clientCert instanceof X509Certificate) {
|
||||
this.clientCert = (X509Certificate) clientCert;
|
||||
}
|
||||
String issuerDn = clientCert == null ? null : this.clientCert.getIssuerDN().getName();
|
||||
String proxiedEntities;
|
||||
String proxiedIssuers;
|
||||
try {
|
||||
@@ -61,9 +62,11 @@ public class TimelyAuthenticationToken extends PreAuthenticatedAuthenticationTok
|
||||
LOG.trace("Created TimelyAuthenticationToken: {}", timelyPrincipal.getName());
|
||||
}
|
||||
|
||||
public TimelyAuthenticationToken(String subjectDn, String issuerDn, X509Certificate clientCert) {
|
||||
public TimelyAuthenticationToken(String subjectDn, String issuerDn, Object clientCert) {
|
||||
super(subjectDn, clientCert);
|
||||
this.clientCert = clientCert;
|
||||
if (clientCert instanceof X509Certificate) {
|
||||
this.clientCert = (X509Certificate) clientCert;
|
||||
}
|
||||
TimelyUser.UserType userType = DnUtils.isServerDN(subjectDn) ? TimelyUser.UserType.SERVER
|
||||
: TimelyUser.UserType.USER;
|
||||
TimelyUser timelyUser = new TimelyUser(SubjectIssuerDNPair.of(subjectDn, issuerDn), userType, null, null, null,
|
||||
|
||||
@@ -1,27 +1,103 @@
|
||||
package timely.store;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import org.apache.accumulo.core.client.ClientConfiguration;
|
||||
import org.apache.accumulo.core.client.Connector;
|
||||
import org.apache.accumulo.core.client.Instance;
|
||||
import org.apache.accumulo.core.client.Scanner;
|
||||
import org.apache.accumulo.core.client.ZooKeeperInstance;
|
||||
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
|
||||
import org.apache.accumulo.core.data.Key;
|
||||
import org.apache.accumulo.core.data.Range;
|
||||
import org.apache.accumulo.core.data.Value;
|
||||
import org.apache.accumulo.core.security.Authorizations;
|
||||
import org.apache.commons.configuration.BaseConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import timely.api.model.Meta;
|
||||
import timely.configuration.Accumulo;
|
||||
import timely.configuration.Configuration;
|
||||
|
||||
public class MetaCacheImpl implements MetaCache {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(MetaCacheImpl.class);
|
||||
private static final Object DUMMY = new Object();
|
||||
private volatile boolean closed = false;
|
||||
private Cache<Meta, Object> cache = null;
|
||||
private Configuration configuration;
|
||||
private Timer timer = new Timer("MetaCacheImpl", true);
|
||||
|
||||
@Override
|
||||
public void init(Configuration config) {
|
||||
long expirationMinutes = config.getMetaCache().getExpirationMinutes();
|
||||
int initialCapacity = config.getMetaCache().getInitialCapacity();
|
||||
long maxCapacity = config.getMetaCache().getMaxCapacity();
|
||||
cache = Caffeine.newBuilder().expireAfterAccess(expirationMinutes, TimeUnit.MINUTES)
|
||||
.initialCapacity(initialCapacity).maximumSize(maxCapacity).build();
|
||||
configuration = config;
|
||||
cache = Caffeine.newBuilder().initialCapacity(1000).build();
|
||||
long cacheRefreshMinutes = configuration.getMetaCache().getCacheRefreshMinutes();
|
||||
if (cacheRefreshMinutes > 0) {
|
||||
timer.schedule(new TimerTask() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
refreshCache(config.getMetaCache().getExpirationMinutes());
|
||||
}
|
||||
}, 60000, cacheRefreshMinutes * 60 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshCache(long expirationMinutes) {
|
||||
long oldestTimestamp = System.currentTimeMillis() - (expirationMinutes * 60 * 1000);
|
||||
final BaseConfiguration apacheConf = new BaseConfiguration();
|
||||
Accumulo accumuloConf = configuration.getAccumulo();
|
||||
apacheConf.setProperty("instance.name", accumuloConf.getInstanceName());
|
||||
apacheConf.setProperty("instance.zookeeper.host", accumuloConf.getZookeepers());
|
||||
final ClientConfiguration aConf = new ClientConfiguration(Collections.singletonList(apacheConf));
|
||||
String metaTable = configuration.getMetaTable();
|
||||
Map<String, Map<String, Long>> metricMap = new HashMap<>();
|
||||
try {
|
||||
final Instance instance = new ZooKeeperInstance(aConf);
|
||||
Connector connector = instance.getConnector(accumuloConf.getUsername(),
|
||||
new PasswordToken(accumuloConf.getPassword()));
|
||||
Scanner scanner = connector.createScanner(metaTable, Authorizations.EMPTY);
|
||||
Key begin = new Key(Meta.VALUE_PREFIX);
|
||||
Key end = new Key("w" + '\0');
|
||||
Range range = new Range(begin, true, end, false);
|
||||
scanner.setRange(range);
|
||||
LOG.debug("Begin scanning " + metaTable);
|
||||
for (Map.Entry<Key, Value> entry : scanner) {
|
||||
Meta meta = Meta.parse(entry.getKey(), entry.getValue(), Meta.VALUE_PREFIX);
|
||||
String metric = meta.getMetric();
|
||||
String tagKey = meta.getTagKey();
|
||||
Map<String, Long> tagMap = metricMap.get(metric);
|
||||
if (tagMap == null) {
|
||||
tagMap = new HashMap<>();
|
||||
metricMap.put(metric, tagMap);
|
||||
}
|
||||
long numTagValues = tagMap.getOrDefault(tagKey, 0l);
|
||||
if (entry.getKey().getTimestamp() > oldestTimestamp) {
|
||||
tagMap.put(tagKey, ++numTagValues);
|
||||
if (numTagValues <= configuration.getMetaCache().getMaxTagValues()) {
|
||||
cache.put(meta, DUMMY);
|
||||
} else {
|
||||
// found maxTagValues on this refresh, so remove this key
|
||||
cache.invalidate(meta);
|
||||
}
|
||||
} else {
|
||||
// this entry is more than expirationMinutes old, so remove it
|
||||
cache.invalidate(meta);
|
||||
}
|
||||
}
|
||||
LOG.debug("Finished scanning " + metaTable);
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,5 +129,4 @@ public class MetaCacheImpl implements MetaCache {
|
||||
public boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import org.apache.accumulo.core.data.Range;
|
||||
import org.apache.accumulo.core.data.Value;
|
||||
import org.apache.commons.configuration.BaseConfiguration;
|
||||
import org.springframework.boot.Banner.Mode;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import timely.api.model.Meta;
|
||||
@@ -26,7 +27,7 @@ public class GetMetricTableSplitPoints {
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
try (ConfigurableApplicationContext ctx = new SpringApplicationBuilder(SpringBootstrap.class)
|
||||
.bannerMode(Mode.OFF).web(false).run(args)) {
|
||||
.bannerMode(Mode.OFF).web(WebApplicationType.NONE).run(args)) {
|
||||
Configuration conf = ctx.getBean(Configuration.class);
|
||||
|
||||
final BaseConfiguration apacheConf = new BaseConfiguration();
|
||||
|
||||
@@ -4,16 +4,22 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import timely.configuration.Configuration;
|
||||
import timely.configuration.SpringBootstrap;
|
||||
|
||||
public class ConfigurationTest {
|
||||
|
||||
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void createContext() {
|
||||
context = new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@After
|
||||
public void closeContext() {
|
||||
@@ -24,7 +30,7 @@ public class ConfigurationTest {
|
||||
public void testMinimalConfiguration() throws Exception {
|
||||
context.register(SpringBootstrap.class);
|
||||
// @formatter:off
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
TestPropertyValues.of(
|
||||
"timely.server.ip:127.0.0.1",
|
||||
"timely.server.tcp-port:54321",
|
||||
"timely.server.udp-port:54325",
|
||||
@@ -38,7 +44,7 @@ public class ConfigurationTest {
|
||||
"timely.accumulo.password:secret",
|
||||
"timely.http.host:localhost",
|
||||
"timely.security.serverSsl.use-generated-keypair:true",
|
||||
"timely.metric-age-off-days[default]:7");
|
||||
"timely.metric-age-off-days[default]:7").applyTo(this.context);
|
||||
// @formatter:on
|
||||
context.refresh();
|
||||
Configuration config = this.context.getBean(Configuration.class);
|
||||
@@ -62,7 +68,7 @@ public class ConfigurationTest {
|
||||
public void testMissingSSLProperty() throws Exception {
|
||||
context.register(SpringBootstrap.class);
|
||||
// @formatter:off
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
TestPropertyValues.of(
|
||||
"timely.server.ip:127.0.0.1",
|
||||
"timely.server.tcp-port:54321",
|
||||
"timely.server.udp-port:54325",
|
||||
@@ -74,7 +80,7 @@ public class ConfigurationTest {
|
||||
"timely.accumulo.instance-name:test",
|
||||
"timely.accumulo.username:root",
|
||||
"timely.accumulo.password:secret",
|
||||
"timely.http.host:localhost");
|
||||
"timely.http.host:localhost").applyTo(this.context);
|
||||
// @formatter:on
|
||||
context.refresh();
|
||||
}
|
||||
@@ -83,7 +89,7 @@ public class ConfigurationTest {
|
||||
public void testSSLProperty() throws Exception {
|
||||
context.register(SpringBootstrap.class);
|
||||
// @formatter:off
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
TestPropertyValues.of(
|
||||
"timely.server.ip:127.0.0.1",
|
||||
"timely.server.tcp-port:54321",
|
||||
"timely.server.udp-port:54325",
|
||||
@@ -97,7 +103,7 @@ public class ConfigurationTest {
|
||||
"timely.accumulo.password:secret",
|
||||
"timely.http.host:localhost",
|
||||
"timely.security.serverSsl.certificate-file:/tmp/foo",
|
||||
"timely.security.serverSsl.key-file:/tmp/bar");
|
||||
"timely.security.serverSsl.key-file:/tmp/bar").applyTo(this.context);
|
||||
// @formatter:on
|
||||
context.refresh();
|
||||
}
|
||||
|
||||
@@ -30,19 +30,19 @@ public class AuthCacheTest {
|
||||
|
||||
@AfterClass
|
||||
public static void after() {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
AuthCache.setSessionMaxAge(config.getSecurity());
|
||||
AuthCache.configure(config.getSecurity());
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("test", "test1");
|
||||
AuthenticationService.authenticate(token, cookie);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
|
||||
@@ -22,8 +22,8 @@ public class AuthenticationServiceTest {
|
||||
public static void before() {
|
||||
config = TestConfiguration.createMinimalConfigurationForTest();
|
||||
config.getSecurity().setSessionMaxAge(Integer.MAX_VALUE);
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.setSessionMaxAge(config.getSecurity());
|
||||
AuthCache.resetConfiguration();
|
||||
AuthCache.configure(config.getSecurity());
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -34,7 +34,7 @@ public class AuthenticationServiceTest {
|
||||
|
||||
@AfterClass
|
||||
public static void after() {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
|
||||
@@ -70,14 +70,14 @@ public class HttpRequestDecoderTest {
|
||||
anonConfig = TestConfiguration.createMinimalConfigurationForTest();
|
||||
anonConfig.getSecurity().setAllowAnonymousHttpAccess(true);
|
||||
cookie = URLEncoder.encode(UUID.randomUUID().toString(), StandardCharsets.UTF_8.name());
|
||||
AuthCache.setSessionMaxAge(config.getSecurity());
|
||||
AuthCache.configure(config.getSecurity());
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("test", "test1");
|
||||
AuthenticationService.authenticate(token, cookie);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after() {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Before
|
||||
|
||||
@@ -47,12 +47,12 @@ public class BasicAuthLoginRequestHandlerTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void before() throws Exception {
|
||||
AuthCache.setSessionMaxAge(TestConfiguration.createMinimalConfigurationForTest().getSecurity());
|
||||
AuthCache.configure(TestConfiguration.createMinimalConfigurationForTest().getSecurity());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Before
|
||||
|
||||
@@ -64,14 +64,14 @@ public class WebSocketRequestDecoderTest {
|
||||
anonConfig = TestConfiguration.createMinimalConfigurationForTest();
|
||||
anonConfig.getSecurity().setAllowAnonymousWsAccess(true);
|
||||
cookie = URLEncoder.encode(UUID.randomUUID().toString(), StandardCharsets.UTF_8.name());
|
||||
AuthCache.setSessionMaxAge(config.getSecurity());
|
||||
AuthCache.configure(config.getSecurity());
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("test", "test1");
|
||||
AuthCache.put(cookie, new TimelyPrincipal(TimelyUser.ANONYMOUS_USER));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after() {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Before
|
||||
|
||||
@@ -41,6 +41,11 @@ public class CaptureChannelHandlerContext implements ChannelHandlerContext {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean hasAttr(AttributeKey<T> attributeKey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel channel() {
|
||||
return null;
|
||||
|
||||
@@ -65,7 +65,7 @@ public class OneWaySSLBase extends QueryBase {
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public class OneWaySSLBasicAuthAccessIT extends OneWaySSLBase {
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -156,7 +156,7 @@ public class TwoWaySSLFailureIT extends QueryBase {
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Test(expected = UnauthorizedUserException.class)
|
||||
|
||||
@@ -160,7 +160,7 @@ public class TwoWaySSLIT extends QueryBase {
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -135,7 +135,7 @@ public class TwoWaySSLOpenSSLIT extends QueryBase {
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -43,7 +43,7 @@ public class TcpClientIT extends OneWaySSLBase {
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -57,7 +57,7 @@ public class UdpClientIT extends MacITBase {
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -73,7 +73,7 @@ public class WebSocketClientIT extends OneWaySSLBase {
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
s.shutdown();
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
public void testWorkflow(WebSocketSubscriptionClient client) throws Exception {
|
||||
|
||||
@@ -8,6 +8,7 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -20,6 +21,13 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.select.Elements;
|
||||
@@ -130,12 +138,44 @@ public class HttpApiIT extends OneWaySSLBase {
|
||||
String metrics = "https://localhost:54322/api/metrics";
|
||||
// Test prefix matching
|
||||
String result = query(metrics, "application/json");
|
||||
assertEquals(expected, result);
|
||||
|
||||
Gson gson = new Gson();
|
||||
JsonObject response = gson.fromJson(result, JsonObject.class);
|
||||
JsonArray metricsArray = response.getAsJsonArray("metrics");
|
||||
assertEquals(3, metricsArray.size());
|
||||
|
||||
for (JsonElement e : metricsArray) {
|
||||
JsonObject metricObject = e.getAsJsonObject();
|
||||
String metricName = metricObject.get("metric").getAsString();
|
||||
Iterator<JsonElement> tagItr = metricObject.get("tags").getAsJsonArray().iterator();
|
||||
Multimap<String, String> tagMap = HashMultimap.create();
|
||||
while (tagItr.hasNext()) {
|
||||
JsonObject tagObject = tagItr.next().getAsJsonObject();
|
||||
tagMap.put(tagObject.get("key").getAsString(), tagObject.get("value").getAsString());
|
||||
}
|
||||
switch (metricName) {
|
||||
case "sys.cpu.user":
|
||||
assertEquals(2, tagMap.size());
|
||||
assertTrue(CollectionUtils.isEqualCollection(Arrays.asList("value1"), tagMap.get("tag1")));
|
||||
assertTrue(CollectionUtils.isEqualCollection(Arrays.asList("value2"), tagMap.get("tag2")));
|
||||
break;
|
||||
case "sys.cpu.idle":
|
||||
assertEquals(2, tagMap.size());
|
||||
assertTrue(CollectionUtils.isEqualCollection(Arrays.asList("value3"), tagMap.get("tag3")));
|
||||
assertTrue(CollectionUtils.isEqualCollection(Arrays.asList("value4"), tagMap.get("tag4")));
|
||||
break;
|
||||
case "zzzz":
|
||||
assertEquals(1, tagMap.size());
|
||||
assertTrue(CollectionUtils.isEqualCollection(Arrays.asList("localhost"), tagMap.get("host")));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
s.shutdown();
|
||||
}
|
||||
// @formatter:on
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -50,7 +50,7 @@ public class TimelyTcpIT extends MacITBase {
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -64,7 +64,7 @@ public class TimelyUdpIT extends MacITBase {
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -176,7 +176,7 @@ public class WebSocketIT extends OneWaySSLBase {
|
||||
|
||||
@AfterClass
|
||||
public static void after() {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
private EventLoopGroup group = null;
|
||||
|
||||
@@ -46,9 +46,12 @@
|
||||
<user-service id="usernamePasswordService">
|
||||
<user name="test" password="test1" authorities="A,B,C" />
|
||||
</user-service>
|
||||
|
||||
|
||||
<beans:bean id="noOpPasswordEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder"/>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
<beans:property name="userDetailsService" ref="usernamePasswordService"/>
|
||||
<beans:property name="passwordEncoder" ref="noOpPasswordEncoder"/>
|
||||
</beans:bean>
|
||||
|
||||
<authentication-manager alias="authenticationManager">
|
||||
|
||||
Reference in new issue
Block a user