mirror of
https://github.com/NationalSecurityAgency/timely.git
synced 2026-11-09 17:36:01 -10:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69203cda3b | ||
|
|
eb286bb33b |
No files matched your search
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<version>1.3.7-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>timely-analytics</artifactId>
|
||||
<!--
|
||||
|
||||
@@ -13,6 +13,10 @@ CONF_DIR=${BASE_DIR}/conf
|
||||
|
||||
. ${BIN_DIR}/timely-balancer-env.sh
|
||||
|
||||
HOST_IP=$(hostname -I | awk '{print $1}')
|
||||
HOST=$(hostname -s)
|
||||
HOST_FQDN=$(hostname -f)
|
||||
|
||||
for i in $(seq 1 $NUM_PROFILES); do
|
||||
if [ "$NUM_PROFILES" -eq "1" ]; then
|
||||
FILENAME=timely-balancer.yml
|
||||
@@ -22,6 +26,9 @@ for i in $(seq 1 $NUM_PROFILES); do
|
||||
|
||||
echo "creating configuration file ${CONF_DIR}/${FILENAME}"
|
||||
cp ${CONF_DIR}/timely-balancer-template.yml ${CONF_DIR}/${FILENAME}
|
||||
sed -i "s/\${HOST}/${HOST}/g" ${CONF_DIR}/${FILENAME}
|
||||
sed -i "s/\${HOST_FQDN}/${HOST_FQDN}/g" ${CONF_DIR}/${FILENAME}
|
||||
sed -i "s/\${HOST_IP}/${HOST_IP}/g" ${CONF_DIR}/${FILENAME}
|
||||
sed -i "s/\${ZOOKEEPERS}/${ZOOKEEPERS}/g" ${CONF_DIR}/${FILENAME}
|
||||
MULTIPLE=$(($i - 1))
|
||||
TCP_PORT=$(($TCP_PORT_START + $MULTIPLE * $PORT_INCREMENT))
|
||||
|
||||
@@ -8,17 +8,13 @@ WEBSOCKET_PORT_START=4244
|
||||
UDP_PORT_START=4245
|
||||
PORT_INCREMENT=100
|
||||
|
||||
HOST_IP=0.0.0.0
|
||||
HOST=$(hostname -s)
|
||||
HOST_FQDN=$(hostname -f)
|
||||
|
||||
GENERATE_KEYS=true
|
||||
TRUST_STORE_TYPE=
|
||||
TRUST_STORE_FILE=
|
||||
SERVER_CERTIFICATE_FILE=
|
||||
SERVER_KEY_FILE=
|
||||
SERVER_KEY_PASSWORD=
|
||||
SERVER_USE_GENERATED_KEYPAIR=true
|
||||
CLIENT_KEY_FILE=
|
||||
CLIENT_KEY_TYPE=pkcs12
|
||||
CLIENT_KEY_PASSWORD=
|
||||
TRUST_STORE_PEM=
|
||||
TRUST_STORE_JKS=
|
||||
TRUST_STORE_PASSWORD=
|
||||
KEY_STORE_TYPE=
|
||||
KEY_STORE_FILE=
|
||||
KEY_STORE_PASSWORD=
|
||||
AUTHORIZATION_URL=
|
||||
AUTHORIZATION_CERTIFICATE_TYPE=
|
||||
AUTHORIZATION_CERTIFICATE_FILE=
|
||||
@@ -10,10 +10,6 @@ fi
|
||||
|
||||
THIS_DIR="${THIS_SCRIPT%/*}"
|
||||
|
||||
set -a
|
||||
. ${THIS_DIR}/timely-balancer-env.sh
|
||||
set +a
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
export PROFILE_NUM=$1
|
||||
PROFILE_ARG="--spring.profiles.active=${PROFILE_NUM}"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
trust.store.type=${TRUST_STORE_TYPE}
|
||||
trust.store.file=${TRUST_STORE_FILE}
|
||||
trust.store.password=${TRUST_STORE_PASSWORD}
|
||||
key.store.type=${KEY_STORE_TYPE}
|
||||
key.store.file=${KEY_STORE_FILE}
|
||||
key.store.password=${KEY_STORE_PASSWORD}
|
||||
authorization.url=${AUTHORIZATION_URL}
|
||||
authorization.certificate.type=${AUTHORIZATION_CERTIFICATE_TYPE}
|
||||
authorization.certificate.file=${AUTHORIZATION_CERTIFICATE_FILE}
|
||||
+41
-34
@@ -1,44 +1,51 @@
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/security"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/security
|
||||
http://www.springframework.org/schema/security/spring-security.xsd
|
||||
http://www.springframework.org/schema/util
|
||||
http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
<context:property-placeholder location="classpath:security.properties"/>
|
||||
|
||||
<beans:bean id="clientSsl" class="timely.configuration.ClientSsl">
|
||||
<beans:property name="trustStoreType" value="${trust.store.type}"/>
|
||||
<beans:property name="trustStoreFile" value="${trust.store.file}"/>
|
||||
<beans:property name="trustStorePassword" value="${trust.store.password}"/>
|
||||
<beans:property name="keyStoreType" value="${key.store.type}"/>
|
||||
<beans:property name="keyStoreFile" value="${key.store.file}"/>
|
||||
<beans:property name="keyStorePassword" value="${key.store.password}"/>
|
||||
http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<beans:bean id="x509PrincipalExtractor" class="org.springframework.security.web.authentication.preauth.x509.SubjectDnX509PrincipalExtractor">
|
||||
<beans:property name="subjectDnRegex" value="CN=(.*?)(?:,|$)"/>
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="authorizationProperties" class="timely.configuration.AuthorizationProperties">
|
||||
<beans:property name="authorizationUrl" value="${authorization.url}"/>
|
||||
<beans:property name="publicCertificateType" value="${authorization.certificate.type}"/>
|
||||
<beans:property name="publicCertificateFile" value="${authorization.certificate.file}"/>
|
||||
<beans:bean id="timelyUserDetailsService" class="timely.auth.UserDetailsService">
|
||||
<beans:property name="users">
|
||||
<util:list>
|
||||
<beans:bean class="timely.auth.TimelyUser">
|
||||
<beans:constructor-arg name="subjectDn">
|
||||
<beans:value>CN=example.com</beans:value>
|
||||
</beans:constructor-arg>
|
||||
<beans:constructor-arg name="auths">
|
||||
<util:list>
|
||||
<beans:value>D</beans:value>
|
||||
<beans:value>E</beans:value>
|
||||
<beans:value>F</beans:value>
|
||||
</util:list>
|
||||
</beans:constructor-arg>
|
||||
<beans:constructor-arg name="roles">
|
||||
<util:list>
|
||||
<beans:value>G</beans:value>
|
||||
<beans:value>H</beans:value>
|
||||
<beans:value>I</beans:value>
|
||||
</util:list>
|
||||
</beans:constructor-arg>
|
||||
</beans:bean>
|
||||
</util:list>
|
||||
</beans:property>
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="remoteUserDetailsService" class="timely.auth.RemoteUserDetailsService">
|
||||
<beans:constructor-arg ref="clientSsl"/>
|
||||
<beans:constructor-arg ref="authorizationProperties"/>
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="x509AuthorizationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
|
||||
<beans:property name="preAuthenticatedUserDetailsService" ref="remoteUserDetailsService" />
|
||||
</beans:bean>
|
||||
|
||||
<user-service id="usernamePasswordService">
|
||||
<user name="test" password="test1" authorities="A,B,C" />
|
||||
</user-service>
|
||||
|
||||
<beans:bean id="x509AuthorizationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
|
||||
<beans:property name="preAuthenticatedUserDetailsService" ref="timelyUserDetailsService" />
|
||||
</beans:bean>
|
||||
|
||||
<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"/>
|
||||
|
||||
@@ -46,7 +53,7 @@
|
||||
<beans:property name="userDetailsService" ref="usernamePasswordService"/>
|
||||
<beans:property name="passwordEncoder" ref="noOpPasswordEncoder"/>
|
||||
</beans:bean>
|
||||
|
||||
|
||||
<authentication-manager alias="authenticationManager">
|
||||
<!-- X509 PreAuthenticated authorization provider -->
|
||||
<authentication-provider ref="x509AuthorizationProvider"/>
|
||||
|
||||
@@ -13,25 +13,23 @@ timely-balancer:
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
serverSsl:
|
||||
key-store-type: ${KEY_STORE_TYPE}
|
||||
key-store-file: ${KEY_STORE_FILE}
|
||||
key-store-password: ${KEY_STORE_PASSWORD}
|
||||
use-generated-keypair: ${GENERATE_KEYS}
|
||||
ignore-ssl-handshake-errors: true
|
||||
trust-store-type: ${TRUST_STORE_TYPE}
|
||||
trust-store-file: ${TRUST_STORE_FILE}
|
||||
trust-store-password: ${TRUST_STORE_PASSWORD}
|
||||
certificate-file: ${SERVER_CERTIFICATE_FILE}
|
||||
key-file: ${SERVER_KEY_FILE}
|
||||
key-password: ${SERVER_KEY_PASSWORD}
|
||||
use-generated-keypair: ${SERVER_USE_GENERATED_KEYPAIR}
|
||||
trust-store-file: ${TRUST_STORE_PEM}
|
||||
use-openssl: true
|
||||
#use-ciphers:
|
||||
clientSsl:
|
||||
key-store-type: ${KEY_STORE_TYPE}
|
||||
key-store-file: ${KEY_STORE_FILE}
|
||||
key-store-password: ${KEY_STORE_PASSWORD}
|
||||
trust-store-type: ${TRUST_STORE_TYPE}
|
||||
trust-store-file: ${TRUST_STORE_FILE}
|
||||
trust-store-password: ${TRUST_STORE_PASSWORD}
|
||||
jwtSsl:
|
||||
key-store-type: ${AUTHORIZATION_CERTIFICATE_TYPE}
|
||||
key-store-file: ${AUTHORIZATION_CERTIFICATE_FILE}
|
||||
key-store-password: ${AUTHORIZATION_CERTIFICATE_PASSWORD}
|
||||
keyFile: ${CLIENT_KEY_FILE}
|
||||
keyType: ${CLIENT_KEY_TYPE}
|
||||
keyPassword: ${CLIENT_KEY_PASSWORD}
|
||||
trustStoreFile: ${TRUST_STORE_JKS}
|
||||
trustStoreType: jks
|
||||
trustStorePassword: ${TRUST_STORE_PASSWORD}
|
||||
jwtCheckKeyStore:
|
||||
jwtCheckKeyType:
|
||||
jwtCheckKeyPassword:
|
||||
cache:
|
||||
enabled: false
|
||||
metric-age-off-hours:
|
||||
|
||||
@@ -13,32 +13,30 @@ timely-balancer:
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
serverSsl:
|
||||
key-store-type:
|
||||
key-store-file:
|
||||
key-store-password:
|
||||
certificate-file:
|
||||
key-file:
|
||||
#key-password:
|
||||
use-generated-keypair: true
|
||||
ignore-ssl-handshake-errors: true
|
||||
trust-store-type:
|
||||
trust-store-file:
|
||||
trust-store-password:
|
||||
use-openssl: true
|
||||
#use-ciphers:
|
||||
clientSsl:
|
||||
key-store-type:
|
||||
key-store-file:
|
||||
key-store-password:
|
||||
trust-store-type:
|
||||
trust-store-file:
|
||||
trust-store-password:
|
||||
jwtSsl:
|
||||
key-store-type:
|
||||
key-store-file:
|
||||
key-store-password:
|
||||
keyFile:
|
||||
keyType: pkcs12
|
||||
#keyPassword:
|
||||
trustStoreFile:
|
||||
trustStoreType: jks
|
||||
#trustStorePassword:
|
||||
jwtCheckKeyStore:
|
||||
jwtCheckKeyType:
|
||||
jwtCheckKeyPassword:
|
||||
cache:
|
||||
enabled: false
|
||||
metric-age-off-hours:
|
||||
default: 26
|
||||
nonCachedMetrics:
|
||||
server:
|
||||
ip: 0.0.0.0
|
||||
ip: 127.0.0.1
|
||||
tcpPort: 4242
|
||||
numTcpPools: 1
|
||||
tcpBufferSize: 100
|
||||
@@ -79,7 +77,7 @@ timely-balancer:
|
||||
testOnReturn: false
|
||||
http:
|
||||
host: localhost
|
||||
ip: 0.0.0.0
|
||||
ip: 127.0.0.1
|
||||
port: 4243
|
||||
redirect-path: /secure-me
|
||||
strict-transport-max-age: 608400
|
||||
@@ -108,7 +106,7 @@ timely-balancer:
|
||||
testOnBorrow: false
|
||||
testOnReturn: false
|
||||
websocket:
|
||||
ip: 0.0.0.0
|
||||
ip: 127.0.0.1
|
||||
port: 5244
|
||||
timeout: 60
|
||||
subscription-lag: 120
|
||||
|
||||
+19
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<version>1.3.7-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>timely-balancer</artifactId>
|
||||
<dependencies>
|
||||
@@ -51,6 +51,12 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.accumulo</groupId>
|
||||
<artifactId>accumulo-core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.accumulo</groupId>
|
||||
@@ -91,6 +97,12 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.hadoop</groupId>
|
||||
<artifactId>hadoop-common</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>jdk.tools</groupId>
|
||||
<artifactId>jdk.tools</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.hadoop</groupId>
|
||||
@@ -107,6 +119,12 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -5,6 +5,7 @@ import static timely.Server.SERVICE_DISCOVERY_PATH;
|
||||
import static timely.store.cache.DataStoreCache.NON_CACHED_METRICS;
|
||||
import static timely.store.cache.DataStoreCache.NON_CACHED_METRICS_LOCK_PATH;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
@@ -51,6 +52,7 @@ import io.netty.handler.ssl.OpenSslServerContext;
|
||||
import io.netty.handler.ssl.OpenSslServerSessionContext;
|
||||
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 io.netty.handler.stream.ChunkedWriteHandler;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
@@ -69,8 +71,8 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import timely.auth.AuthCache;
|
||||
import timely.auth.JWTTokenHandler;
|
||||
import timely.auth.util.SslHelper;
|
||||
import timely.balancer.configuration.BalancerConfiguration;
|
||||
import timely.balancer.configuration.ClientSsl;
|
||||
import timely.balancer.configuration.SpringBootstrap;
|
||||
import timely.balancer.connection.http.HttpClientPool;
|
||||
import timely.balancer.connection.tcp.TcpClientPool;
|
||||
@@ -84,7 +86,6 @@ import timely.balancer.netty.ws.WsRelayHandler;
|
||||
import timely.balancer.resolver.BalancedMetricResolver;
|
||||
import timely.balancer.resolver.MetricResolver;
|
||||
import timely.client.http.HttpClient;
|
||||
import timely.configuration.ClientSsl;
|
||||
import timely.configuration.ServerSsl;
|
||||
import timely.netty.http.HttpStaticFileServerHandler;
|
||||
import timely.netty.http.NonSslRedirectHandler;
|
||||
@@ -322,13 +323,32 @@ public class Balancer {
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate("localhost", begin, end);
|
||||
ssl = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey());
|
||||
} else {
|
||||
if (null == sslCfg.getKeyStoreFile()) {
|
||||
String cert = sslCfg.getCertificateFile();
|
||||
String key = sslCfg.getKeyFile();
|
||||
String keyPass = sslCfg.getKeyPassword();
|
||||
if (null == cert || null == key) {
|
||||
throw new IllegalArgumentException("Check your SSL properties, something is wrong.");
|
||||
}
|
||||
ssl = SslHelper.getSslContextBuilder(sslCfg);
|
||||
ssl = SslContextBuilder.forServer(new File(cert), new File(key), keyPass);
|
||||
}
|
||||
|
||||
ssl.ciphers(sslCfg.getUseCiphers());
|
||||
|
||||
// Can't set to REQUIRE because the CORS pre-flight requests will fail.
|
||||
ssl.clientAuth(ClientAuth.OPTIONAL);
|
||||
|
||||
Boolean useOpenSSL = sslCfg.isUseOpenssl();
|
||||
if (useOpenSSL) {
|
||||
ssl.sslProvider(SslProvider.OPENSSL);
|
||||
} else {
|
||||
ssl.sslProvider(SslProvider.JDK);
|
||||
}
|
||||
String trustStore = sslCfg.getTrustStoreFile();
|
||||
if (null != trustStore) {
|
||||
if (!trustStore.isEmpty()) {
|
||||
ssl.trustManager(new File(trustStore));
|
||||
}
|
||||
}
|
||||
return ssl.build();
|
||||
}
|
||||
|
||||
@@ -336,7 +356,7 @@ public class Balancer {
|
||||
|
||||
ClientSsl ssl = config.getSecurity().getClientSsl();
|
||||
return HttpClient.getSSLContext(ssl.getTrustStoreFile(), ssl.getTrustStoreType(), ssl.getTrustStorePassword(),
|
||||
ssl.getKeyStoreFile(), ssl.getKeyStoreType(), ssl.getKeyStorePassword());
|
||||
ssl.getKeyFile(), ssl.getKeyType(), ssl.getKeyPassword());
|
||||
}
|
||||
|
||||
private void ensureZkPaths(CuratorFramework curatorFramework, String[] paths) {
|
||||
@@ -365,7 +385,7 @@ public class Balancer {
|
||||
ensureZkPaths(curatorFramework, zkPaths);
|
||||
|
||||
AuthCache.configure(balancerConfig.getSecurity());
|
||||
JWTTokenHandler.init(balancerConfig.getSecurity().getJwtSsl(), null);
|
||||
JWTTokenHandler.init(balancerConfig.getSecurity(), null);
|
||||
final boolean useEpoll = useEpoll();
|
||||
Class<? extends ServerSocketChannel> channelClass;
|
||||
Class<? extends Channel> datagramChannelClass;
|
||||
@@ -516,12 +536,12 @@ public class Balancer {
|
||||
ch.pipeline().addLast("queryDecoder", new timely.netty.http.HttpRequestDecoder(
|
||||
balancerConfig.getSecurity(), balancerConfig.getHttp()));
|
||||
ch.pipeline().addLast("fileServer", new HttpStaticFileServerHandler().setIgnoreSslHandshakeErrors(
|
||||
balancerConfig.getSecurity().getServerSsl().isIgnoreSslHandshakeErrors()));
|
||||
balancerConfig.getSecurity().getServerSsl().isUseGeneratedKeypair()));
|
||||
ch.pipeline().addLast("login",
|
||||
new X509LoginRequestHandler(balancerConfig.getSecurity(), balancerConfig.getHttp()));
|
||||
ch.pipeline().addLast("httpRelay", new HttpRelayHandler(metricResolver, httpClientPool));
|
||||
ch.pipeline().addLast("error", new TimelyExceptionHandler().setIgnoreSslHandshakeErrors(
|
||||
balancerConfig.getSecurity().getServerSsl().isIgnoreSslHandshakeErrors()));
|
||||
balancerConfig.getSecurity().getServerSsl().isUseGeneratedKeypair()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package timely.balancer.configuration;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import timely.configuration.ClientSsl;
|
||||
import timely.configuration.Security;
|
||||
|
||||
public class BalancerSecurity extends Security {
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package timely.balancer.configuration;
|
||||
|
||||
public class ClientSsl {
|
||||
|
||||
private String keyFile;
|
||||
private String keyType;
|
||||
private String keyPassword;
|
||||
private String trustStoreFile;
|
||||
private String trustStoreType;
|
||||
private String trustStorePassword;
|
||||
private boolean useClientCert = true;
|
||||
private boolean hostVerificationEnabled = true;
|
||||
|
||||
public String getKeyFile() {
|
||||
return keyFile;
|
||||
}
|
||||
|
||||
public void setKeyFile(String keyFile) {
|
||||
this.keyFile = keyFile;
|
||||
}
|
||||
|
||||
public String getKeyType() {
|
||||
return keyType;
|
||||
}
|
||||
|
||||
public void setKeyType(String keyType) {
|
||||
this.keyType = keyType;
|
||||
}
|
||||
|
||||
public String getKeyPassword() {
|
||||
return keyPassword;
|
||||
}
|
||||
|
||||
public void setKeyPassword(String keyPassword) {
|
||||
this.keyPassword = keyPassword;
|
||||
}
|
||||
|
||||
public String getTrustStoreFile() {
|
||||
return trustStoreFile;
|
||||
}
|
||||
|
||||
public void setTrustStoreFile(String trustStoreFile) {
|
||||
this.trustStoreFile = trustStoreFile;
|
||||
}
|
||||
|
||||
public String getTrustStoreType() {
|
||||
return trustStoreType;
|
||||
}
|
||||
|
||||
public void setTrustStoreType(String trustStoreType) {
|
||||
this.trustStoreType = trustStoreType;
|
||||
}
|
||||
|
||||
public String getTrustStorePassword() {
|
||||
return trustStorePassword;
|
||||
}
|
||||
|
||||
public void setTrustStorePassword(String trustStorePassword) {
|
||||
this.trustStorePassword = trustStorePassword;
|
||||
}
|
||||
|
||||
public void setUseClientCert(boolean useClientCert) {
|
||||
this.useClientCert = useClientCert;
|
||||
}
|
||||
|
||||
public boolean isUseClientCert() {
|
||||
return useClientCert;
|
||||
}
|
||||
|
||||
public void setHostVerificationEnabled(boolean hostVerificationEnabled) {
|
||||
this.hostVerificationEnabled = hostVerificationEnabled;
|
||||
}
|
||||
|
||||
public boolean isHostVerificationEnabled() {
|
||||
return hostVerificationEnabled;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -4,13 +4,13 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.0.1</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.1</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);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<version>1.3.7-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>collectd-nsq-plugin</artifactId>
|
||||
<dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<version>1.3.7-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>collectd-plugin-parent</artifactId>
|
||||
<dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<version>1.3.7-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>collectd-timely-plugin</artifactId>
|
||||
<dependencies>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<version>1.3.7-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>timely-common</artifactId>
|
||||
<dependencies>
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<version>1.3.7-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>timely-app</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
Vendored
+2
-2
@@ -28,8 +28,8 @@
|
||||
}
|
||||
],
|
||||
"screenshots": [],
|
||||
"version": "2.0.1",
|
||||
"updated": "2024-01-26"
|
||||
"version": "1.3.7-SNAPSHOT",
|
||||
"updated": "2023-10-13"
|
||||
},
|
||||
"dependencies": {
|
||||
"classnames": "2.2.6",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "timely-datasource",
|
||||
"version": "2.0.1",
|
||||
"version": "1.3.7-SNAPSHOT",
|
||||
"description": "Timely",
|
||||
"backend": true,
|
||||
"alerting": true,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.0.1</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>
|
||||
@@ -40,19 +40,17 @@
|
||||
<os.detection.classifierWithLikes>fedora</os.detection.classifierWithLikes>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<surefire.forkCount>1C</surefire.forkCount>
|
||||
<version.accumulo>2.1.2</version.accumulo>
|
||||
<version.buildnumber-maven>1.4</version.buildnumber-maven>
|
||||
<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>
|
||||
@@ -78,22 +76,19 @@
|
||||
<version.maven-build-helper>3.0.0</version.maven-build-helper>
|
||||
<version.maven-compiler>3.8.1</version.maven-compiler>
|
||||
<version.maven-dependency>3.1.1</version.maven-dependency>
|
||||
<version.maven-failsafe-plugin>3.2.5</version.maven-failsafe-plugin>
|
||||
<version.maven-jar>3.1.2</version.maven-jar>
|
||||
<version.maven-pmd>3.12.0</version.maven-pmd>
|
||||
<version.maven-rpm>2.2.0</version.maven-rpm>
|
||||
<version.maven-shade>3.2.1</version.maven-shade>
|
||||
<version.maven-surefire-plugin>3.2.5</version.maven-surefire-plugin>
|
||||
<version.maven-surefire>3.0.0-M3</version.maven-surefire>
|
||||
<version.micrometer>1.11.1</version.micrometer>
|
||||
<version.netty>4.1.45.Final</version.netty>
|
||||
<version.netty-tcnative>2.0.29.Final</version.netty-tcnative>
|
||||
<version.os-maven>1.5.0.Final</version.os-maven>
|
||||
<version.powermock>1.6.4</version.powermock>
|
||||
<version.reactor-netty>0.8.5.RELEASE</version.reactor-netty>
|
||||
<version.slf4j>1.7.26</version.slf4j>
|
||||
<version.spotbugs-maven>4.7.3.5</version.spotbugs-maven>
|
||||
<version.spring-boot>2.1.3.RELEASE</version.spring-boot>
|
||||
<version.spring-webflux>5.1.4.RELEASE</version.spring-webflux>
|
||||
<version.tyrus>1.15</version.tyrus>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
@@ -185,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>
|
||||
@@ -260,10 +244,6 @@
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -325,44 +305,22 @@
|
||||
<groupId>org.apache.flink</groupId>
|
||||
<artifactId>flink-clients_2.11</artifactId>
|
||||
<version>${version.flink}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.flink</groupId>
|
||||
<artifactId>flink-java</artifactId>
|
||||
<version>${version.flink}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.flink</groupId>
|
||||
<artifactId>flink-streaming-java_2.11</artifactId>
|
||||
<version>${version.flink}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.hadoop</groupId>
|
||||
<artifactId>hadoop-client</artifactId>
|
||||
<version>${version.hadoop}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty</artifactId>
|
||||
@@ -379,10 +337,6 @@
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-reload4j</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
@@ -398,22 +352,10 @@
|
||||
<artifactId>hadoop-common</artifactId>
|
||||
<version>${version.hadoop}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>jdk.tools</groupId>
|
||||
<artifactId>jdk.tools</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-reload4j</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
@@ -433,10 +375,6 @@
|
||||
<artifactId>hadoop-minicluster</artifactId>
|
||||
<version>${version.hadoop}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>ch.qos.reload4j</groupId>
|
||||
<artifactId>reload4j</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty</artifactId>
|
||||
@@ -453,10 +391,6 @@
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-reload4j</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
@@ -507,22 +441,6 @@
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>${version.slf4j}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webflux</artifactId>
|
||||
<version>${version.spring-webflux}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>${version.spring-boot}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>collectd-plugin-parent</artifactId>
|
||||
@@ -640,57 +558,20 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${version.maven-compiler}</version>
|
||||
<configuration>
|
||||
<source>${maven.compiler.source}</source>
|
||||
<target>${maven.compiler.target}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>${version.maven-dependency}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-banned-dependencies</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<bannedDependencies>
|
||||
<excludes>
|
||||
<!-- do not use the following slf4j binders -->
|
||||
<exclude>ch.qos.reload4j:reload4j</exclude>
|
||||
<exclude>org.slf4j:slf4j-reload4j</exclude>
|
||||
<!-- spring boot microservices do not use 1.x versions of log4j -->
|
||||
<exclude>log4j:log4j</exclude>
|
||||
<!-- spring boot microservices do not use 1.x versions of junit -->
|
||||
<exclude>junit:junit</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<!-- some spring boot microservices include test dependencies which use 1.x versions of junit -->
|
||||
<include>junit:junit:*:*:test</include>
|
||||
</includes>
|
||||
</bannedDependencies>
|
||||
</rules>
|
||||
<fail>true</fail>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${version.maven-failsafe-plugin}</version>
|
||||
<version>${version.maven-surefire}</version>
|
||||
<configuration>
|
||||
<argLine>${failsafeArgLine} -Djava.library.path=${project.build.directory}/native/META-INF/native/libnetty_tcnative_linux_x86_64.so -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Dfile.encoding=UTF8 -Duser.timezone=GMT -Xmx1024m -Dapple.awt.UIElement=true -Djava.security.krb5.realm= -Djava.security.krb5.kdc= -Dzookeeper.sasl.client=false</argLine>
|
||||
<argLine>${failsafeArgLine} -Djava.library.path=${project.build.directory}/native/META-INF/native/libnetty_tcnative_linux_x86_64.so -Dzookeeper.sasl.client=false</argLine>
|
||||
<includes>
|
||||
<include>**/*IT.java</include>
|
||||
<include>**/*.java</include>
|
||||
</includes>
|
||||
<groups>timely.test.IntegrationTest</groups>
|
||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||
@@ -734,16 +615,9 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${version.maven-surefire-plugin}</version>
|
||||
<version>${version.maven-surefire}</version>
|
||||
<configuration>
|
||||
<reuseForks>false</reuseForks>
|
||||
<forkCount>${surefire.forkCount}</forkCount>
|
||||
<threadCount>1</threadCount>
|
||||
<threadCountClasses>1</threadCountClasses>
|
||||
<threadCountMethods>0</threadCountMethods>
|
||||
<threadCountSuites>0</threadCountSuites>
|
||||
<argLine>${sureFireArgLine} -Djava.library.path=${project.build.directory}/native/META-INF/native/libnetty_tcnative_linux_x86_64.so -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Dfile.encoding=UTF8 -Duser.timezone=GMT -Xmx1024m -Dapple.awt.UIElement=true -Djava.security.krb5.realm= -Djava.security.krb5.kdc= -Dzookeeper.sasl.client=false</argLine>
|
||||
<runOrder>random</runOrder>
|
||||
<argLine>${sureFireArgLine} -Djava.library.path=${project.build.directory}/native/META-INF/native/libnetty-tcnative_linux_x86_64.so -Dzookeeper.sasl.client=false</argLine>
|
||||
<excludedGroups>timely.test.IntegrationTest</excludedGroups>
|
||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||
</configuration>
|
||||
@@ -913,35 +787,6 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.0.0-M3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-no-snapshots</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireReleaseDeps>
|
||||
<message>Snapshot dependencies are prohibited on a release build.</message>
|
||||
<onlyWhenRelease>true</onlyWhenRelease>
|
||||
</requireReleaseDeps>
|
||||
<requireJavaVersion>
|
||||
<version>${java.version}</version>
|
||||
</requireJavaVersion>
|
||||
</rules>
|
||||
<fail>true</fail>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<reporting>
|
||||
@@ -1013,7 +858,7 @@
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<maven.compiler.release>${maven.compiler.target}</maven.compiler.release>
|
||||
<maven.compiler.release>8</maven.compiler.release>
|
||||
</properties>
|
||||
<build>
|
||||
<pluginManagement>
|
||||
@@ -1076,7 +921,10 @@
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>jdk8</id>
|
||||
<id>jdk-release-flag</id>
|
||||
<activation>
|
||||
<jdk>[9,)</jdk>
|
||||
</activation>
|
||||
<properties>
|
||||
<maven.compiler.release>8</maven.compiler.release>
|
||||
</properties>
|
||||
|
||||
@@ -13,6 +13,10 @@ CONF_DIR=${BASE_DIR}/conf
|
||||
|
||||
. ${BIN_DIR}/timely-env.sh
|
||||
|
||||
HOST_IP=$(hostname -I | awk '{print $1}')
|
||||
HOST=$(hostname -s)
|
||||
HOST_FQDN=$(hostname -f)
|
||||
|
||||
for i in $(seq 1 $NUM_PROFILES); do
|
||||
if [ "$NUM_PROFILES" -eq "1" ]; then
|
||||
FILENAME=timely.yml
|
||||
@@ -22,6 +26,9 @@ for i in $(seq 1 $NUM_PROFILES); do
|
||||
|
||||
echo "creating configuration file ${CONF_DIR}/${FILENAME}"
|
||||
cp ${CONF_DIR}/timely-template.yml ${CONF_DIR}/${FILENAME}
|
||||
sed -i "s/\${HOST}/${HOST}/g" ${CONF_DIR}/${FILENAME}
|
||||
sed -i "s/\${HOST_FQDN}/${HOST_FQDN}/g" ${CONF_DIR}/${FILENAME}
|
||||
sed -i "s/\${HOST_IP}/${HOST_IP}/g" ${CONF_DIR}/${FILENAME}
|
||||
sed -i "s/\${ZOOKEEPERS}/${ZOOKEEPERS}/g" ${CONF_DIR}/${FILENAME}
|
||||
sed -i "s/\${AGE_OFF_DAYS}/${AGE_OFF_DAYS}/g" ${CONF_DIR}/${FILENAME}
|
||||
MULTIPLE=$(($i - 1))
|
||||
|
||||
@@ -9,19 +9,4 @@ UDP_PORT_START=4245
|
||||
PORT_INCREMENT=100
|
||||
AGE_OFF_DAYS=7
|
||||
ACCUMULO_USER=root
|
||||
ACCUMULO_PASSWORD=secret
|
||||
|
||||
HOST_IP=0.0.0.0
|
||||
HOST=$(hostname -s)
|
||||
HOST_FQDN=$(hostname -f)
|
||||
|
||||
GENERATE_KEYS=true
|
||||
TRUST_STORE_TYPE=
|
||||
TRUST_STORE_FILE=
|
||||
TRUST_STORE_PASSWORD=
|
||||
KEY_STORE_TYPE=
|
||||
KEY_STORE_FILE=
|
||||
KEY_STORE_PASSWORD=
|
||||
AUTHORIZATION_URL=
|
||||
AUTHORIZATION_CERTIFICATE_TYPE=
|
||||
AUTHORIZATION_CERTIFICATE_FILE=
|
||||
ACCUMULO_PASSWORD=secret
|
||||
@@ -10,10 +10,6 @@ fi
|
||||
|
||||
THIS_DIR="${THIS_SCRIPT%/*}"
|
||||
|
||||
set -a
|
||||
. ${THIS_DIR}/timely-env.sh
|
||||
set +a
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
export PROFILE_NUM=$1
|
||||
PROFILE_ARG="--spring.profiles.active=${PROFILE_NUM}"
|
||||
@@ -57,9 +53,11 @@ if [ "$PID" == "" ]; then
|
||||
JVM_ARGS="${JVM_ARGS} -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"
|
||||
JVM_ARGS="${JVM_ARGS} -Djava.library.path=${NATIVE_DIR}"
|
||||
|
||||
JVM_ARGS="${JVM_ARGS} -Xmx4G -Xms4G -XX:NewSize=1G -XX:MaxNewSize=1G"
|
||||
JVM_ARGS="${JVM_ARGS} -Xmx4G -Xms4G -XX:NewSize=1G -XX:MaxNewSize=1G -XX:+UnlockDiagnosticVMOptions"
|
||||
JVM_ARGS="${JVM_ARGS} -XX:+UseConcMarkSweepGC -XX:+CMSScavengeBeforeRemark -XX:+ScavengeBeforeFullGC -XX:ReservedCodeCacheSize=384M -XX:+UseCodeCacheFlushing -XX:+UseParNewGC"
|
||||
JVM_ARGS="${JVM_ARGS} -XX:SurvivorRatio=8 -XX:ParallelGCThreads=16 -XX:ConcGCThreads=8 -XX:+UseCondCardMark -XX:ParGCCardsPerStrideChunk=32768"
|
||||
JVM_ARGS="${JVM_ARGS} -XX:+CMSClassUnloadingEnabled -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=30 -XX:+UseCMSInitiatingOccupancyOnly"
|
||||
JVM_ARGS="${JVM_ARGS} -XX:+UseCompressedOops -XX:+UseNUMA -Djava.net.preferIPv4Stack=true"
|
||||
JVM_ARGS="${JVM_ARGS} -XX:+UseG1GC -XX:MaxGCPauseMillis=4000 -XX:ParallelGCThreads=20 -XX:+UseStringDeduplication"
|
||||
|
||||
echo "$JAVA_HOME/bin/java ${JVM_ARGS} timely.Server --spring.config.name=timely ${PROFILE_ARG}"
|
||||
nohup $JAVA_HOME/bin/java ${JVM_ARGS} timely.Server --spring.config.name=timely ${PROFILE_ARG} >> ${LOG_DIR}/timely-server${PROFILE_NUM}-startup.log 2>&1 &
|
||||
|
||||
Regular → Executable
File mode changed.
@@ -1,9 +0,0 @@
|
||||
trust.store.type=${TRUST_STORE_TYPE}
|
||||
trust.store.file=${TRUST_STORE_FILE}
|
||||
trust.store.password=${TRUST_STORE_PASSWORD}
|
||||
key.store.type=${KEY_STORE_TYPE}
|
||||
key.store.file=${KEY_STORE_FILE}
|
||||
key.store.password=${KEY_STORE_PASSWORD}
|
||||
authorization.url=${AUTHORIZATION_URL}
|
||||
authorization.certificate.type=${AUTHORIZATION_CERTIFICATE_TYPE}
|
||||
authorization.certificate.file=${AUTHORIZATION_CERTIFICATE_FILE}
|
||||
+33
-26
@@ -1,39 +1,46 @@
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/security"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/security
|
||||
http://www.springframework.org/schema/security/spring-security.xsd
|
||||
http://www.springframework.org/schema/util
|
||||
http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<context:property-placeholder location="classpath:security.properties"/>
|
||||
<beans:bean id="x509PrincipalExtractor" class="org.springframework.security.web.authentication.preauth.x509.SubjectDnX509PrincipalExtractor">
|
||||
<beans:property name="subjectDnRegex" value="CN=(.*?)(?:,|$)"/>
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="clientSsl" class="timely.configuration.ClientSsl">
|
||||
<beans:property name="trustStoreType" value="${trust.store.type}"/>
|
||||
<beans:property name="trustStoreFile" value="${trust.store.file}"/>
|
||||
<beans:property name="trustStorePassword" value="${trust.store.password}"/>
|
||||
<beans:property name="keyStoreType" value="${key.store.type}"/>
|
||||
<beans:property name="keyStoreFile" value="${key.store.file}"/>
|
||||
<beans:property name="keyStorePassword" value="${key.store.password}"/>
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="authorizationProperties" class="timely.configuration.AuthorizationProperties">
|
||||
<beans:property name="authorizationUrl" value="${authorization.url}"/>
|
||||
<beans:property name="publicCertificateType" value="${authorization.certificate.type}"/>
|
||||
<beans:property name="publicCertificateFile" value="${authorization.certificate.file}"/>
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="remoteUserDetailsService" class="timely.auth.RemoteUserDetailsService">
|
||||
<beans:constructor-arg ref="clientSsl"/>
|
||||
<beans:constructor-arg ref="authorizationProperties"/>
|
||||
<beans:bean id="timelyUserDetailsService" class="timely.auth.UserDetailsService">
|
||||
<beans:property name="users">
|
||||
<util:list>
|
||||
<beans:bean class="timely.auth.TimelyUser">
|
||||
<beans:constructor-arg name="subjectDn">
|
||||
<beans:value>CN=example.com</beans:value>
|
||||
</beans:constructor-arg>
|
||||
<beans:constructor-arg name="auths">
|
||||
<util:list>
|
||||
<beans:value>D</beans:value>
|
||||
<beans:value>E</beans:value>
|
||||
<beans:value>F</beans:value>
|
||||
</util:list>
|
||||
</beans:constructor-arg>
|
||||
<beans:constructor-arg name="roles">
|
||||
<util:list>
|
||||
<beans:value>G</beans:value>
|
||||
<beans:value>H</beans:value>
|
||||
<beans:value>I</beans:value>
|
||||
</util:list>
|
||||
</beans:constructor-arg>
|
||||
</beans:bean>
|
||||
</util:list>
|
||||
</beans:property>
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="x509AuthorizationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
|
||||
<beans:property name="preAuthenticatedUserDetailsService" ref="remoteUserDetailsService" />
|
||||
<beans:property name="preAuthenticatedUserDetailsService" ref="timelyUserDetailsService" />
|
||||
</beans:bean>
|
||||
|
||||
<user-service id="usernamePasswordService">
|
||||
|
||||
@@ -24,19 +24,13 @@ timely:
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
serverSsl:
|
||||
key-store-type:
|
||||
key-store-file:
|
||||
key-store-password:
|
||||
server-ssl:
|
||||
certificate-file:
|
||||
key-file:
|
||||
key-password: timely
|
||||
use-generated-keypair: true
|
||||
ignore-ssl-handshake-errors: true
|
||||
trust-store-type:
|
||||
trust-store-file:
|
||||
trust-store-password:
|
||||
jwtSsl:
|
||||
key-store-type:
|
||||
key-store-file:
|
||||
key-store-password:
|
||||
use-openssl: false
|
||||
server:
|
||||
ip: 0.0.0.0
|
||||
tcp-port: 54321
|
||||
|
||||
@@ -28,19 +28,17 @@ timely:
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
serverSsl:
|
||||
key-store-type: ${KEY_STORE_TYPE}
|
||||
key-store-file: ${KEY_STORE_FILE}
|
||||
key-store-password: ${KEY_STORE_PASSWORD}
|
||||
use-generated-keypair: ${GENERATE_KEYS}
|
||||
ignore-ssl-handshake-errors: true
|
||||
trust-store-type: ${TRUST_STORE_TYPE}
|
||||
trust-store-file: ${TRUST_STORE_FILE}
|
||||
trust-store-password: ${TRUST_STORE_PASSWORD}
|
||||
jwtSsl:
|
||||
key-store-type: ${AUTHORIZATION_CERTIFICATE_TYPE}
|
||||
key-store-file: ${AUTHORIZATION_CERTIFICATE_FILE}
|
||||
key-store-password: ${AUTHORIZATION_CERTIFICATE_PASSWORD}
|
||||
server-ssl:
|
||||
certificate-file:
|
||||
key-file:
|
||||
key-password:
|
||||
use-generated-keypair: true
|
||||
trust-store-file:
|
||||
use-openssl: true
|
||||
#use-ciphers:
|
||||
jwtCheckKeyStore:
|
||||
jwtCheckKeyType:
|
||||
jwtCheckKeyPassword:
|
||||
server:
|
||||
ip: ${HOST_IP}
|
||||
tcp-port: ${TCP_PORT}
|
||||
|
||||
+9
-11
@@ -27,19 +27,17 @@ timely:
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
serverSsl:
|
||||
key-store-type:
|
||||
key-store-file:
|
||||
key-store-password:
|
||||
server-ssl:
|
||||
certificate-file:
|
||||
key-file:
|
||||
key-password:
|
||||
use-generated-keypair: true
|
||||
ignore-ssl-handshake-errors: true
|
||||
trust-store-type:
|
||||
trust-store-file:
|
||||
trust-store-password:
|
||||
jwtSsl:
|
||||
key-store-type:
|
||||
key-store-file:
|
||||
key-store-password:
|
||||
use-openssl: true
|
||||
#use-ciphers:
|
||||
jwtCheckKeyStore:
|
||||
jwtCheckKeyType:
|
||||
jwtCheckKeyPassword:
|
||||
server:
|
||||
ip: 0.0.0.0
|
||||
tcp-port: 4242
|
||||
|
||||
+24
-21
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.0.1</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>
|
||||
@@ -68,10 +64,6 @@
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor.netty</groupId>
|
||||
<artifactId>reactor-netty</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.websocket</groupId>
|
||||
<artifactId>jakarta.websocket-api</artifactId>
|
||||
@@ -79,6 +71,12 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.accumulo</groupId>
|
||||
<artifactId>accumulo-core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.accumulo</groupId>
|
||||
@@ -115,6 +113,12 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.hadoop</groupId>
|
||||
<artifactId>hadoop-common</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>jdk.tools</groupId>
|
||||
<artifactId>jdk.tools</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.hadoop</groupId>
|
||||
@@ -124,13 +128,15 @@
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webflux</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -172,6 +178,11 @@
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
@@ -288,14 +299,6 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<extensions>
|
||||
<!-- Use os-maven-plugin to initialize the "os.detected" properties -->
|
||||
|
||||
@@ -4,6 +4,7 @@ import static org.apache.accumulo.core.conf.ConfigurationTypeHelper.getTimeInMil
|
||||
import static timely.store.cache.DataStoreCache.NON_CACHED_METRICS;
|
||||
import static timely.store.cache.DataStoreCache.NON_CACHED_METRICS_LOCK_PATH;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
@@ -11,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;
|
||||
@@ -55,13 +55,12 @@ import io.netty.handler.ssl.OpenSslServerContext;
|
||||
import io.netty.handler.ssl.OpenSslServerSessionContext;
|
||||
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 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;
|
||||
@@ -82,8 +81,6 @@ import org.springframework.context.ConfigurableApplicationContext;
|
||||
import timely.auth.AuthCache;
|
||||
import timely.auth.JWTTokenHandler;
|
||||
import timely.auth.VisibilityCache;
|
||||
import timely.auth.util.SslHelper;
|
||||
import timely.configuration.Accumulo;
|
||||
import timely.configuration.Configuration;
|
||||
import timely.configuration.Cors;
|
||||
import timely.configuration.ServerSsl;
|
||||
@@ -144,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;
|
||||
@@ -307,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);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -419,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) {
|
||||
@@ -502,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());
|
||||
@@ -512,7 +483,7 @@ public class Server {
|
||||
MetaCacheFactory.getCache(config);
|
||||
AuthCache.configure(config.getSecurity());
|
||||
VisibilityCache.init(config);
|
||||
JWTTokenHandler.init(config.getSecurity().getJwtSsl(), accumuloClient);
|
||||
JWTTokenHandler.init(config.getSecurity(), config.getAccumulo());
|
||||
final boolean useEpoll = useEpoll();
|
||||
Class<? extends ServerSocketChannel> channelClass;
|
||||
Class<? extends Channel> datagramChannelClass;
|
||||
@@ -548,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();
|
||||
@@ -572,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();
|
||||
|
||||
@@ -584,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();
|
||||
@@ -615,19 +590,38 @@ 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);
|
||||
ssl = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey());
|
||||
} else {
|
||||
if (null == sslCfg.getKeyStoreFile()) {
|
||||
String cert = sslCfg.getCertificateFile();
|
||||
String key = sslCfg.getKeyFile();
|
||||
String keyPass = sslCfg.getKeyPassword();
|
||||
if (null == cert || null == key) {
|
||||
throw new IllegalArgumentException("Check your SSL properties, something is wrong.");
|
||||
}
|
||||
ssl = SslHelper.getSslContextBuilder(sslCfg);
|
||||
ssl = SslContextBuilder.forServer(new File(cert), new File(key), keyPass);
|
||||
}
|
||||
|
||||
ssl.ciphers(sslCfg.getUseCiphers());
|
||||
|
||||
// Can't set to REQUIRE because the CORS pre-flight requests will fail.
|
||||
ssl.clientAuth(ClientAuth.OPTIONAL);
|
||||
|
||||
Boolean useOpenSSL = sslCfg.isUseOpenssl();
|
||||
if (useOpenSSL) {
|
||||
ssl.sslProvider(SslProvider.OPENSSL);
|
||||
} else {
|
||||
ssl.sslProvider(SslProvider.JDK);
|
||||
}
|
||||
String trustStore = sslCfg.getTrustStoreFile();
|
||||
if (null != trustStore) {
|
||||
if (!trustStore.isEmpty()) {
|
||||
ssl.trustManager(new File(trustStore));
|
||||
}
|
||||
}
|
||||
return ssl.build();
|
||||
}
|
||||
|
||||
@@ -666,7 +660,7 @@ public class Server {
|
||||
ch.pipeline().addLast("queryDecoder",
|
||||
new timely.netty.http.HttpRequestDecoder(config.getSecurity(), config.getHttp()));
|
||||
ch.pipeline().addLast("fileServer", new HttpStaticFileServerHandler()
|
||||
.setIgnoreSslHandshakeErrors(config.getSecurity().getServerSsl().isIgnoreSslHandshakeErrors()));
|
||||
.setIgnoreSslHandshakeErrors(config.getSecurity().getServerSsl().isUseGeneratedKeypair()));
|
||||
ch.pipeline().addLast("strict", new StrictTransportHandler(config));
|
||||
ch.pipeline().addLast("login", new X509LoginRequestHandler(config.getSecurity(), config.getHttp()));
|
||||
ch.pipeline().addLast("doLogin",
|
||||
@@ -680,7 +674,7 @@ public class Server {
|
||||
ch.pipeline().addLast("cache", new HttpCacheRequestHandler(dataStoreCache));
|
||||
ch.pipeline().addLast("put", new HttpMetricPutHandler(dataStore));
|
||||
ch.pipeline().addLast("error", new TimelyExceptionHandler()
|
||||
.setIgnoreSslHandshakeErrors(config.getSecurity().getServerSsl().isIgnoreSslHandshakeErrors()));
|
||||
.setIgnoreSslHandshakeErrors(config.getSecurity().getServerSsl().isUseGeneratedKeypair()));
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -27,8 +27,8 @@ import timely.netty.http.auth.TimelyUserDetails;
|
||||
public class AuthenticationService {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AuthenticationService.class);
|
||||
private static ApplicationContext springContext;
|
||||
private static AuthenticationManager authManager;
|
||||
private static ApplicationContext springContext = null;
|
||||
private static AuthenticationManager authManager = null;
|
||||
private static ConcurrentHashMap<String, Object> fetchingEntity = new ConcurrentHashMap<>();
|
||||
private static ConcurrentHashMap<String, Object> fetchingPrincipal = new ConcurrentHashMap<>();
|
||||
private static Collection<String> requiredRoles;
|
||||
@@ -161,8 +161,9 @@ public class AuthenticationService {
|
||||
}
|
||||
verifiedPrincipal = new TimelyPrincipal(authenticatedTimelyUsers);
|
||||
AuthCache.put(verifiedPrincipal.getName(), verifiedPrincipal);
|
||||
LOG.debug("Authenticated user {} with authorizations {}",
|
||||
verifiedPrincipal.getName(), verifiedPrincipal.getAuthorizationsString());
|
||||
LOG.debug("Authenticated user {} for request {} with authorizations {}",
|
||||
verifiedPrincipal.getName(), request.toString(),
|
||||
verifiedPrincipal.getAuthorizationsString());
|
||||
} else {
|
||||
LOG.trace("Verified principal {} in AuthCache on 2nd attempt", entity);
|
||||
}
|
||||
|
||||
@@ -7,24 +7,21 @@ import java.security.KeyStore;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.guava.GuavaModule;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jws;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
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.JwtSsl;
|
||||
import timely.configuration.Accumulo;
|
||||
import timely.configuration.Security;
|
||||
|
||||
/**
|
||||
* Converts between a String encoded JSON Web Token and a collection of
|
||||
@@ -37,23 +34,23 @@ public class JWTTokenHandler {
|
||||
private static ObjectMapper objectMapper;
|
||||
private static Collection<String> accumuloAuths = new TreeSet<>();
|
||||
|
||||
public static void init(JwtSsl ssl, AccumuloClient accumuloClient) {
|
||||
if (StringUtils.isNotBlank(ssl.getKeyStoreFile())) {
|
||||
public static void init(Security security, Accumulo accumuloConfiguration) {
|
||||
if (StringUtils.isNotBlank(security.getJwtCheckKeyStore())) {
|
||||
try {
|
||||
String type = ssl.getKeyStoreType();
|
||||
String type = security.getJwtCheckKeyType();
|
||||
if (type != null && type.equals("X.509")) {
|
||||
CertificateFactory factory = CertificateFactory.getInstance("X.509");
|
||||
InputStream is = ResourceUtils.getURL(ssl.getKeyStoreFile()).openStream();
|
||||
InputStream is = ResourceUtils.getURL(security.getJwtCheckKeyStore()).openStream();
|
||||
X509Certificate certificate = (X509Certificate) factory.generateCertificate(is);
|
||||
JWTTokenHandler.signatureCheckKey = certificate.getPublicKey();
|
||||
} else {
|
||||
KeyStore keyStore = KeyStore.getInstance(type == null ? "JKS" : type);
|
||||
char[] keyPassword = ssl.getKeyStorePassword() == null ? null
|
||||
: ssl.getKeyStorePassword().toCharArray();
|
||||
keyStore.load(ResourceUtils.getURL(ssl.getKeyStoreFile()).openStream(), keyPassword);
|
||||
char[] keyPassword = security.getJwtCheckKeyPassword() == null ? null
|
||||
: security.getJwtCheckKeyPassword().toCharArray();
|
||||
keyStore.load(ResourceUtils.getURL(security.getJwtCheckKeyStore()).openStream(), keyPassword);
|
||||
String alias = keyStore.aliases().nextElement();
|
||||
Certificate certificate = keyStore.getCertificate(alias);
|
||||
JWTTokenHandler.signatureCheckKey = certificate.getPublicKey();
|
||||
Certificate cert = keyStore.getCertificate(alias);
|
||||
JWTTokenHandler.signatureCheckKey = cert.getPublicKey();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Invalid SSL configuration.", e);
|
||||
@@ -61,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);
|
||||
}
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
package timely.auth;
|
||||
|
||||
import static timely.auth.AuthenticationService.PRINCIPALS_CLAIM;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.client.reactive.ClientHttpConnector;
|
||||
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import reactor.netty.http.client.HttpClient;
|
||||
import timely.auth.util.SslHelper;
|
||||
import timely.configuration.AuthorizationProperties;
|
||||
import timely.configuration.ClientSsl;
|
||||
import timely.netty.http.auth.TimelyAuthenticationToken;
|
||||
import timely.netty.http.auth.TimelyUserDetails;
|
||||
|
||||
public class RemoteUserDetailsService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
|
||||
|
||||
static private final Logger log = LoggerFactory.getLogger(RemoteUserDetailsService.class);
|
||||
private WebClient webClient;
|
||||
private ClientSsl clientSsl;
|
||||
private AuthorizationProperties authorizationProperties;
|
||||
|
||||
public RemoteUserDetailsService() {
|
||||
|
||||
}
|
||||
|
||||
public RemoteUserDetailsService(ClientSsl clientSsl, AuthorizationProperties authorizationProperties)
|
||||
throws Exception {
|
||||
this.clientSsl = clientSsl;
|
||||
this.authorizationProperties = authorizationProperties;
|
||||
initialize();
|
||||
}
|
||||
|
||||
public void initialize() throws Exception {
|
||||
WebClient.Builder webClientBuilder = WebClient.builder();
|
||||
SslContext sslContext = SslHelper.getSslContext(clientSsl);
|
||||
HttpClient httpClient = HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
|
||||
ClientHttpConnector httpConnector = new ReactorClientHttpConnector(httpClient);
|
||||
this.webClient = webClientBuilder.clientConnector(httpConnector)
|
||||
.baseUrl(authorizationProperties.getAuthorizationUrl()).build();
|
||||
}
|
||||
|
||||
public void setClientSsl(ClientSsl clientSsl) {
|
||||
this.clientSsl = clientSsl;
|
||||
}
|
||||
|
||||
public void setAuthorizationProperties(AuthorizationProperties authorizationProperties) {
|
||||
this.authorizationProperties = authorizationProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) throws UsernameNotFoundException {
|
||||
TimelyUserDetails userDetails = null;
|
||||
if (!(token instanceof TimelyAuthenticationToken)) {
|
||||
log.error("Unexpected type for token: {}", token.getClass().getName());
|
||||
}
|
||||
TimelyAuthenticationToken timelyToken = (TimelyAuthenticationToken) token;
|
||||
TimelyPrincipal principal = timelyToken.getTimelyPrincipal();
|
||||
String subjectDN = principal.getPrimaryUser().getDn().subjectDN();
|
||||
String issuerDN = principal.getPrimaryUser().getDn().issuerDN();
|
||||
try {
|
||||
log.trace("Authenticating {} via the authorization microservice", subjectDN);
|
||||
// @formatter:off
|
||||
String jwt = webClient.get()
|
||||
.header(TimelyAuthenticationToken.PROXIED_ENTITIES_HEADER, subjectDN)
|
||||
.header(TimelyAuthenticationToken.PROXIED_ISSUERS_HEADER, issuerDN)
|
||||
.retrieve()
|
||||
.bodyToMono(String.class)
|
||||
.block();
|
||||
// @formatter:on
|
||||
log.trace("Authenticated {} via the authorization microservice with {} result", subjectDN,
|
||||
jwt == null ? "null" : "non-null");
|
||||
if (jwt != null) {
|
||||
Collection<TimelyUser> timelyUsers = JWTTokenHandler.createUsersFromToken(jwt, PRINCIPALS_CLAIM);
|
||||
if (timelyUsers.iterator().hasNext()) {
|
||||
userDetails = getTimelyUserDetails(timelyUsers.iterator().next());
|
||||
}
|
||||
}
|
||||
if (userDetails == null) {
|
||||
throw new UsernameNotFoundException("No entities found for " + subjectDN);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed performing lookup of {}: {}", subjectDN, e);
|
||||
throw new UsernameNotFoundException(e.getMessage(), e);
|
||||
}
|
||||
return userDetails;
|
||||
}
|
||||
|
||||
private TimelyUserDetails getTimelyUserDetails(TimelyUser timelyUser) {
|
||||
return new TimelyUserDetails() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Collection<SimpleGrantedAuthority> getAuthorities() {
|
||||
final Collection<SimpleGrantedAuthority> auths = new ArrayList<>();
|
||||
timelyUser.getAuths().forEach(a -> {
|
||||
auths.add(new SimpleGrantedAuthority(a));
|
||||
});
|
||||
return auths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getRoles() {
|
||||
final Collection<String> roles = new ArrayList<>();
|
||||
roles.addAll(timelyUser.getRoles());
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPassword() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return timelyUser.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -7,13 +7,13 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
|
||||
import timely.netty.http.auth.TimelyUserDetails;
|
||||
|
||||
public class FileUserDetailsService implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
|
||||
public class UserDetailsService implements
|
||||
org.springframework.security.core.userdetails.AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
|
||||
|
||||
private HashMap<String, TimelyUser> users;
|
||||
|
||||
@@ -1,504 +0,0 @@
|
||||
package timely.auth.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Principal;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Provider;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.KeyManagerFactorySpi;
|
||||
import javax.net.ssl.ManagerFactoryParameters;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.TrustManagerFactorySpi;
|
||||
import javax.net.ssl.X509ExtendedKeyManager;
|
||||
import javax.net.ssl.X509ExtendedTrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.netty.handler.ssl.SslProvider;
|
||||
import io.netty.util.concurrent.FastThreadLocal;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import timely.configuration.ServerSsl;
|
||||
import timely.configuration.Ssl;
|
||||
|
||||
public class SslHelper {
|
||||
|
||||
public static SslContext getSslContext(Ssl ssl) throws Exception {
|
||||
return getSslContextBuilder(ssl).build();
|
||||
}
|
||||
|
||||
public static SslContextBuilder getSslContextBuilder(Ssl ssl) throws Exception {
|
||||
KeyManagerFactory keyManagerFactory = getKeyManagerFactory(ssl);
|
||||
SslContextBuilder builder = ssl instanceof ServerSsl ? SslContextBuilder.forServer(keyManagerFactory)
|
||||
: SslContextBuilder.forClient().keyManager(keyManagerFactory);
|
||||
boolean useOpenSSL = ssl.isUseOpenssl();
|
||||
if (useOpenSSL) {
|
||||
builder.sslProvider(SslProvider.OPENSSL);
|
||||
} else {
|
||||
builder.sslProvider(SslProvider.JDK);
|
||||
}
|
||||
if (ssl.getTrustStoreFile() != null) {
|
||||
builder.trustManager(getTrustManagerFactory(ssl));
|
||||
}
|
||||
if (ssl.getCiphers() != null)
|
||||
builder.ciphers(Arrays.asList(ssl.getCiphers()));
|
||||
if (ssl.getEnabledProtocols() != null)
|
||||
builder.protocols(ssl.getEnabledProtocols());
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static KeyManager[] getKeyManagers(Ssl ssl) {
|
||||
return getKeyManagerFactory(ssl).getKeyManagers();
|
||||
}
|
||||
|
||||
public static KeyManagerFactory getKeyManagerFactory(Ssl ssl) {
|
||||
try {
|
||||
KeyStore keyStore = getKeyStore(ssl);
|
||||
|
||||
// Get key manager to provide client credentials.
|
||||
KeyManagerFactory keyManagerFactory = KeyManagerFactory
|
||||
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
char[] keyStorePassword = ssl.getKeyStorePassword() == null ? null
|
||||
: ssl.getKeyStorePassword().toCharArray();
|
||||
keyManagerFactory.init(keyStore, keyStorePassword);
|
||||
if (ssl.getKeyAlias() != null)
|
||||
return new KeyAliasKeyManagerFactory(keyManagerFactory, ssl.getKeyAlias());
|
||||
else
|
||||
return keyManagerFactory;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static KeyStore getKeyStore(Ssl ssl)
|
||||
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
|
||||
String keyStoreType = ssl.getKeyStoreType();
|
||||
if (keyStoreType == null) {
|
||||
keyStoreType = "PKCS12";
|
||||
}
|
||||
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
|
||||
URL url = ResourceUtils.getURL(ssl.getKeyStoreFile());
|
||||
char[] keyStorePassword = ssl.getKeyStorePassword() == null ? null : ssl.getKeyStorePassword().toCharArray();
|
||||
keyStore.load(url.openStream(), keyStorePassword);
|
||||
return keyStore;
|
||||
}
|
||||
|
||||
public static TrustManager[] getTrustManagers(Ssl ssl) {
|
||||
TrustManagerFactory tmf = getTrustManagerFactory(ssl);
|
||||
return tmf.getTrustManagers();
|
||||
}
|
||||
|
||||
public static TrustManagerFactory getTrustManagerFactory(Ssl ssl) {
|
||||
try {
|
||||
KeyStore trustStore = getTrustStore(ssl);
|
||||
KeyStore keyStore = getKeyStore(ssl);
|
||||
|
||||
X509Certificate trustedCertificate = getTrustedCertificate(ssl.getKeyAlias(), keyStore);
|
||||
|
||||
TrustManagerFactory trustManagerFactory = new TimelyTrustMangerFactory(
|
||||
TrustManagerFactory.getDefaultAlgorithm(), trustedCertificate);
|
||||
trustManagerFactory.init(trustStore);
|
||||
return trustManagerFactory;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static KeyStore getTrustStore(Ssl ssl)
|
||||
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
|
||||
String trustStoreType = ssl.getTrustStoreType();
|
||||
if (trustStoreType == null) {
|
||||
trustStoreType = "JKS";
|
||||
}
|
||||
String trustStoreURL = ssl.getTrustStoreFile();
|
||||
if (trustStoreURL == null) {
|
||||
return null;
|
||||
}
|
||||
KeyStore trustStore = KeyStore.getInstance(trustStoreType);
|
||||
URL url = ResourceUtils.getURL(trustStoreURL);
|
||||
char[] trustStorePassword = ssl.getTrustStorePassword() == null ? null
|
||||
: ssl.getTrustStorePassword().toCharArray();
|
||||
trustStore.load(url.openStream(), trustStorePassword);
|
||||
return trustStore;
|
||||
}
|
||||
|
||||
public static X509Certificate getTrustedCertificate(String alias, KeyStore keyStore) throws KeyStoreException {
|
||||
Certificate trustCandidate = null;
|
||||
X509Certificate trustedCertificate = null;
|
||||
if (alias != null) {
|
||||
trustCandidate = keyStore.getCertificate(alias);
|
||||
} else {
|
||||
Enumeration<String> aliases = keyStore.aliases();
|
||||
if (aliases.hasMoreElements()) {
|
||||
trustCandidate = keyStore.getCertificate(aliases.nextElement());
|
||||
}
|
||||
}
|
||||
if (trustCandidate instanceof X509Certificate) {
|
||||
trustedCertificate = (X509Certificate) trustCandidate;
|
||||
}
|
||||
return trustedCertificate;
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom {@link TrustManagerFactory} that wraps any returned
|
||||
* {@link TrustManager}s in order to apply custom behavior for trusting a remote
|
||||
* server.
|
||||
*/
|
||||
private static class TimelyTrustMangerFactory extends TrustManagerFactory {
|
||||
|
||||
private static final Provider PROVIDER = new Provider("", 0.0, "") {
|
||||
|
||||
private static final long serialVersionUID = -2680540247105807895L;
|
||||
};
|
||||
private static final FastThreadLocal<TimelyTrustManagerSpi> CURRENT_SPI = new FastThreadLocal<>() {
|
||||
|
||||
@Override
|
||||
protected TimelyTrustManagerSpi initialValue() {
|
||||
return new TimelyTrustManagerSpi();
|
||||
}
|
||||
};
|
||||
|
||||
public TimelyTrustMangerFactory(String algorithm, X509Certificate trustedCertificate)
|
||||
throws NoSuchAlgorithmException {
|
||||
super(CURRENT_SPI.get(), PROVIDER, algorithm);
|
||||
CURRENT_SPI.get().init(TrustManagerFactory.getInstance(algorithm), trustedCertificate);
|
||||
CURRENT_SPI.remove();
|
||||
|
||||
Preconditions.checkNotNull(algorithm);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link TrustManagerFactorySpi} that is used by
|
||||
* {@link TimelyTrustMangerFactory} in order to wrap any returned
|
||||
* {@link TrustManager}s with a {@link TimelyTrustManager}.
|
||||
*/
|
||||
private static class TimelyTrustManagerSpi extends TrustManagerFactorySpi {
|
||||
|
||||
private TrustManagerFactory delegate;
|
||||
private X509Certificate trustedCertificate;
|
||||
private volatile TrustManager[] trustManagers;
|
||||
|
||||
public void init(TrustManagerFactory delegate, X509Certificate trustedCertificate) {
|
||||
this.delegate = delegate;
|
||||
this.trustedCertificate = trustedCertificate;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineInit(KeyStore keyStore) throws KeyStoreException {
|
||||
delegate.init(keyStore);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineInit(ManagerFactoryParameters managerFactoryParameters)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
delegate.init(managerFactoryParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TrustManager[] engineGetTrustManagers() {
|
||||
TrustManager[] trustManagers = this.trustManagers;
|
||||
if (trustManagers == null) {
|
||||
trustManagers = delegate.getTrustManagers();
|
||||
for (int i = 0; i < trustManagers.length; i++) {
|
||||
final TrustManager tm = trustManagers[i];
|
||||
if (tm instanceof X509TrustManager) {
|
||||
trustManagers[i] = new TimelyTrustManager((X509TrustManager) tm, trustedCertificate);
|
||||
} else {
|
||||
trustManagers[i] = tm;
|
||||
}
|
||||
}
|
||||
this.trustManagers = trustManagers;
|
||||
}
|
||||
return trustManagers.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension of {@link X509ExtendedTrustManager} that applies custom trust
|
||||
* behavior for use with microservices. It is expected that these services will
|
||||
* run on a cluster where DNS might be used for service discovery. However, the
|
||||
* server certificate used by the microservices will not have the DNS names as
|
||||
* Subject Alternative Name values, so normal trust for the certificate would
|
||||
* fail. This trust manager trusts the remote server regardless of the host name
|
||||
* used to access it, so long as the presented certificate is the one we expect.
|
||||
* Otherwise, it falls back to the normal trust behavior.
|
||||
*/
|
||||
private static class TimelyTrustManager extends X509ExtendedTrustManager {
|
||||
|
||||
private X509Certificate trustedCertificate;
|
||||
private X509TrustManager delegate;
|
||||
private X509ExtendedTrustManager extendedDelegate;
|
||||
|
||||
public TimelyTrustManager(X509TrustManager delegate, X509Certificate trustedCertificate) {
|
||||
this.trustedCertificate = trustedCertificate;
|
||||
this.delegate = delegate;
|
||||
if (delegate instanceof X509ExtendedTrustManager) {
|
||||
extendedDelegate = (X509ExtendedTrustManager) delegate;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return delegate.getAcceptedIssuers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
|
||||
delegate.checkClientTrusted(x509Certificates, s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
|
||||
delegate.checkServerTrusted(x509Certificates, s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] x509Certificates, String s, Socket socket)
|
||||
throws CertificateException {
|
||||
Preconditions.checkNotNull(extendedDelegate, "Not wrapping an X509ExtendedTrustManager");
|
||||
boolean certChainTrusted = certChainTrusted(x509Certificates);
|
||||
if ((socket instanceof SSLSocket) && socket.isConnected() && certChainTrusted) {
|
||||
SSLSocket sslSocket = (SSLSocket) socket;
|
||||
SSLParameters origParameters = sslSocket.getSSLParameters();
|
||||
String curIdentityAlgorithm = origParameters.getEndpointIdentificationAlgorithm();
|
||||
try {
|
||||
// Setting the identification algorithm to empty will prevent the hostname
|
||||
// verification.
|
||||
SSLParameters overrideParameters = sslSocket.getSSLParameters();
|
||||
overrideParameters.setEndpointIdentificationAlgorithm("");
|
||||
sslSocket.setSSLParameters(overrideParameters);
|
||||
|
||||
extendedDelegate.checkClientTrusted(x509Certificates, s, socket);
|
||||
} finally {
|
||||
origParameters.setEndpointIdentificationAlgorithm(curIdentityAlgorithm);
|
||||
sslSocket.setSSLParameters(origParameters);
|
||||
}
|
||||
} else {
|
||||
extendedDelegate.checkClientTrusted(x509Certificates, s, socket);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] x509Certificates, String s, Socket socket)
|
||||
throws CertificateException {
|
||||
Preconditions.checkNotNull(extendedDelegate, "Not wrapping an X509ExtendedTrustManager");
|
||||
boolean certChainTrusted = certChainTrusted(x509Certificates);
|
||||
if ((socket instanceof SSLSocket) && socket.isConnected() && certChainTrusted) {
|
||||
SSLSocket sslSocket = (SSLSocket) socket;
|
||||
SSLParameters origParameters = sslSocket.getSSLParameters();
|
||||
String curIdentityAlgorithm = origParameters.getEndpointIdentificationAlgorithm();
|
||||
try {
|
||||
// Setting the identification algorithm to empty will prevent the hostname
|
||||
// verification.
|
||||
SSLParameters overrideParameters = sslSocket.getSSLParameters();
|
||||
overrideParameters.setEndpointIdentificationAlgorithm("");
|
||||
sslSocket.setSSLParameters(overrideParameters);
|
||||
extendedDelegate.checkServerTrusted(x509Certificates, s, socket);
|
||||
} finally {
|
||||
origParameters.setEndpointIdentificationAlgorithm(curIdentityAlgorithm);
|
||||
sslSocket.setSSLParameters(origParameters);
|
||||
}
|
||||
} else {
|
||||
extendedDelegate.checkServerTrusted(x509Certificates, s, socket);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine)
|
||||
throws CertificateException {
|
||||
Preconditions.checkNotNull(extendedDelegate, "Not wrapping an X509ExtendedTrustManager");
|
||||
boolean certChainTrusted = certChainTrusted(x509Certificates);
|
||||
SSLParameters origParameters = sslEngine.getSSLParameters();
|
||||
String curIdentityAlgorithm = origParameters.getEndpointIdentificationAlgorithm();
|
||||
try {
|
||||
// Setting the identification algorithm to empty will prevent the hostname
|
||||
// verification.
|
||||
if (certChainTrusted) {
|
||||
SSLParameters overrideParameters = sslEngine.getSSLParameters();
|
||||
overrideParameters.setEndpointIdentificationAlgorithm("");
|
||||
sslEngine.setSSLParameters(overrideParameters);
|
||||
}
|
||||
|
||||
extendedDelegate.checkClientTrusted(x509Certificates, s, sslEngine);
|
||||
} finally {
|
||||
origParameters.setEndpointIdentificationAlgorithm(curIdentityAlgorithm);
|
||||
sslEngine.setSSLParameters(origParameters);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine)
|
||||
throws CertificateException {
|
||||
Preconditions.checkNotNull(extendedDelegate, "Not wrapping an X509ExtendedTrustManager");
|
||||
boolean certChainTrusted = certChainTrusted(x509Certificates);
|
||||
SSLParameters origParameters = sslEngine.getSSLParameters();
|
||||
String curIdentityAlgorithm = origParameters.getEndpointIdentificationAlgorithm();
|
||||
try {
|
||||
// Setting the identification algorithm to empty will prevent the hostname
|
||||
// verification.
|
||||
if (certChainTrusted) {
|
||||
SSLParameters overrideParameters = sslEngine.getSSLParameters();
|
||||
overrideParameters.setEndpointIdentificationAlgorithm("");
|
||||
sslEngine.setSSLParameters(overrideParameters);
|
||||
}
|
||||
extendedDelegate.checkServerTrusted(x509Certificates, s, sslEngine);
|
||||
} finally {
|
||||
origParameters.setEndpointIdentificationAlgorithm(curIdentityAlgorithm);
|
||||
sslEngine.setSSLParameters(origParameters);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean certChainTrusted(X509Certificate[] x509Certificates) {
|
||||
// If there was no peer certificate available or none matched the trusted
|
||||
// certificate, then return
|
||||
// immediately so that we use the default trust verification instead of our
|
||||
// custom verification.
|
||||
boolean peerCertIsTrusted = false;
|
||||
if (x509Certificates != null && trustedCertificate != null) {
|
||||
for (X509Certificate cert : x509Certificates) {
|
||||
if (cert.getSubjectDN().equals(trustedCertificate.getSubjectDN())
|
||||
&& cert.getIssuerDN().equals(trustedCertificate.getIssuerDN())) {
|
||||
peerCertIsTrusted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return peerCertIsTrusted;
|
||||
}
|
||||
}
|
||||
|
||||
private static class KeyAliasKeyManagerFactory extends KeyManagerFactory {
|
||||
|
||||
private static final Provider PROVIDER = new Provider("", 0.0, "") {
|
||||
|
||||
private static final long serialVersionUID = -2680540247105807895L;
|
||||
};
|
||||
private static final FastThreadLocal<KeyAliasKeyManagerSpi> CURRENT_SPI = new FastThreadLocal<KeyAliasKeyManagerSpi>() {
|
||||
|
||||
@Override
|
||||
protected KeyAliasKeyManagerSpi initialValue() {
|
||||
return new KeyAliasKeyManagerSpi();
|
||||
}
|
||||
};
|
||||
|
||||
public KeyAliasKeyManagerFactory(KeyManagerFactory delegate, String alias) {
|
||||
|
||||
super(CURRENT_SPI.get(), PROVIDER, delegate.getAlgorithm());
|
||||
CURRENT_SPI.get().init(delegate, alias);
|
||||
CURRENT_SPI.remove();
|
||||
}
|
||||
}
|
||||
|
||||
private static class KeyAliasKeyManagerSpi extends KeyManagerFactorySpi {
|
||||
|
||||
private KeyManagerFactory delegate;
|
||||
private String alias;
|
||||
private volatile KeyManager[] keyManagers;
|
||||
|
||||
public void init(KeyManagerFactory delegate, String alias) {
|
||||
this.delegate = delegate;
|
||||
this.alias = alias;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineInit(KeyStore keyStore, char[] chars)
|
||||
throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException {
|
||||
delegate.init(keyStore, chars);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void engineInit(ManagerFactoryParameters managerFactoryParameters)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
delegate.init(managerFactoryParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected KeyManager[] engineGetKeyManagers() {
|
||||
KeyManager[] keyManagers = this.keyManagers;
|
||||
if (keyManagers == null) {
|
||||
keyManagers = delegate.getKeyManagers();
|
||||
for (int i = 0; i < keyManagers.length; i++) {
|
||||
final KeyManager km = keyManagers[i];
|
||||
if (km instanceof X509ExtendedKeyManager) {
|
||||
keyManagers[i] = new KeyAliasKeyManager((X509ExtendedKeyManager) km, alias);
|
||||
} else {
|
||||
keyManagers[i] = km;
|
||||
}
|
||||
}
|
||||
this.keyManagers = keyManagers;
|
||||
}
|
||||
return keyManagers.clone();
|
||||
}
|
||||
}
|
||||
|
||||
private static class KeyAliasKeyManager extends X509ExtendedKeyManager {
|
||||
|
||||
private final X509ExtendedKeyManager delegate;
|
||||
private final String alias;
|
||||
|
||||
public KeyAliasKeyManager(X509ExtendedKeyManager delegate, String alias) {
|
||||
this.delegate = delegate;
|
||||
this.alias = alias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chooseEngineClientAlias(String[] strings, Principal[] principals, SSLEngine sslEngine) {
|
||||
return delegate.chooseEngineClientAlias(strings, principals, sslEngine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chooseEngineServerAlias(String s, Principal[] principals, SSLEngine sslEngine) {
|
||||
return (alias != null) ? alias : delegate.chooseEngineServerAlias(s, principals, sslEngine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getClientAliases(String s, Principal[] principals) {
|
||||
return delegate.getClientAliases(s, principals);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) {
|
||||
return delegate.chooseClientAlias(strings, principals, socket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getServerAliases(String s, Principal[] principals) {
|
||||
return delegate.getServerAliases(s, principals);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chooseServerAlias(String s, Principal[] principals, Socket socket) {
|
||||
return delegate.chooseServerAlias(s, principals, socket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getCertificateChain(String s) {
|
||||
return delegate.getCertificateChain(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateKey getPrivateKey(String s) {
|
||||
return delegate.getPrivateKey(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package timely.configuration;
|
||||
|
||||
public class AuthorizationProperties {
|
||||
|
||||
private boolean enabled = false;
|
||||
private String authorizationUrl;
|
||||
private String publicCertificateFile;
|
||||
private String publicCertificateType;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getAuthorizationUrl() {
|
||||
return authorizationUrl;
|
||||
}
|
||||
|
||||
public void setAuthorizationUrl(String authorizationUrl) {
|
||||
this.authorizationUrl = authorizationUrl;
|
||||
}
|
||||
|
||||
public String getPublicCertificateFile() {
|
||||
return publicCertificateFile;
|
||||
}
|
||||
|
||||
public void setPublicCertificateFile(String publicCertificateFile) {
|
||||
this.publicCertificateFile = publicCertificateFile;
|
||||
}
|
||||
|
||||
public String getPublicCertificateType() {
|
||||
return publicCertificateType;
|
||||
}
|
||||
|
||||
public void setPublicCertificateType(String publicCertificateType) {
|
||||
this.publicCertificateType = publicCertificateType;
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package timely.configuration;
|
||||
|
||||
public class ClientSsl implements Ssl {
|
||||
|
||||
private String[] ciphers;
|
||||
private String[] enabledProtocols;
|
||||
private String keyStoreFile;
|
||||
private String keyStoreType;
|
||||
private String keyStorePassword;
|
||||
private String keyAlias;
|
||||
private String trustStoreFile;
|
||||
private String trustStoreType;
|
||||
private String trustStorePassword;
|
||||
private boolean useClientCert = true;
|
||||
private boolean hostVerificationEnabled = true;
|
||||
private boolean useOpenssl = true;
|
||||
|
||||
public String[] getCiphers() {
|
||||
return ciphers;
|
||||
}
|
||||
|
||||
public void setCiphers(String[] ciphers) {
|
||||
this.ciphers = ciphers;
|
||||
}
|
||||
|
||||
public String[] getEnabledProtocols() {
|
||||
return enabledProtocols;
|
||||
}
|
||||
|
||||
public void setEnabledProtocols(String[] enabledProtocols) {
|
||||
this.enabledProtocols = enabledProtocols;
|
||||
}
|
||||
|
||||
public String getKeyStoreFile() {
|
||||
return keyStoreFile;
|
||||
}
|
||||
|
||||
public void setKeyStoreFile(String keyStoreFile) {
|
||||
this.keyStoreFile = keyStoreFile;
|
||||
}
|
||||
|
||||
public String getKeyStoreType() {
|
||||
return keyStoreType;
|
||||
}
|
||||
|
||||
public void setKeyStoreType(String keyStoreType) {
|
||||
this.keyStoreType = keyStoreType;
|
||||
}
|
||||
|
||||
public String getKeyStorePassword() {
|
||||
return keyStorePassword;
|
||||
}
|
||||
|
||||
public void setKeyStorePassword(String keyStorePassword) {
|
||||
this.keyStorePassword = keyStorePassword;
|
||||
}
|
||||
|
||||
public String getKeyAlias() {
|
||||
return keyAlias;
|
||||
}
|
||||
|
||||
public void setKeyAlias(String keyAlias) {
|
||||
this.keyAlias = keyAlias;
|
||||
}
|
||||
|
||||
public String getTrustStoreFile() {
|
||||
return trustStoreFile;
|
||||
}
|
||||
|
||||
public void setTrustStoreFile(String trustStoreFile) {
|
||||
this.trustStoreFile = trustStoreFile;
|
||||
}
|
||||
|
||||
public String getTrustStoreType() {
|
||||
return trustStoreType;
|
||||
}
|
||||
|
||||
public void setTrustStoreType(String trustStoreType) {
|
||||
this.trustStoreType = trustStoreType;
|
||||
}
|
||||
|
||||
public String getTrustStorePassword() {
|
||||
return trustStorePassword;
|
||||
}
|
||||
|
||||
public void setTrustStorePassword(String trustStorePassword) {
|
||||
this.trustStorePassword = trustStorePassword;
|
||||
}
|
||||
|
||||
public void setUseClientCert(boolean useClientCert) {
|
||||
this.useClientCert = useClientCert;
|
||||
}
|
||||
|
||||
public boolean isUseClientCert() {
|
||||
return useClientCert;
|
||||
}
|
||||
|
||||
public void setHostVerificationEnabled(boolean hostVerificationEnabled) {
|
||||
this.hostVerificationEnabled = hostVerificationEnabled;
|
||||
}
|
||||
|
||||
public boolean isHostVerificationEnabled() {
|
||||
return hostVerificationEnabled;
|
||||
}
|
||||
|
||||
public boolean isUseOpenssl() {
|
||||
return useOpenssl;
|
||||
}
|
||||
|
||||
public void setUseOpenssl(boolean useOpenssl) {
|
||||
this.useOpenssl = useOpenssl;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package timely.configuration;
|
||||
|
||||
public class JwtSsl {
|
||||
|
||||
private String keyStoreType;
|
||||
private String keyStoreFile;
|
||||
private String keyStorePassword;
|
||||
|
||||
public String getKeyStoreType() {
|
||||
return keyStoreType;
|
||||
}
|
||||
|
||||
public void setKeyStoreType(String keyStoreType) {
|
||||
this.keyStoreType = keyStoreType;
|
||||
}
|
||||
|
||||
public String getKeyStoreFile() {
|
||||
return keyStoreFile;
|
||||
}
|
||||
|
||||
public void setKeyStoreFile(String keyStoreFile) {
|
||||
this.keyStoreFile = keyStoreFile;
|
||||
}
|
||||
|
||||
public String getKeyStorePassword() {
|
||||
return keyStorePassword;
|
||||
}
|
||||
|
||||
public void setKeyStorePassword(String keyStorePassword) {
|
||||
this.keyStorePassword = keyStorePassword;
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,10 @@ public class Security {
|
||||
private int sessionMaxAge = 86400;
|
||||
private int cacheExpirationMinutes = 60;
|
||||
private int cacheRefreshMinutes = 5;
|
||||
@NestedConfigurationProperty
|
||||
private JwtSsl jwtSsl = new JwtSsl();
|
||||
private String jwtCheckKeyStore;
|
||||
private String jwtCheckKeyType;
|
||||
private String jwtCheckKeyPassword;
|
||||
|
||||
@Valid
|
||||
@NestedConfigurationProperty
|
||||
private ServerSsl serverSsl = new ServerSsl();
|
||||
@@ -61,7 +63,27 @@ public class Security {
|
||||
return serverSsl;
|
||||
}
|
||||
|
||||
public JwtSsl getJwtSsl() {
|
||||
return jwtSsl;
|
||||
public String getJwtCheckKeyStore() {
|
||||
return jwtCheckKeyStore;
|
||||
}
|
||||
|
||||
public void setJwtCheckKeyStore(String jwtCheckKeyStore) {
|
||||
this.jwtCheckKeyStore = jwtCheckKeyStore;
|
||||
}
|
||||
|
||||
public String getJwtCheckKeyType() {
|
||||
return jwtCheckKeyType;
|
||||
}
|
||||
|
||||
public void setJwtCheckKeyType(String jwtCheckKeyType) {
|
||||
this.jwtCheckKeyType = jwtCheckKeyType;
|
||||
}
|
||||
|
||||
public String getJwtCheckKeyPassword() {
|
||||
return jwtCheckKeyPassword;
|
||||
}
|
||||
|
||||
public void setJwtCheckKeyPassword(String jwtCheckKeyPassword) {
|
||||
this.jwtCheckKeyPassword = jwtCheckKeyPassword;
|
||||
}
|
||||
}
|
||||
@@ -2,82 +2,47 @@ package timely.configuration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import timely.validator.NotEmptyIfFieldSet;
|
||||
|
||||
@NotEmptyIfFieldSet.List({
|
||||
@NotEmptyIfFieldSet(fieldName = "useGeneratedKeypair", fieldValue = "false", notNullFieldName = "keyStoreFile", message = "must be set if timely.security.ssl.use-generated-keypair is false") })
|
||||
@NotEmptyIfFieldSet(fieldName = "useGeneratedKeypair", fieldValue = "false", notNullFieldName = "certificateFile", message = "must be set if timely.security.ssl.use-generated-keypair is false"),
|
||||
@NotEmptyIfFieldSet(fieldName = "useGeneratedKeypair", fieldValue = "false", notNullFieldName = "keyFile", message = "must be set if timely.security.ssl.use-generated-keypair is false") })
|
||||
|
||||
public class ServerSsl implements Ssl {
|
||||
public class ServerSsl {
|
||||
|
||||
private String[] ciphers = new String[] { "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA",
|
||||
"SSL_RSA_WITH_3DES_EDE_CBC_SHA" };
|
||||
private String[] enabledProtocols;
|
||||
private String keyStoreType;
|
||||
private String keyStoreFile;
|
||||
private String keyStorePassword;
|
||||
private String keyAlias;
|
||||
private String trustStoreType;
|
||||
private String certificateFile;
|
||||
private String keyFile;
|
||||
private String keyPassword;
|
||||
private String trustStoreFile;
|
||||
private String trustStorePassword;
|
||||
private boolean useGeneratedKeypair = false;
|
||||
private boolean ignoreSslHandshakeErrors = false;
|
||||
private boolean useOpenssl = true;
|
||||
private List<String> useCiphers = Lists.newArrayList("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_GCM_SHA256", "TLS_RSA_WITH_AES_128_CBC_SHA",
|
||||
"SSL_RSA_WITH_3DES_EDE_CBC_SHA");
|
||||
|
||||
public String[] getCiphers() {
|
||||
return ciphers;
|
||||
public String getCertificateFile() {
|
||||
return certificateFile;
|
||||
}
|
||||
|
||||
public void setCiphers(String[] ciphers) {
|
||||
this.ciphers = ciphers;
|
||||
public void setCertificateFile(String certificateFile) {
|
||||
this.certificateFile = certificateFile;
|
||||
}
|
||||
|
||||
public String[] getEnabledProtocols() {
|
||||
return enabledProtocols;
|
||||
public String getKeyFile() {
|
||||
return keyFile;
|
||||
}
|
||||
|
||||
public void setEnabledProtocols(String[] enabledProtocols) {
|
||||
this.enabledProtocols = enabledProtocols;
|
||||
public void setKeyFile(String keyFile) {
|
||||
this.keyFile = keyFile;
|
||||
}
|
||||
|
||||
public String getKeyStoreType() {
|
||||
return keyStoreType;
|
||||
public String getKeyPassword() {
|
||||
return keyPassword;
|
||||
}
|
||||
|
||||
public void setKeyStoreType(String keyStoreType) {
|
||||
this.keyStoreType = keyStoreType;
|
||||
}
|
||||
|
||||
public String getKeyStoreFile() {
|
||||
return keyStoreFile;
|
||||
}
|
||||
|
||||
public void setKeyStoreFile(String keyStoreFile) {
|
||||
this.keyStoreFile = keyStoreFile;
|
||||
}
|
||||
|
||||
public String getKeyStorePassword() {
|
||||
return keyStorePassword;
|
||||
}
|
||||
|
||||
public void setKeyStorePassword(String keyStorePassword) {
|
||||
this.keyStorePassword = keyStorePassword;
|
||||
}
|
||||
|
||||
public String getKeyAlias() {
|
||||
return keyAlias;
|
||||
}
|
||||
|
||||
public void setKeyAlias(String keyAlias) {
|
||||
this.keyAlias = keyAlias;
|
||||
}
|
||||
|
||||
public String getTrustStoreType() {
|
||||
return trustStoreType;
|
||||
}
|
||||
|
||||
public void setTrustStoreType(String trustStoreType) {
|
||||
this.trustStoreType = trustStoreType;
|
||||
public void setKeyPassword(String keyPassword) {
|
||||
this.keyPassword = keyPassword;
|
||||
}
|
||||
|
||||
public String getTrustStoreFile() {
|
||||
@@ -88,14 +53,6 @@ public class ServerSsl implements Ssl {
|
||||
this.trustStoreFile = trustStoreFile;
|
||||
}
|
||||
|
||||
public String getTrustStorePassword() {
|
||||
return trustStorePassword;
|
||||
}
|
||||
|
||||
public void setTrustStorePassword(String trustStorePassword) {
|
||||
this.trustStorePassword = trustStorePassword;
|
||||
}
|
||||
|
||||
public boolean isUseGeneratedKeypair() {
|
||||
return useGeneratedKeypair;
|
||||
}
|
||||
@@ -104,14 +61,6 @@ public class ServerSsl implements Ssl {
|
||||
this.useGeneratedKeypair = useGeneratedKeypair;
|
||||
}
|
||||
|
||||
public boolean isIgnoreSslHandshakeErrors() {
|
||||
return ignoreSslHandshakeErrors;
|
||||
}
|
||||
|
||||
public void setIgnoreSslHandshakeErrors(boolean ignoreSslHandshakeErrors) {
|
||||
this.ignoreSslHandshakeErrors = ignoreSslHandshakeErrors;
|
||||
}
|
||||
|
||||
public boolean isUseOpenssl() {
|
||||
return useOpenssl;
|
||||
}
|
||||
@@ -119,4 +68,12 @@ public class ServerSsl implements Ssl {
|
||||
public void setUseOpenssl(boolean useOpenssl) {
|
||||
this.useOpenssl = useOpenssl;
|
||||
}
|
||||
|
||||
public List<String> getUseCiphers() {
|
||||
return useCiphers;
|
||||
}
|
||||
|
||||
public void setUseCiphers(List<String> useCiphers) {
|
||||
this.useCiphers = useCiphers;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package timely.configuration;
|
||||
|
||||
public interface Ssl {
|
||||
|
||||
String getKeyStoreType();
|
||||
|
||||
void setKeyStoreType(String keyStoreType);
|
||||
|
||||
String getKeyStoreFile();
|
||||
|
||||
void setKeyStoreFile(String keyStoreFile);
|
||||
|
||||
String getKeyStorePassword();
|
||||
|
||||
void setKeyStorePassword(String keyStorePassword);
|
||||
|
||||
String getKeyAlias();
|
||||
|
||||
void setKeyAlias(String keyAlias);
|
||||
|
||||
String getTrustStoreType();
|
||||
|
||||
void setTrustStoreType(String trustStoreType);
|
||||
|
||||
String getTrustStoreFile();
|
||||
|
||||
void setTrustStoreFile(String trustStoreFile);
|
||||
|
||||
String getTrustStorePassword();
|
||||
|
||||
void setTrustStorePassword(String trustStorePassword);
|
||||
|
||||
String[] getCiphers();
|
||||
|
||||
void setCiphers(String[] ciphers);
|
||||
|
||||
String[] getEnabledProtocols();
|
||||
|
||||
void setEnabledProtocols(String[] enabledProtocols);
|
||||
|
||||
boolean isUseOpenssl();
|
||||
|
||||
void setUseOpenssl(boolean useOpenssl);
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,8 +102,8 @@ public class ConfigurationTest {
|
||||
"timely.accumulo.username:root",
|
||||
"timely.accumulo.password:secret",
|
||||
"timely.http.host:localhost",
|
||||
"timely.security.serverSsl.key-store-file:/tmp/foo",
|
||||
"timely.security.serverSsl.key-store-password:password").applyTo(this.context);
|
||||
"timely.security.serverSsl.certificate-file:/tmp/foo",
|
||||
"timely.security.serverSsl.key-file:/tmp/bar").applyTo(this.context);
|
||||
// @formatter:on
|
||||
context.refresh();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -31,7 +31,7 @@ public class MetricAdapterTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToMutation() {
|
||||
public void testToMutation() throws Exception {
|
||||
long ts = System.currentTimeMillis();
|
||||
List<Tag> tags = new ArrayList<>();
|
||||
tags.add(new Tag("tag1", "value1"));
|
||||
@@ -72,7 +72,7 @@ public class MetricAdapterTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToMutationWithViz() {
|
||||
public void testToMutationWithViz() throws Exception {
|
||||
long ts = System.currentTimeMillis();
|
||||
List<Tag> tags = new ArrayList<>();
|
||||
tags.add(new Tag("tag1", "value1"));
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+5
-5
@@ -10,16 +10,16 @@ import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
public class FileUserDetailsServiceTest {
|
||||
public class UserDetailsServiceTest {
|
||||
|
||||
private static ApplicationContext springContext = null;
|
||||
private static FileUserDetailsService fileUserDetailsService = null;
|
||||
private static UserDetailsService userDetailsService = null;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupClass() {
|
||||
try {
|
||||
springContext = new ClassPathXmlApplicationContext("security.xml");
|
||||
fileUserDetailsService = (FileUserDetailsService) springContext.getBean("timelyUserDetailsService");
|
||||
userDetailsService = (UserDetailsService) springContext.getBean("timelyUserDetailsService");
|
||||
} catch (BeansException e) {
|
||||
throw new ServiceConfigurationError("Error initializing from spring: " + e.getMessage(), e.getRootCause());
|
||||
}
|
||||
@@ -27,7 +27,7 @@ public class FileUserDetailsServiceTest {
|
||||
|
||||
@Test
|
||||
public void testAuths() {
|
||||
TimelyUser u = fileUserDetailsService.getUsers().get("CN=example.com");
|
||||
TimelyUser u = userDetailsService.getUsers().get("CN=example.com");
|
||||
Assert.assertNotNull("TimelyUser not found", u);
|
||||
Assert.assertEquals("3 auths expected", 3, u.getAuths().size());
|
||||
Assert.assertTrue("Unexpected auths found " + u.getAuths(),
|
||||
@@ -36,7 +36,7 @@ public class FileUserDetailsServiceTest {
|
||||
|
||||
@Test
|
||||
public void testRoles() {
|
||||
TimelyUser u = fileUserDetailsService.getUsers().get("CN=example.com");
|
||||
TimelyUser u = userDetailsService.getUsers().get("CN=example.com");
|
||||
Assert.assertNotNull("TimelyUser not found", u);
|
||||
Assert.assertEquals("3 roles expected", 3, u.getRoles().size());
|
||||
Assert.assertTrue("Unexpected roles found " + u.getRoles(),
|
||||
@@ -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
@@ -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,157 +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 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() throws Exception {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,18 @@
|
||||
package timely.test.integration;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
|
||||
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.apache.commons.io.FileUtils;
|
||||
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;
|
||||
@@ -45,46 +39,31 @@ 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 {
|
||||
if (null == mac) {
|
||||
final MiniAccumuloConfig macConfig = new MiniAccumuloConfig(tempDir, MAC_ROOT_PASSWORD);
|
||||
mac = new MiniAccumuloCluster(macConfig);
|
||||
// this is needed if the timely server is run against MiniAccumulo
|
||||
File libExt = new File(macConfig.getDir(), "/lib/ext");
|
||||
copyJarsToMacLibExt(libExt, "target", "timely-server.*.jar");
|
||||
copyJarsToMacLibExt(libExt, "target/lib", ".*.jar");
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyJarsToMacLibExt(File macLibExt, String searchDirStr, String jarRegex) {
|
||||
File searchDir = new File(Paths.get(searchDirStr).toUri());
|
||||
File[] jarFiles = searchDir.listFiles((dir, name) -> name.matches(jarRegex));
|
||||
for (File f : jarFiles) {
|
||||
try {
|
||||
FileUtils.copyURLToFile(requireNonNull(f.toURI().toURL()), new File(macLibExt, f.getName()));
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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 -> {
|
||||
@@ -108,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");
|
||||
@@ -71,9 +82,18 @@ public class MetricCompactionIT extends MacITBase {
|
||||
|
||||
@After
|
||||
public void teardown() throws Exception {
|
||||
accumuloClient.instanceOperations().setProperty(Property.TSERV_MAJC_DELAY.getKey(), "30s");
|
||||
adapter.resetState();
|
||||
AuthCache.resetConfiguration();
|
||||
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
|
||||
@@ -114,7 +134,7 @@ public class MetricCompactionIT extends MacITBase {
|
||||
|
||||
@Test
|
||||
public void tabletsCompactedUntilAgeOff() throws Exception {
|
||||
// test will replicate problem in time-series tablets where data is
|
||||
// test will replicated problem in time-series tablets where data is
|
||||
// split automatically and the resulting tablets will not be cleaned up
|
||||
// by the default compaction strategy
|
||||
//
|
||||
@@ -213,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);
|
||||
@@ -51,13 +41,19 @@ public class OneWaySSLBase extends QueryBase {
|
||||
|
||||
protected static void setupSSL(Configuration config) throws Exception {
|
||||
SelfSignedCertificate serverCert = new SelfSignedCertificate();
|
||||
config.getSecurity().getServerSsl().setCertificateFile(serverCert.certificate().getAbsolutePath());
|
||||
clientTrustStoreFile = serverCert.certificate().getAbsoluteFile();
|
||||
config.getSecurity().getServerSsl().setKeyStoreFile(serverCert.privateKey().getAbsolutePath());
|
||||
config.getSecurity().getServerSsl().setKeyFile(serverCert.privateKey().getAbsolutePath());
|
||||
config.getSecurity().getServerSsl().setUseOpenssl(false);
|
||||
config.getSecurity().getServerSsl().setUseGeneratedKeypair(false);
|
||||
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
|
||||
@@ -71,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,140 +0,0 @@
|
||||
package timely.test.integration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.Certificate;
|
||||
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.apache.commons.io.FileUtils;
|
||||
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) throws Exception {
|
||||
SelfSignedCertificate serverCert = getServerCert();
|
||||
String password = "password";
|
||||
|
||||
// write the keyStore with server certificate into a P12 trustStore
|
||||
KeyStore keyStore = KeyStore.getInstance("PKCS12");
|
||||
keyStore.load(null, null);
|
||||
keyStore.setCertificateEntry("cert", serverCert.cert());
|
||||
File trustStoreP12File = File.createTempFile("trustStore_", ".p12");
|
||||
try (OutputStream out = FileUtils.newOutputStream(trustStoreP12File, false)) {
|
||||
keyStore.store(out, password.toCharArray());
|
||||
}
|
||||
|
||||
// write the keyStore with private key and server certificate into a P12
|
||||
// keyStore
|
||||
keyStore.setKeyEntry("key", serverCert.key(), password.toCharArray(), new Certificate[] { serverCert.cert() });
|
||||
File keyStoreP12File = File.createTempFile("keyStore_", ".p12");
|
||||
try (OutputStream out = FileUtils.newOutputStream(keyStoreP12File, false)) {
|
||||
keyStore.store(out, password.toCharArray());
|
||||
}
|
||||
|
||||
config.getSecurity().getServerSsl().setKeyStoreType("PKCS12");
|
||||
config.getSecurity().getServerSsl().setKeyStoreFile(keyStoreP12File.getAbsolutePath());
|
||||
config.getSecurity().getServerSsl().setKeyStorePassword(password);
|
||||
// Needed for 2way SSL
|
||||
config.getSecurity().getServerSsl().setTrustStoreType("PKCS12");
|
||||
config.getSecurity().getServerSsl().setTrustStoreFile(trustStoreP12File.getAbsolutePath());
|
||||
config.getSecurity().getServerSsl().setTrustStorePassword(password);
|
||||
config.getSecurity().getServerSsl().setUseOpenssl(false);
|
||||
config.getSecurity().getServerSsl().setUseGeneratedKeypair(false);
|
||||
config.getSecurity().getServerSsl().setIgnoreSslHandshakeErrors(true);
|
||||
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
|
||||
|
||||
+9
-7
@@ -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));
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<beans:property name="subjectDnRegex" value="CN=(.*?)(?:,|$)"/>
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="timelyUserDetailsService" class="timely.auth.FileUserDetailsService">
|
||||
<beans:bean id="timelyUserDetailsService" class="timely.auth.UserDetailsService">
|
||||
<beans:property name="users">
|
||||
<util:list>
|
||||
<beans:bean class="timely.auth.TimelyUser">
|
||||
|
||||
Reference in new issue
Block a user