mirror of
https://github.com/NationalSecurityAgency/timely.git
synced 2026-11-10 11:51:29 -10:00
Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9027cac6e3 | ||
|
|
3663b4e6d5 | ||
|
|
64973d0674 | ||
|
|
5512306f1e | ||
|
|
d35ae08188 | ||
|
|
e448657afb | ||
|
|
1dcd893711 | ||
|
|
409f5375d1 | ||
|
|
c5df8139ca | ||
|
|
dcd23d4fc8 | ||
|
|
cc7326fc19 | ||
|
|
0d2b6e61c8 | ||
|
|
b7cd8765c5 | ||
|
|
a9d27d5b1b | ||
|
|
7d67eb218d | ||
|
|
5fb7e3dd2b | ||
|
|
5a89861cec | ||
|
|
a3bc9a01ee | ||
|
|
e2bbe4e212 |
No files matched your search
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>timely-analytics</artifactId>
|
||||
<!--
|
||||
|
||||
@@ -67,7 +67,7 @@ public class SummarizationJob {
|
||||
})
|
||||
.name("Metric Windows")
|
||||
.addSink(
|
||||
new SocketClientSink<MetricHistogram>(jp.getTimelyHostname(), jp.getTimelyTcpPort(),
|
||||
new SocketClientSink<MetricHistogram>(jp.getTimelyHostname(), jp.getTimelyTcpPort(),
|
||||
new MetricHistogram(), 2, true) {
|
||||
|
||||
private final Logger LOG = LoggerFactory
|
||||
|
||||
@@ -27,15 +27,14 @@ fi
|
||||
mkdir -p ${NATIVE_DIR}
|
||||
|
||||
pushd ${BASE_DIR}/bin
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-tcnative*.jar META-INF/native/libnetty_tcnative.${TCNATIVE_SUFFIX}
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-transport-native-epoll*.jar META-INF/native/libnetty_transport_native_epoll_x86_64.${TCNATIVE_SUFFIX}
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-tcnative-boringssl-static*.jar META-INF/native/libnetty_tcnative_linux_x86_64.${TCNATIVE_SUFFIX}
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-all*.jar META-INF/native/libnetty_transport_native_epoll_x86_64.${TCNATIVE_SUFFIX}
|
||||
popd
|
||||
|
||||
export CLASSPATH="${CONF_DIR}:${LIB_DIR}/*:${HADOOP_CONF_DIR}"
|
||||
JVM_ARGS="-Xmx1G -Xms1G -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS}"
|
||||
JVM_ARGS="-Xmx1G -Xms1G -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS} -Dlog4j.configurationFile=${CONF_DIR}/log4j2-spring.xml"
|
||||
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} -Djava.library.path=${NATIVE_DIR}/libnetty-${TCNATIVE_SUFFIX}"
|
||||
|
||||
#JVM_ARGS="${JVM_ARGS} -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
|
||||
|
||||
|
||||
@@ -46,9 +46,12 @@
|
||||
<user-service id="usernamePasswordService">
|
||||
<user name="test" password="test1" authorities="A,B,C" />
|
||||
</user-service>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
|
||||
<beans:bean id="noOpPasswordEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder"/>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
<beans:property name="userDetailsService" ref="usernamePasswordService"/>
|
||||
<beans:property name="passwordEncoder" ref="noOpPasswordEncoder"/>
|
||||
</beans:bean>
|
||||
|
||||
<authentication-manager alias="authenticationManager">
|
||||
|
||||
@@ -8,6 +8,8 @@ timely-balancer:
|
||||
assignmentFile: /timely/balancer/assignments.csv
|
||||
security:
|
||||
session-max-age: 86400
|
||||
cache-expiration-minutes: 60
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
serverSsl:
|
||||
|
||||
+3
-39
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>timely-balancer</artifactId>
|
||||
<dependencies>
|
||||
@@ -161,9 +161,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative</artifactId>
|
||||
<version>${version.netty-tcnative}</version>
|
||||
<classifier>${os.detected.classifier}</classifier>
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -247,9 +245,8 @@
|
||||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative</artifactId>
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
<version>${version.netty-tcnative}</version>
|
||||
<classifier>${os.detected.classifier}</classifier>
|
||||
<type>jar</type>
|
||||
<overWrite>false</overWrite>
|
||||
<outputDirectory>${project.build.directory}/native</outputDirectory>
|
||||
@@ -291,37 +288,4 @@
|
||||
</extension>
|
||||
</extensions>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>native-epoll-linux</id>
|
||||
<activation>
|
||||
<os>
|
||||
<family>!mac</family>
|
||||
</os>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-epoll</artifactId>
|
||||
<version>${version.netty}</version>
|
||||
<classifier>linux-x86_64</classifier>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>native-epoll</id>
|
||||
<activation>
|
||||
<os>
|
||||
<family>mac</family>
|
||||
</os>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-epoll</artifactId>
|
||||
<version>${version.netty}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
@@ -25,6 +25,7 @@ import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.WriteBufferWaterMark;
|
||||
import io.netty.channel.epoll.EpollChannelOption;
|
||||
import io.netty.channel.epoll.EpollDatagramChannel;
|
||||
import io.netty.channel.epoll.EpollEventLoopGroup;
|
||||
@@ -64,6 +65,7 @@ import org.apache.zookeeper.CreateMode;
|
||||
import org.apache.zookeeper.data.Stat;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import timely.auth.AuthCache;
|
||||
@@ -143,7 +145,7 @@ public class Balancer {
|
||||
}
|
||||
|
||||
protected static ConfigurableApplicationContext initializeConfiguration(String[] args) {
|
||||
return new SpringApplicationBuilder(SpringBootstrap.class).web(false).run(args);
|
||||
return new SpringApplicationBuilder(SpringBootstrap.class).web(WebApplicationType.NONE).run(args);
|
||||
}
|
||||
|
||||
private void shutdownHook() {
|
||||
@@ -363,7 +365,7 @@ public class Balancer {
|
||||
curatorFramework.start();
|
||||
ensureZkPaths(curatorFramework, zkPaths);
|
||||
|
||||
AuthCache.setSessionMaxAge(balancerConfig.getSecurity());
|
||||
AuthCache.configure(balancerConfig.getSecurity());
|
||||
final boolean useEpoll = useEpoll();
|
||||
Class<? extends ServerSocketChannel> channelClass;
|
||||
Class<? extends Channel> datagramChannelClass;
|
||||
@@ -449,10 +451,9 @@ public class Balancer {
|
||||
wsServer.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
|
||||
wsServer.option(ChannelOption.SO_BACKLOG, 128);
|
||||
wsServer.option(ChannelOption.SO_KEEPALIVE, true);
|
||||
/* Not sure if next three lines are necessary */
|
||||
/* Not sure if next two lines are necessary */
|
||||
wsServer.option(ChannelOption.SO_SNDBUF, 1048576);
|
||||
wsServer.option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 838860);
|
||||
wsServer.option(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 620145);
|
||||
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();
|
||||
|
||||
@@ -566,7 +567,7 @@ public class Balancer {
|
||||
ch.pipeline().addLast("idle-handler",
|
||||
new IdleStateHandler(balancerConfig.getWebsocket().getTimeout(), 0, 0));
|
||||
ch.pipeline().addLast("ws-protocol",
|
||||
new WebSocketServerProtocolHandler(WS_PATH, null, true, 65536, true));
|
||||
new WebSocketServerProtocolHandler(WS_PATH, null, true, 65536, false, true));
|
||||
ch.pipeline().addLast("wsDecoder", new WebSocketRequestDecoder(balancerConfig.getSecurity()));
|
||||
ch.pipeline().addLast("httpRelay", new WsRelayHandler(balancerConfig, metricResolver, wsClientPool));
|
||||
ch.pipeline().addLast("error", new WSTimelyExceptionHandler());
|
||||
|
||||
@@ -5,8 +5,10 @@ import javax.validation.Valid;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import timely.configuration.Cache;
|
||||
|
||||
@Validated
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "timely-balancer")
|
||||
public class BalancerConfiguration {
|
||||
|
||||
@@ -3,6 +3,7 @@ package timely.balancer.configuration;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import timely.configuration.Http;
|
||||
|
||||
@@ -10,9 +11,9 @@ public class BalancerHttp extends Http {
|
||||
|
||||
@Valid
|
||||
@NestedConfigurationProperty
|
||||
private GenericKeyedObjectPoolConfig httpClientPool = new GenericKeyedObjectPoolConfig();
|
||||
private GenericKeyedObjectPoolConfig<CloseableHttpClient> httpClientPool = new GenericKeyedObjectPoolConfig<>();
|
||||
|
||||
public GenericKeyedObjectPoolConfig getHttpClientPool() {
|
||||
public GenericKeyedObjectPoolConfig<CloseableHttpClient> getHttpClientPool() {
|
||||
return httpClientPool;
|
||||
}
|
||||
}
|
||||
@@ -4,27 +4,29 @@ import javax.validation.Valid;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import timely.client.tcp.TcpClient;
|
||||
import timely.client.udp.UdpClient;
|
||||
import timely.configuration.Server;
|
||||
|
||||
public class BalancerServer extends Server {
|
||||
|
||||
@Valid
|
||||
@NestedConfigurationProperty
|
||||
private GenericKeyedObjectPoolConfig udpClientPool = new GenericKeyedObjectPoolConfig();
|
||||
private GenericKeyedObjectPoolConfig<UdpClient> udpClientPool = new GenericKeyedObjectPoolConfig<>();
|
||||
|
||||
@Valid
|
||||
@NestedConfigurationProperty
|
||||
private GenericKeyedObjectPoolConfig tcpClientPool = new GenericKeyedObjectPoolConfig();
|
||||
private GenericKeyedObjectPoolConfig<TcpClient> tcpClientPool = new GenericKeyedObjectPoolConfig<>();
|
||||
|
||||
private int numTcpPools = 1;
|
||||
|
||||
private int tcpBufferSize = -1;
|
||||
|
||||
public GenericKeyedObjectPoolConfig getUdpClientPool() {
|
||||
public GenericKeyedObjectPoolConfig<UdpClient> getUdpClientPool() {
|
||||
return udpClientPool;
|
||||
}
|
||||
|
||||
public GenericKeyedObjectPoolConfig getTcpClientPool() {
|
||||
public GenericKeyedObjectPoolConfig<TcpClient> getTcpClientPool() {
|
||||
return tcpClientPool;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,15 +4,16 @@ import javax.validation.Valid;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import timely.client.websocket.subscription.WebSocketSubscriptionClient;
|
||||
import timely.configuration.Websocket;
|
||||
|
||||
public class BalancerWebsocket extends Websocket {
|
||||
|
||||
@Valid
|
||||
@NestedConfigurationProperty
|
||||
private GenericKeyedObjectPoolConfig wsClientPool = new GenericKeyedObjectPoolConfig();
|
||||
private GenericKeyedObjectPoolConfig<WebSocketSubscriptionClient> wsClientPool = new GenericKeyedObjectPoolConfig<>();
|
||||
|
||||
public GenericKeyedObjectPoolConfig getWsClientPool() {
|
||||
public GenericKeyedObjectPoolConfig<WebSocketSubscriptionClient> getWsClientPool() {
|
||||
return wsClientPool;
|
||||
}
|
||||
}
|
||||
@@ -4,16 +4,12 @@ import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import timely.balancer.configuration.BalancerHttp;
|
||||
import timely.balancer.configuration.BalancerSecurity;
|
||||
import timely.balancer.connection.TimelyBalancedHost;
|
||||
|
||||
public class HttpClientPool extends GenericKeyedObjectPool<TimelyBalancedHost, CloseableHttpClient> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HttpClientPool.class);
|
||||
|
||||
public HttpClientPool(BalancerSecurity balancerSecurity, BalancerHttp http, SSLContext sslContext) {
|
||||
super(new HttpClientFactory(balancerSecurity, sslContext), http.getHttpClientPool());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package timely.balancer.netty.http;
|
||||
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;
|
||||
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.net.URLEncoder;
|
||||
@@ -67,7 +67,7 @@ public class HttpRelayHandler extends SimpleChannelInboundHandler<HttpRequest> i
|
||||
try {
|
||||
try {
|
||||
request = msg.getHttpRequest();
|
||||
String originalURI = request.getUri();
|
||||
String originalURI = request.uri();
|
||||
originalURI = encodeURI(originalURI);
|
||||
|
||||
String metric = null;
|
||||
@@ -101,7 +101,7 @@ public class HttpRelayHandler extends SimpleChannelInboundHandler<HttpRequest> i
|
||||
|
||||
List<Header> relayedHeaderList = new ArrayList<>();
|
||||
for (Map.Entry<String, String> h : headers.entries()) {
|
||||
if (!h.getKey().equals(CONTENT_LENGTH)) {
|
||||
if (!h.getKey().equals(CONTENT_LENGTH.toString())) {
|
||||
relayedHeaderList.add(new BasicHeader(h.getKey(), h.getValue()));
|
||||
}
|
||||
}
|
||||
@@ -109,14 +109,14 @@ public class HttpRelayHandler extends SimpleChannelInboundHandler<HttpRequest> i
|
||||
relayedHeaderList.toArray(headerArray);
|
||||
|
||||
String relayURI = "https://" + k.getHost() + ":" + k.getHttpPort() + originalURI;
|
||||
if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
if (request.method().equals(HttpMethod.GET)) {
|
||||
HttpUriRequest relayedRequest = new HttpGet(relayURI);
|
||||
if (headerArray.length > 0) {
|
||||
relayedRequest.setHeaders(headerArray);
|
||||
}
|
||||
relayedResponse = client.execute(relayedRequest);
|
||||
|
||||
} else if (request.getMethod().equals(HttpMethod.POST)) {
|
||||
} else if (request.method().equals(HttpMethod.POST)) {
|
||||
HttpPost relayedRequest = new HttpPost(relayURI);
|
||||
|
||||
String content = request.content().toString(StandardCharsets.UTF_8);
|
||||
@@ -170,7 +170,7 @@ public class HttpRelayHandler extends SimpleChannelInboundHandler<HttpRequest> i
|
||||
if (client != null && k != null) {
|
||||
httpClientPool.returnObject(k, client);
|
||||
} else {
|
||||
LOG.error("NOT RETURNING CONNECTION! " + msg.getHttpRequest().getUri());
|
||||
LOG.error("NOT RETURNING CONNECTION! " + msg.getHttpRequest().uri());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class WsClientHandler extends ClientHandler {
|
||||
Multimap<String, String> proxyRequestHeaders = HashMultimap.create();
|
||||
ProxiedEntityUtils.addProxyHeaders(proxyRequestHeaders, token.getClientCert());
|
||||
for (String s : proxyRequestHeaders.keySet()) {
|
||||
headers.put(s, new ArrayList(proxyRequestHeaders.get(s)));
|
||||
headers.put(s, new ArrayList<>(proxyRequestHeaders.get(s)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class WsClientHandler extends ClientHandler {
|
||||
for (String s : originalRequestHeaders.keySet()) {
|
||||
if (!headers.containsKey(s)) {
|
||||
// add pre-existing values if key does not exist in proxyRequest
|
||||
headers.put(s, new ArrayList(originalRequestHeaders.get(s)));
|
||||
headers.put(s, new ArrayList<>(originalRequestHeaders.get(s)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,15 +265,15 @@ public class BalancedMetricResolver implements MetricResolver {
|
||||
|
||||
private void startServiceListener(CuratorFramework curatorFramework) {
|
||||
try {
|
||||
ServiceDiscovery discovery = ServiceDiscoveryBuilder.builder(ServerDetails.class).client(curatorFramework)
|
||||
.basePath(SERVICE_DISCOVERY_PATH).build();
|
||||
ServiceDiscovery<ServerDetails> discovery = ServiceDiscoveryBuilder.builder(ServerDetails.class)
|
||||
.client(curatorFramework).basePath(SERVICE_DISCOVERY_PATH).build();
|
||||
discovery.start();
|
||||
Collection<ServiceInstance> instances = discovery.queryForInstances("timely-server");
|
||||
Collection<ServiceInstance<ServerDetails>> instances = discovery.queryForInstances("timely-server");
|
||||
|
||||
balancerLock.writeLock().lock();
|
||||
try {
|
||||
for (ServiceInstance si : instances) {
|
||||
ServerDetails pl = (ServerDetails) si.getPayload();
|
||||
for (ServiceInstance<ServerDetails> si : instances) {
|
||||
ServerDetails pl = si.getPayload();
|
||||
TimelyBalancedHost tbh = TimelyBalancedHost.of(pl.getHost(), pl.getTcpPort(), pl.getHttpPort(),
|
||||
pl.getWsPort(), pl.getUdpPort());
|
||||
LOG.info("adding service {} host:{} tcpPort:{} httpPort:{} wsPort:{} udpPort:{}", si.getId(),
|
||||
@@ -286,7 +286,8 @@ public class BalancedMetricResolver implements MetricResolver {
|
||||
balancerLock.writeLock().unlock();
|
||||
}
|
||||
|
||||
final ServiceCache serviceCache = discovery.serviceCacheBuilder().name("timely-server").build();
|
||||
final ServiceCache<ServerDetails> serviceCache = discovery.serviceCacheBuilder().name("timely-server")
|
||||
.build();
|
||||
ServiceCacheListener listener = new ServiceCacheListener() {
|
||||
|
||||
@Override
|
||||
@@ -294,9 +295,9 @@ public class BalancedMetricResolver implements MetricResolver {
|
||||
boolean rebalanceNeeded = false;
|
||||
balancerLock.writeLock().lock();
|
||||
try {
|
||||
List<ServiceInstance> instances = serviceCache.getInstances();
|
||||
List<ServiceInstance<ServerDetails>> instances = serviceCache.getInstances();
|
||||
Set<TimelyBalancedHost> availableHosts = new HashSet<>();
|
||||
for (ServiceInstance si : instances) {
|
||||
for (ServiceInstance<ServerDetails> si : instances) {
|
||||
ServerDetails pl = (ServerDetails) si.getPayload();
|
||||
TimelyBalancedHost tbh = TimelyBalancedHost.of(pl.getHost(), pl.getTcpPort(),
|
||||
pl.getHttpPort(), pl.getWsPort(), pl.getUdpPort());
|
||||
|
||||
+3
-2
@@ -4,12 +4,13 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>timely-client</artifactId>
|
||||
<properties>
|
||||
<!-- PEP 440 compliant version gets substituted into src/main/python/template/setup.py -->
|
||||
<python.client.version>1.2.1.dev0</python.client.version>
|
||||
<!-- use .dev0 instead of -SNAPSHOT -->
|
||||
<python.client.version>1.2.5.dev0</python.client.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
||||
@@ -47,7 +47,6 @@ public class TcpClient implements AutoCloseable {
|
||||
*
|
||||
* @param metric
|
||||
* newline terminated string representation of Timely metric
|
||||
* @throws IOException
|
||||
*/
|
||||
public synchronized void write(String metric) throws IOException {
|
||||
if (connect() != 0) {
|
||||
|
||||
@@ -62,7 +62,6 @@ public interface ObjectSizeOf {
|
||||
* ObjectSizeOf interface and if implemented on the object will use that.
|
||||
* Otherwise it will do a simple navigation of the fields using reflection.
|
||||
*
|
||||
* @param o
|
||||
* @return an approximation of the object size
|
||||
*/
|
||||
public static long getObjectSize(Object o, boolean useSizeInBytesMethod, boolean debug) {
|
||||
|
||||
@@ -77,8 +77,6 @@ public class Tag implements Comparable<Tag>, Serializable {
|
||||
|
||||
/**
|
||||
* Joins key and value into key=value
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String join() {
|
||||
return tagParser.combine(this);
|
||||
|
||||
@@ -47,7 +47,6 @@ public class TagListParser implements Parser<List<Tag>>, Combiner<Collection<Tag
|
||||
* An alternative combiner for a map of string to string instead of a list of
|
||||
* tags
|
||||
*
|
||||
* @param tags
|
||||
* @return string representation
|
||||
*/
|
||||
public String combine(Map<String, String> tags) {
|
||||
|
||||
@@ -47,9 +47,9 @@ public class SerializationTest {
|
||||
testSerialization(remove);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> void testSerialization(T o) throws Exception {
|
||||
String ser = mapper.writeValueAsString(o);
|
||||
@SuppressWarnings("unchecked")
|
||||
T des = mapper.readValue(ser, (Class<T>) o.getClass());
|
||||
Assert.assertEquals(o, des);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>collectd-nsq-plugin</artifactId>
|
||||
<dependencies>
|
||||
|
||||
+8
-8
@@ -10,7 +10,7 @@ import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.collectd.api.OConfigItem;
|
||||
|
||||
public class PooledCloseableHttpClientFactory implements PooledObjectFactory {
|
||||
public class PooledCloseableHttpClientFactory implements PooledObjectFactory<CloseableHttpClient> {
|
||||
|
||||
private int connectionRequestTimeout = 10000; // 10 seconds in milliseconds
|
||||
private int connectTimeout = 30000; // 30 seconds in milliseconds
|
||||
@@ -43,19 +43,19 @@ public class PooledCloseableHttpClientFactory implements PooledObjectFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledObject makeObject() throws Exception {
|
||||
public PooledObject<CloseableHttpClient> makeObject() throws Exception {
|
||||
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(connectionRequestTimeout)
|
||||
.setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).build();
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
builder.setDefaultRequestConfig(requestConfig);
|
||||
builder.setConnectionTimeToLive(connectionTimeToLive, TimeUnit.MILLISECONDS);
|
||||
return new DefaultPooledObject(builder.build());
|
||||
return new DefaultPooledObject<>(builder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyObject(PooledObject pooledObject) throws Exception {
|
||||
public void destroyObject(PooledObject<CloseableHttpClient> pooledObject) throws Exception {
|
||||
try {
|
||||
((CloseableHttpClient) pooledObject.getObject()).close();
|
||||
pooledObject.getObject().close();
|
||||
} catch (Exception e) {
|
||||
// do nothing
|
||||
} finally {
|
||||
@@ -65,17 +65,17 @@ public class PooledCloseableHttpClientFactory implements PooledObjectFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateObject(PooledObject pooledObject) {
|
||||
public boolean validateObject(PooledObject<CloseableHttpClient> pooledObject) {
|
||||
return pooledObject.getObject() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activateObject(PooledObject pooledObject) throws Exception {
|
||||
public void activateObject(PooledObject<CloseableHttpClient> pooledObject) throws Exception {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passivateObject(PooledObject pooledObject) throws Exception {
|
||||
public void passivateObject(PooledObject<CloseableHttpClient> pooledObject) throws Exception {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ public class WriteNSQPlugin extends CollectDPluginParent
|
||||
Collectd.registerWrite(WriteNSQPlugin.class.getName(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int write(ValueList vl) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
DataOutputStream out = new DataOutputStream(baos);
|
||||
@@ -110,15 +111,17 @@ public class WriteNSQPlugin extends CollectDPluginParent
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int shutdown() {
|
||||
Collectd.logInfo("Shutting down connection to NSQ at " + host + ":" + port);
|
||||
clientPool.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int config(OConfigItem config) {
|
||||
super.config(config);
|
||||
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
|
||||
GenericObjectPoolConfig<CloseableHttpClient> poolConfig = new GenericObjectPoolConfig<>();
|
||||
// use max size for maxTotal and maxIdle
|
||||
// no need to activate or passivate
|
||||
poolConfig.setMaxTotal(POOL_MAX_SIZE);
|
||||
@@ -156,7 +159,7 @@ public class WriteNSQPlugin extends CollectDPluginParent
|
||||
Collectd.logError("NSQ host, port, and topic must be configured");
|
||||
return -1;
|
||||
}
|
||||
this.clientPool = new GenericObjectPool(pooledCloseableHttpClientFactory, poolConfig);
|
||||
this.clientPool = new GenericObjectPool<>(pooledCloseableHttpClientFactory, poolConfig);
|
||||
this.endpoint = "http://" + host + ":" + port + "/mpub?topic=" + topic;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>collectd-plugin-parent</artifactId>
|
||||
<dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>collectd-timely-plugin</artifactId>
|
||||
<dependencies>
|
||||
|
||||
+7
-7
@@ -8,7 +8,7 @@ import org.apache.commons.pool2.impl.DefaultPooledObject;
|
||||
import org.collectd.api.Collectd;
|
||||
import org.collectd.api.OConfigItem;
|
||||
|
||||
public class PooledSocketFactory implements PooledObjectFactory {
|
||||
public class PooledSocketFactory implements PooledObjectFactory<Socket> {
|
||||
|
||||
private String host = null;
|
||||
private int port = 0;
|
||||
@@ -81,12 +81,12 @@ public class PooledSocketFactory implements PooledObjectFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledObject makeObject() throws Exception {
|
||||
return new DefaultPooledObject(connect());
|
||||
public PooledObject<Socket> makeObject() throws Exception {
|
||||
return new DefaultPooledObject<>(connect());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyObject(PooledObject pooledObject) throws Exception {
|
||||
public void destroyObject(PooledObject<Socket> pooledObject) throws Exception {
|
||||
try {
|
||||
Collectd.logDebug("Shutting down connection to Timely at " + host + ":" + port);
|
||||
Socket socket = (Socket) pooledObject.getObject();
|
||||
@@ -103,7 +103,7 @@ public class PooledSocketFactory implements PooledObjectFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateObject(PooledObject pooledObject) {
|
||||
public boolean validateObject(PooledObject<Socket> pooledObject) {
|
||||
if (connectionTimeToLive > -1) {
|
||||
if (System.currentTimeMillis() > pooledObject.getCreateTime() + connectionTimeToLive) {
|
||||
return false;
|
||||
@@ -114,12 +114,12 @@ public class PooledSocketFactory implements PooledObjectFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activateObject(PooledObject pooledObject) throws Exception {
|
||||
public void activateObject(PooledObject<Socket> pooledObject) throws Exception {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passivateObject(PooledObject pooledObject) throws Exception {
|
||||
public void passivateObject(PooledObject<Socket> pooledObject) throws Exception {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@@ -86,13 +86,13 @@ public class WriteTimelyPlugin extends CollectDPluginParent
|
||||
PooledSocketFactory socketFactory = new PooledSocketFactory();
|
||||
retval = socketFactory.config(config);
|
||||
if (retval == 0) {
|
||||
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
|
||||
GenericObjectPoolConfig<Socket> poolConfig = new GenericObjectPoolConfig<>();
|
||||
// use max size for maxTotal and maxIdle
|
||||
// no need to activate and passivate
|
||||
poolConfig.setMaxTotal(POOL_MAX_SIZE);
|
||||
poolConfig.setMaxIdle(POOL_MAX_SIZE);
|
||||
poolConfig.setTestOnReturn(true);
|
||||
socketPool = new GenericObjectPool(socketFactory, poolConfig);
|
||||
socketPool = new GenericObjectPool<>(socketFactory, poolConfig);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>timely-common</artifactId>
|
||||
<dependencies>
|
||||
|
||||
@@ -27,15 +27,14 @@ fi
|
||||
mkdir -p ${NATIVE_DIR}
|
||||
|
||||
pushd ${BASE_DIR}/bin
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-tcnative*.jar META-INF/native/libnetty_tcnative.${TCNATIVE_SUFFIX}
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-transport-native-epoll*.jar META-INF/native/libnetty_transport_native_epoll_x86_64.${TCNATIVE_SUFFIX}
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-tcnative-boringssl-static*.jar META-INF/native/libnetty_tcnative_linux_x86_64.${TCNATIVE_SUFFIX}
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-all*.jar META-INF/native/libnetty_transport_native_epoll_x86_64.${TCNATIVE_SUFFIX}
|
||||
popd
|
||||
|
||||
export CLASSPATH="${CONF_DIR}:${LIB_DIR}/*:${HADOOP_CONF_DIR}"
|
||||
JVM_ARGS="-Xmx1G -Xms1G -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS}"
|
||||
JVM_ARGS="-Xmx1G -Xms1G -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS} Dlog4j.configurationFile=${CONF_DIR}/log4j2-spring.xml"
|
||||
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} -Djava.library.path=${NATIVE_DIR}/libnetty-${TCNATIVE_SUFFIX}"
|
||||
|
||||
#JVM_ARGS="${JVM_ARGS} -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ grafana-auth:
|
||||
port: 3001
|
||||
security:
|
||||
session-max-age: 86400
|
||||
cache-expiration-minutes: 60
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
serverSsl:
|
||||
|
||||
@@ -46,9 +46,12 @@
|
||||
<user-service id="usernamePasswordService">
|
||||
<user name="test" password="test1" authorities="A,B,C" />
|
||||
</user-service>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
|
||||
<beans:bean id="noOpPasswordEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder"/>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
<beans:property name="userDetailsService" ref="usernamePasswordService"/>
|
||||
<beans:property name="passwordEncoder" ref="noOpPasswordEncoder"/>
|
||||
</beans:bean>
|
||||
|
||||
<authentication-manager alias="authenticationManager">
|
||||
|
||||
+3
-39
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>grafana-auth</artifactId>
|
||||
<dependencies>
|
||||
@@ -165,9 +165,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative</artifactId>
|
||||
<version>${version.netty-tcnative}</version>
|
||||
<classifier>${os.detected.classifier}</classifier>
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -251,9 +249,8 @@
|
||||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative</artifactId>
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
<version>${version.netty-tcnative}</version>
|
||||
<classifier>${os.detected.classifier}</classifier>
|
||||
<type>jar</type>
|
||||
<overWrite>false</overWrite>
|
||||
<outputDirectory>${project.build.directory}/native</outputDirectory>
|
||||
@@ -295,37 +292,4 @@
|
||||
</extension>
|
||||
</extensions>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>native-epoll-linux</id>
|
||||
<activation>
|
||||
<os>
|
||||
<family>!mac</family>
|
||||
</os>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-epoll</artifactId>
|
||||
<version>${version.netty}</version>
|
||||
<classifier>linux-x86_64</classifier>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>native-epoll</id>
|
||||
<activation>
|
||||
<os>
|
||||
<family>mac</family>
|
||||
</os>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-epoll</artifactId>
|
||||
<version>${version.netty}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
@@ -43,6 +43,7 @@ import io.netty.handler.stream.ChunkedWriteHandler;
|
||||
import io.netty.util.internal.SystemPropertyUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import timely.auth.AuthCache;
|
||||
@@ -81,7 +82,7 @@ public class GrafanaAuth {
|
||||
}
|
||||
|
||||
protected static ConfigurableApplicationContext initializeConfiguration(String[] args) {
|
||||
return new SpringApplicationBuilder(SpringBootstrap.class).web(false).run(args);
|
||||
return new SpringApplicationBuilder(SpringBootstrap.class).web(WebApplicationType.NONE).run(args);
|
||||
}
|
||||
|
||||
private void shutdownHook() {
|
||||
@@ -225,7 +226,7 @@ public class GrafanaAuth {
|
||||
|
||||
public void run() throws Exception {
|
||||
|
||||
AuthCache.setSessionMaxAge(grafanaAuthConfig.getSecurity());
|
||||
AuthCache.configure(grafanaAuthConfig.getSecurity());
|
||||
final boolean useEpoll = useEpoll();
|
||||
Class<? extends ServerSocketChannel> channelClass;
|
||||
if (useEpoll) {
|
||||
|
||||
+2
-2
@@ -5,9 +5,11 @@ import javax.validation.Valid;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import timely.balancer.configuration.BalancerHttp;
|
||||
import timely.balancer.configuration.BalancerSecurity;
|
||||
|
||||
@Validated
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "grafana-auth")
|
||||
public class GrafanaAuthConfiguration {
|
||||
@@ -41,8 +43,6 @@ public class GrafanaAuthConfiguration {
|
||||
/**
|
||||
* Time to wait (in seconds) for connections to finish and to make sure no new
|
||||
* connections happen before shutting down Netty event loop groups.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getShutdownQuietPeriod() {
|
||||
return this.shutdownQuietPeriod;
|
||||
|
||||
+14
-14
@@ -1,6 +1,6 @@
|
||||
package timely.grafana.auth.netty.http;
|
||||
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;
|
||||
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.net.URLEncoder;
|
||||
@@ -71,7 +71,7 @@ public class GrafanaRelayHandler extends SimpleChannelInboundHandler<HttpRequest
|
||||
try {
|
||||
try {
|
||||
request = msg.getHttpRequest();
|
||||
String originalURI = request.getUri();
|
||||
String originalURI = request.uri();
|
||||
originalURI = encodeURI(originalURI);
|
||||
|
||||
if (msg instanceof GrafanaRequest) {
|
||||
@@ -92,37 +92,37 @@ public class GrafanaRelayHandler extends SimpleChannelInboundHandler<HttpRequest
|
||||
Multimap<String, String> headers = HttpHeaderUtils.toMultimap(request.headers());
|
||||
|
||||
// If incoming user sets these headers, do not relay them
|
||||
headers.removeAll("X-WEBAUTH-USER");
|
||||
headers.removeAll("X-WEBAUTH-NAME");
|
||||
headers.removeAll("x-webauth-user");
|
||||
headers.removeAll("x-webauth-name");
|
||||
TimelyPrincipal principal = token.getTimelyPrincipal();
|
||||
TimelyUser user = principal.getPrimaryUser();
|
||||
String subjectDn = user.getDn().subjectDN();
|
||||
String userName = DnUtils.getCommonName(subjectDn);
|
||||
String loginName = DnUtils.getShortName(subjectDn);
|
||||
headers.put("X-WEBAUTH-USER", loginName);
|
||||
headers.put("X-WEBAUTH-NAME", userName);
|
||||
headers.put("x-webauth-user", loginName);
|
||||
headers.put("x-webauth-name", userName);
|
||||
List<Header> relayedHeaderList = new ArrayList<>();
|
||||
for (Map.Entry<String, String> h : headers.entries()) {
|
||||
if (!h.getKey().equals(CONTENT_LENGTH)) {
|
||||
if (!h.getKey().equals(CONTENT_LENGTH.toString())) {
|
||||
relayedHeaderList.add(new BasicHeader(h.getKey(), h.getValue()));
|
||||
}
|
||||
}
|
||||
Header[] headerArray = new Header[relayedHeaderList.size()];
|
||||
relayedHeaderList.toArray(headerArray);
|
||||
relayURI = protocol + "://" + host + ":" + port + originalURI;
|
||||
if (request.getMethod().equals(HttpMethod.HEAD)) {
|
||||
if (request.method().equals(HttpMethod.HEAD)) {
|
||||
HttpHead relayedRequest = new HttpHead(relayURI);
|
||||
if (headerArray.length > 0) {
|
||||
relayedRequest.setHeaders(headerArray);
|
||||
}
|
||||
relayedResponse = client.execute(relayedRequest);
|
||||
} else if (request.getMethod().equals(HttpMethod.GET)) {
|
||||
} else if (request.method().equals(HttpMethod.GET)) {
|
||||
HttpGet relayedRequest = new HttpGet(relayURI);
|
||||
if (headerArray.length > 0) {
|
||||
relayedRequest.setHeaders(headerArray);
|
||||
}
|
||||
relayedResponse = client.execute(relayedRequest);
|
||||
} else if (request.getMethod().equals(HttpMethod.POST)) {
|
||||
} else if (request.method().equals(HttpMethod.POST)) {
|
||||
HttpPost relayedRequest = new HttpPost(relayURI);
|
||||
String content = request.content().toString(StandardCharsets.UTF_8);
|
||||
StringEntity entity = new StringEntity(content);
|
||||
@@ -131,7 +131,7 @@ public class GrafanaRelayHandler extends SimpleChannelInboundHandler<HttpRequest
|
||||
relayedRequest.setHeaders(headerArray);
|
||||
}
|
||||
relayedResponse = client.execute(relayedRequest);
|
||||
} else if (request.getMethod().equals(HttpMethod.PUT)) {
|
||||
} else if (request.method().equals(HttpMethod.PUT)) {
|
||||
HttpPut relayedRequest = new HttpPut(relayURI);
|
||||
String content = request.content().toString(StandardCharsets.UTF_8);
|
||||
StringEntity entity = new StringEntity(content);
|
||||
@@ -140,13 +140,13 @@ public class GrafanaRelayHandler extends SimpleChannelInboundHandler<HttpRequest
|
||||
relayedRequest.setHeaders(headerArray);
|
||||
}
|
||||
relayedResponse = client.execute(relayedRequest);
|
||||
} else if (request.getMethod().equals(HttpMethod.DELETE)) {
|
||||
} else if (request.method().equals(HttpMethod.DELETE)) {
|
||||
HttpDelete relayedRequest = new HttpDelete(relayURI);
|
||||
if (headerArray.length > 0) {
|
||||
relayedRequest.setHeaders(headerArray);
|
||||
}
|
||||
relayedResponse = client.execute(relayedRequest);
|
||||
} else if (request.getMethod().equals(HttpMethod.OPTIONS)) {
|
||||
} else if (request.method().equals(HttpMethod.OPTIONS)) {
|
||||
HttpOptions relayedRequest = new HttpOptions(relayURI);
|
||||
if (headerArray.length > 0) {
|
||||
relayedRequest.setHeaders(headerArray);
|
||||
@@ -199,7 +199,7 @@ public class GrafanaRelayHandler extends SimpleChannelInboundHandler<HttpRequest
|
||||
if (client != null && k != null) {
|
||||
httpClientPool.returnObject(k, client);
|
||||
} else {
|
||||
LOG.error("NOT RETURNING CONNECTION! " + msg.getHttpRequest().getUri());
|
||||
LOG.error("NOT RETURNING CONNECTION! " + msg.getHttpRequest().uri());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@ import com.google.common.collect.Multimap;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.QueryStringDecoder;
|
||||
import io.netty.handler.codec.http.cookie.ServerCookieDecoder;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -47,7 +47,7 @@ public class GrafanaRequestDecoder extends MessageToMessageDecoder<FullHttpReque
|
||||
|
||||
public static String getSessionId(FullHttpRequest msg) {
|
||||
Multimap<String, String> headers = HttpHeaderUtils.toMultimap(msg.headers());
|
||||
Collection<String> cookies = headers.get(Names.COOKIE);
|
||||
Collection<String> cookies = headers.get(HttpHeaderNames.COOKIE.toString());
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
cookies.forEach(h -> {
|
||||
ServerCookieDecoder.STRICT.decode(h).forEach(c -> {
|
||||
@@ -70,7 +70,7 @@ public class GrafanaRequestDecoder extends MessageToMessageDecoder<FullHttpReque
|
||||
|
||||
LOG.trace(LOG_RECEIVED_REQUEST, msg);
|
||||
|
||||
final String uri = msg.getUri();
|
||||
final String uri = msg.uri();
|
||||
final QueryStringDecoder decoder = new QueryStringDecoder(uri);
|
||||
if (decoder.path().equals(nonSecureRedirectAddress)) {
|
||||
out.add(new StrictTransportResponse());
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>timely-app</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
Vendored
+2
-2
@@ -23,8 +23,8 @@
|
||||
{"name": "Project site", "url": "https://github.com/NationalSecurityAgency/timely"},
|
||||
{"name": "License & Terms", "url": "https://raw.githubusercontent.com/NationalSecurityAgency/timely/master/LICENSE"}
|
||||
],
|
||||
"version": "1.1.0",
|
||||
"updated": "2019-01-15"
|
||||
"version": "1.2.5-SNAPSHOT",
|
||||
"updated": "2019-05-30"
|
||||
},
|
||||
|
||||
"includes": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "timely-app",
|
||||
"private": true,
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.5-SNAPSHOT",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
{"name": "Project site", "url": "https://github.com/NationalSecurityAgency/timely"},
|
||||
{"name": "License & Terms", "url": "https://raw.githubusercontent.com/NationalSecurityAgency/timely/master/LICENSE"}
|
||||
],
|
||||
"version": "1.1.0",
|
||||
"updated": "2019-01-15"
|
||||
"version": "1.2.5-SNAPSHOT",
|
||||
"updated": "2019-05-30"
|
||||
},
|
||||
|
||||
"includes": [
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.5-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Timely</name>
|
||||
<description>A secure and scalable time series database based on Apache Accumulo</description>
|
||||
@@ -41,33 +41,31 @@
|
||||
<os.detection.classifierWithLikes>fedora</os.detection.classifierWithLikes>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<version.accumulo>1.9.2</version.accumulo>
|
||||
<version.accumulo>1.9.3</version.accumulo>
|
||||
<version.buildnumber-maven>1.4</version.buildnumber-maven>
|
||||
<version.caffeine>2.3.3</version.caffeine>
|
||||
<version.caffeine>2.6.2</version.caffeine>
|
||||
<version.collectd>5.7.1</version.collectd>
|
||||
<version.commons-collections4>4.1</version.commons-collections4>
|
||||
<version.commons-configuration>1.10</version.commons-configuration>
|
||||
<version.commons-io>2.6</version.commons-io>
|
||||
<version.commons-lang3>3.5</version.commons-lang3>
|
||||
<version.commons-pool2>2.6.0</version.commons-pool2>
|
||||
<version.curator>2.11.1</version.curator>
|
||||
<version.disruptor>3.3.6</version.disruptor>
|
||||
<version.commons-collections4>4.3</version.commons-collections4>
|
||||
<version.commons-lang3>3.8.1</version.commons-lang3>
|
||||
<version.commons-pool2>2.6.1</version.commons-pool2>
|
||||
<version.curator>4.1.0</version.curator>
|
||||
<version.disruptor>3.4.2</version.disruptor>
|
||||
<version.eclipse-lifecycle>1.0.0</version.eclipse-lifecycle>
|
||||
<version.fast-classpath-scanner>2.0.5</version.fast-classpath-scanner>
|
||||
<version.fast-classpath-scanner>3.1.13</version.fast-classpath-scanner>
|
||||
<version.flink>1.1.4</version.flink>
|
||||
<version.google-flatbuffers>1.10.0</version.google-flatbuffers>
|
||||
<version.guava>19.0</version.guava>
|
||||
<version.guava>27.1-jre</version.guava>
|
||||
<version.hadoop>2.7.3</version.hadoop>
|
||||
<version.httpcomponents>4.5.2</version.httpcomponents>
|
||||
<version.httpcomponents>4.5.6</version.httpcomponents>
|
||||
<version.impsort>1.2.0</version.impsort>
|
||||
<version.jackson>2.9.8</version.jackson>
|
||||
<version.jackson>2.9.9</version.jackson>
|
||||
<version.jacoco>0.7.6.201602180812</version.jacoco>
|
||||
<version.javacsv>2.0</version.javacsv>
|
||||
<version.javassist>3.21.0-GA</version.javassist>
|
||||
<version.javassist>3.24.1-GA</version.javassist>
|
||||
<version.jcip-annotations>1.0</version.jcip-annotations>
|
||||
<version.jsoup>1.9.2</version.jsoup>
|
||||
<version.jsoup>1.11.3</version.jsoup>
|
||||
<version.junit>4.12</version.junit>
|
||||
<version.log4j>2.6.2</version.log4j>
|
||||
<version.log4j>2.11.2</version.log4j>
|
||||
<version.maven-assembly>2.6</version.maven-assembly>
|
||||
<version.maven-build-helper>1.12</version.maven-build-helper>
|
||||
<version.maven-compiler>3.3</version.maven-compiler>
|
||||
@@ -77,14 +75,14 @@
|
||||
<version.maven-rpm>2.1.4</version.maven-rpm>
|
||||
<version.maven-shade>2.4.2</version.maven-shade>
|
||||
<version.maven-surefire>2.19.1</version.maven-surefire>
|
||||
<version.netty>4.0.56.Final</version.netty>
|
||||
<version.netty-tcnative>2.0.7.Final</version.netty-tcnative>
|
||||
<version.netty>4.1.35.Final</version.netty>
|
||||
<version.netty-tcnative>2.0.25.Final</version.netty-tcnative>
|
||||
<version.os-maven>1.5.0.Final</version.os-maven>
|
||||
<version.powermock>1.6.4</version.powermock>
|
||||
<version.slf4j>1.7.21</version.slf4j>
|
||||
<version.slf4j>1.7.26</version.slf4j>
|
||||
<version.spotbugs-maven>3.1.7</version.spotbugs-maven>
|
||||
<version.spring-boot>1.4.1.RELEASE</version.spring-boot>
|
||||
<version.tyrus>1.13</version.tyrus>
|
||||
<version.spring-boot>2.1.3.RELEASE</version.spring-boot>
|
||||
<version.tyrus>1.15</version.tyrus>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
@@ -141,13 +139,18 @@
|
||||
<dependency>
|
||||
<groupId>io.github.lukehutch</groupId>
|
||||
<artifactId>fast-classpath-scanner</artifactId>
|
||||
<version>2.0.5</version>
|
||||
<version>${version.fast-classpath-scanner}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>${version.netty}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
<version>${version.netty-tcnative}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.javacsv</groupId>
|
||||
<artifactId>javacsv</artifactId>
|
||||
@@ -157,6 +160,12 @@
|
||||
<groupId>org.apache.accumulo</groupId>
|
||||
<artifactId>accumulo-core</artifactId>
|
||||
<version>${version.accumulo}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.accumulo</groupId>
|
||||
@@ -452,7 +461,7 @@
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${version.maven-surefire}</version>
|
||||
<configuration>
|
||||
<argLine>${failsafeArgLine} -Djava.library.path=${project.build.directory}/native/META-INF/native/libnetty-tcnative.so -Dzookeeper.sasl.client=false</argLine>
|
||||
<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>**/*.java</include>
|
||||
</includes>
|
||||
@@ -495,7 +504,7 @@
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${version.maven-surefire}</version>
|
||||
<configuration>
|
||||
<argLine>${sureFireArgLine} -Djava.library.path=${project.build.directory}/native/META-INF/native/libnetty-tcnative.so -Dzookeeper.sasl.client=false</argLine>
|
||||
<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>
|
||||
|
||||
@@ -27,15 +27,14 @@ fi
|
||||
mkdir -p ${NATIVE_DIR}
|
||||
|
||||
pushd ${BASE_DIR}/bin
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-tcnative*.jar META-INF/native/libnetty_tcnative.${TCNATIVE_SUFFIX}
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-transport-native-epoll*.jar META-INF/native/libnetty_transport_native_epoll_x86_64.${TCNATIVE_SUFFIX}
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-tcnative-boringssl-static*.jar META-INF/native/libnetty_tcnative_linux_x86_64.${TCNATIVE_SUFFIX}
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-all*.jar META-INF/native/libnetty_transport_native_epoll_x86_64.${TCNATIVE_SUFFIX}
|
||||
popd
|
||||
|
||||
export CLASSPATH="${CONF_DIR}:${LIB_DIR}/*"
|
||||
JVM_ARGS="-Xmx256m -Xms256m -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS}"
|
||||
export CLASSPATH="${CONF_DIR}:${LIB_DIR}/*:${HADOOP_CONF_DIR}"
|
||||
JVM_ARGS="-Xmx256m -Xms256m -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS} -Dlog4j.configurationFile=${CONF_DIR}/log4j2-spring.xml"
|
||||
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} -Djava.library.path=${NATIVE_DIR}/libnetty-${TCNATIVE_SUFFIX}"
|
||||
|
||||
echo "$JAVA_HOME/bin/java ${JVM_ARGS} timely.Server --spring.config.name=timely"
|
||||
$JAVA_HOME/bin/java ${JVM_ARGS} timely.Server --spring.config.name=timely
|
||||
|
||||
@@ -2,17 +2,12 @@
|
||||
|
||||
if [[ `uname` == "Darwin" ]]; then
|
||||
THIS_SCRIPT=`python -c 'import os,sys; print os.path.realpath(sys.argv[1])' $0`
|
||||
TCNATIVE_SUFFIX="tcnative.jnilib"
|
||||
TCNATIVE_SUFFIX="jnilib"
|
||||
else
|
||||
THIS_SCRIPT=`readlink -f $0`
|
||||
TCNATIVE_SUFFIX="tcnative.so"
|
||||
TCNATIVE_SUFFIX="so"
|
||||
fi
|
||||
|
||||
# netty tcnative file reference
|
||||
#netty-tcnative-1.1.33.Fork18-linux-x86_64-fedora.jar -> libnetty-tcnative.so
|
||||
#netty-tcnative-1.1.33.Fork18-linux-x86_64.jar -> libnetty-tcnative.so
|
||||
#netty-tcnative-1.1.33.Fork18-osx-x86_64.jar -> libnetty-tcnative.jnilib
|
||||
|
||||
THIS_DIR="${THIS_SCRIPT%/*}"
|
||||
NATIVE_DIR="${THIS_DIR}/META-INF/native"
|
||||
BASE_DIR=${THIS_DIR}/..
|
||||
@@ -32,11 +27,12 @@ fi
|
||||
mkdir -p ${NATIVE_DIR}
|
||||
|
||||
pushd ${BASE_DIR}/bin
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-tcnative*.jar META-INF/native/libnetty-${TCNATIVE_SUFFIX}
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-tcnative-boringssl-static*.jar META-INF/native/libnetty_tcnative_linux_x86_64.${TCNATIVE_SUFFIX}
|
||||
$JAVA_HOME/bin/jar xf ${LIB_DIR}/netty-all*.jar META-INF/native/libnetty_transport_native_epoll_x86_64.${TCNATIVE_SUFFIX}
|
||||
popd
|
||||
|
||||
export CLASSPATH="${CONF_DIR}:${LIB_DIR}/*"
|
||||
JVM_ARGS="-Xmx256m -Xms256m -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS}"
|
||||
export CLASSPATH="${CONF_DIR}:${LIB_DIR}/*:${HADOOP_CONF_DIR}"
|
||||
JVM_ARGS="-Xmx256m -Xms256m -Dio.netty.eventLoopThreads=${NUM_SERVER_THREADS} -Dlog4j.configurationFile=${CONF_DIR}/log4j2-spring.xml"
|
||||
JVM_ARGS="${JVM_ARGS} -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"
|
||||
JVM_ARGS="${JVM_ARGS} -Djava.library.path=${NATIVE_DIR}"
|
||||
# for debugging
|
||||
|
||||
@@ -46,9 +46,12 @@
|
||||
<user-service id="usernamePasswordService">
|
||||
<user name="test" password="test1" authorities="A,B,C" />
|
||||
</user-service>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
|
||||
<beans:bean id="noOpPasswordEncoder" class="org.springframework.security.crypto.password.NoOpPasswordEncoder"/>
|
||||
|
||||
<beans:bean id="UserNamePasswordAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
|
||||
<beans:property name="userDetailsService" ref="usernamePasswordService"/>
|
||||
<beans:property name="passwordEncoder" ref="noOpPasswordEncoder"/>
|
||||
</beans:bean>
|
||||
|
||||
<authentication-manager alias="authenticationManager">
|
||||
|
||||
@@ -18,9 +18,11 @@ timely:
|
||||
max-downsample-memory: 10000000
|
||||
security:
|
||||
session-max-age: 86400
|
||||
cache-expiration-minutes: 60
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
ssl:
|
||||
server-ssl:
|
||||
certificate-file: /timely-server-src/server/pki/timely.csr
|
||||
key-file: /timely-server-src/server/pki/timely-pkcs8.key
|
||||
key-password: password
|
||||
@@ -50,9 +52,9 @@ timely:
|
||||
timeout: 60
|
||||
subscription-lag: 120
|
||||
meta-cache:
|
||||
expiration-minutes: 60
|
||||
initial-capacity: 2000
|
||||
max-capacity: 10000
|
||||
expiration-minutes: 1440
|
||||
cache-refresh-minutes: 60
|
||||
max-tag-values: 100
|
||||
visibility-cache:
|
||||
expiration-minutes: 60
|
||||
initial-capacity: 2000
|
||||
|
||||
@@ -3,6 +3,8 @@ timely:
|
||||
meta-table: timely.meta
|
||||
metric-age-off-days:
|
||||
default: 7
|
||||
cache:
|
||||
enabled: false
|
||||
metrics-report-ignored-tags:
|
||||
accumulo:
|
||||
instance-name: TimelyStandalone
|
||||
@@ -18,9 +20,11 @@ timely:
|
||||
max-downsample-memory: 10000000
|
||||
security:
|
||||
session-max-age: 86400
|
||||
cache-expiration-minutes: 60
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
ssl:
|
||||
server-ssl:
|
||||
certificate-file:
|
||||
key-file:
|
||||
key-password: timely
|
||||
@@ -54,9 +58,9 @@ timely:
|
||||
scanner-read-ahead: 1
|
||||
subscription-batch-size: 5000
|
||||
meta-cache:
|
||||
expiration-minutes: 60
|
||||
initial-capacity: 2000
|
||||
max-capacity: 10000
|
||||
expiration-minutes: 1440
|
||||
cache-refresh-minutes: 60
|
||||
max-tag-values: 100
|
||||
visibility-cache:
|
||||
expiration-minutes: 60
|
||||
initial-capacity: 2000
|
||||
|
||||
@@ -23,9 +23,11 @@ timely:
|
||||
max-downsample-memory: 10000000
|
||||
security:
|
||||
session-max-age: 86400
|
||||
cache-expiration-minutes: 60
|
||||
cache-refresh-minutes: 5
|
||||
allow-anonymous-http-access: true
|
||||
allow-anonymous-ws-access: true
|
||||
serverSsl:
|
||||
server-ssl:
|
||||
certificate-file:
|
||||
key-file:
|
||||
key-password:
|
||||
@@ -60,10 +62,9 @@ timely:
|
||||
scanner-read-ahead: 1
|
||||
subscription-batch-size: 5000
|
||||
meta-cache:
|
||||
expiration-minutes: 60
|
||||
initial-capacity: 2000
|
||||
max-capacity: 10000
|
||||
expiration-minutes: 1440
|
||||
cache-refresh-minutes: 60
|
||||
max-tag-values: 100
|
||||
visibility-cache:
|
||||
expiration-minutes: 60
|
||||
initial-capacity: 2000
|
||||
max-capacity: 10000
|
||||
|
||||
+3
-39
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>1.2.1-SNAPSHOT</version>
|
||||
<version>1.2.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>timely-server</artifactId>
|
||||
<dependencies>
|
||||
@@ -149,9 +149,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative</artifactId>
|
||||
<version>${version.netty-tcnative}</version>
|
||||
<classifier>${os.detected.classifier}</classifier>
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -240,9 +238,8 @@
|
||||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative</artifactId>
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
<version>${version.netty-tcnative}</version>
|
||||
<classifier>${os.detected.classifier}</classifier>
|
||||
<type>jar</type>
|
||||
<overWrite>false</overWrite>
|
||||
<outputDirectory>${project.build.directory}/native</outputDirectory>
|
||||
@@ -284,37 +281,4 @@
|
||||
</extension>
|
||||
</extensions>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>native-epoll-linux</id>
|
||||
<activation>
|
||||
<os>
|
||||
<family>!mac</family>
|
||||
</os>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-epoll</artifactId>
|
||||
<version>${version.netty}</version>
|
||||
<classifier>linux-x86_64</classifier>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>native-epoll</id>
|
||||
<activation>
|
||||
<os>
|
||||
<family>mac</family>
|
||||
</os>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-epoll</artifactId>
|
||||
<version>${version.netty}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
@@ -24,6 +24,7 @@ import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.WriteBufferWaterMark;
|
||||
import io.netty.channel.epoll.EpollChannelOption;
|
||||
import io.netty.channel.epoll.EpollDatagramChannel;
|
||||
import io.netty.channel.epoll.EpollEventLoopGroup;
|
||||
@@ -44,6 +45,7 @@ import io.netty.handler.codec.http.HttpRequestDecoder;
|
||||
import io.netty.handler.codec.http.HttpResponseEncoder;
|
||||
import io.netty.handler.codec.http.HttpServerCodec;
|
||||
import io.netty.handler.codec.http.cors.CorsConfig;
|
||||
import io.netty.handler.codec.http.cors.CorsConfigBuilder;
|
||||
import io.netty.handler.codec.http.cors.CorsHandler;
|
||||
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
|
||||
import io.netty.handler.logging.LoggingHandler;
|
||||
@@ -70,6 +72,7 @@ import org.apache.zookeeper.CreateMode;
|
||||
import org.apache.zookeeper.data.Stat;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import timely.api.response.TimelyException;
|
||||
@@ -208,13 +211,13 @@ public class Server {
|
||||
payload.setWsPort(config.getWebsocket().getPort());
|
||||
payload.setUdpPort(config.getServer().getUdpPort());
|
||||
|
||||
ServiceInstanceBuilder builder = ServiceInstance.builder();
|
||||
ServiceInstanceBuilder<ServerDetails> builder = ServiceInstance.builder();
|
||||
String serviceName = host + ":" + config.getServer().getTcpPort();
|
||||
ServiceInstance serviceInstance = builder.id(serviceName).name("timely-server")
|
||||
ServiceInstance<ServerDetails> serviceInstance = builder.id(serviceName).name("timely-server")
|
||||
.address(config.getServer().getIp()).port(config.getServer().getTcpPort()).payload(payload).build();
|
||||
|
||||
ServiceDiscovery discovery = ServiceDiscoveryBuilder.builder(ServerDetails.class).client(curatorFramework)
|
||||
.basePath(SERVICE_DISCOVERY_PATH).build();
|
||||
ServiceDiscovery<ServerDetails> discovery = ServiceDiscoveryBuilder.builder(ServerDetails.class)
|
||||
.client(curatorFramework).basePath(SERVICE_DISCOVERY_PATH).build();
|
||||
discovery.start();
|
||||
discovery.registerService(serviceInstance);
|
||||
|
||||
@@ -250,7 +253,7 @@ public class Server {
|
||||
}
|
||||
|
||||
protected static Configuration initializeConfiguration(String[] args) {
|
||||
applicationContext = new SpringApplicationBuilder(SpringBootstrap.class).web(false).run(args);
|
||||
applicationContext = new SpringApplicationBuilder(SpringBootstrap.class).web(WebApplicationType.NONE).run(args);
|
||||
return applicationContext.getBean(Configuration.class);
|
||||
}
|
||||
|
||||
@@ -430,7 +433,7 @@ public class Server {
|
||||
// Initialize the MetaCache
|
||||
MetaCacheFactory.getCache(config);
|
||||
// initialize the auth cache
|
||||
AuthCache.setSessionMaxAge(config.getSecurity());
|
||||
AuthCache.configure(config.getSecurity());
|
||||
// Initialize the VisibilityCache
|
||||
VisibilityCache.init(config);
|
||||
final boolean useEpoll = useEpoll();
|
||||
@@ -507,10 +510,9 @@ public class Server {
|
||||
wsServer.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
|
||||
wsServer.option(ChannelOption.SO_BACKLOG, 128);
|
||||
wsServer.option(ChannelOption.SO_KEEPALIVE, true);
|
||||
/* Not sure if next three lines are necessary */
|
||||
/* Not sure if next two lines are necessary */
|
||||
wsServer.option(ChannelOption.SO_SNDBUF, 1048576);
|
||||
wsServer.option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 838860);
|
||||
wsServer.option(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 620145);
|
||||
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();
|
||||
|
||||
@@ -590,11 +592,11 @@ public class Server {
|
||||
ch.pipeline().addLast("aggregator", new HttpObjectAggregator(65536));
|
||||
ch.pipeline().addLast("chunker", new ChunkedWriteHandler());
|
||||
final Cors corsCfg = config.getHttp().getCors();
|
||||
final CorsConfig.Builder ccb;
|
||||
final CorsConfigBuilder ccb;
|
||||
if (corsCfg.isAllowAnyOrigin()) {
|
||||
ccb = new CorsConfig.Builder();
|
||||
ccb = CorsConfigBuilder.forAnyOrigin();
|
||||
} else {
|
||||
ccb = new CorsConfig.Builder(corsCfg.getAllowedOrigins().stream().toArray(String[]::new));
|
||||
ccb = CorsConfigBuilder.forOrigins(corsCfg.getAllowedOrigins().stream().toArray(String[]::new));
|
||||
}
|
||||
if (corsCfg.isAllowNullOrigin()) {
|
||||
ccb.allowNullOrigin();
|
||||
@@ -667,7 +669,7 @@ public class Server {
|
||||
ch.pipeline().addLast("sessionExtractor", new WebSocketFullRequestHandler());
|
||||
ch.pipeline().addLast("idle-handler", new IdleStateHandler(conf.getWebsocket().getTimeout(), 0, 0));
|
||||
ch.pipeline().addLast("ws-protocol",
|
||||
new WebSocketServerProtocolHandler(WS_PATH, null, true, 65536, true));
|
||||
new WebSocketServerProtocolHandler(WS_PATH, null, true, 65536, false, true));
|
||||
ch.pipeline().addLast("wsDecoder", new WebSocketRequestDecoder(config.getSecurity()));
|
||||
ch.pipeline().addLast("aggregators", new WSAggregatorsRequestHandler());
|
||||
ch.pipeline().addLast("metrics", new WSMetricsRequestHandler(config));
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package timely.adapter.accumulo;
|
||||
|
||||
import org.apache.accumulo.core.data.Key;
|
||||
import timely.api.model.Meta;
|
||||
import timely.model.Metric;
|
||||
|
||||
/**
|
||||
* Creates Accumulo data structures from {@link Metric}
|
||||
*/
|
||||
public class MetaAdapter {
|
||||
|
||||
public static Key createMetricKey(String metricName, Long timestamp) {
|
||||
return new Key(Meta.METRIC_PREFIX + metricName, "", "", timestamp);
|
||||
}
|
||||
|
||||
public static Key createTagKey(String metricName, String tagName, Long timestamp) {
|
||||
return new Key(Meta.TAG_PREFIX + metricName, tagName, "", timestamp);
|
||||
}
|
||||
|
||||
public static Key createValueKey(String metricName, String tagName, String tagValue, Long timestamp) {
|
||||
return new Key(Meta.VALUE_PREFIX + metricName, tagName, tagValue, timestamp);
|
||||
}
|
||||
|
||||
public static Meta parse(Key key) {
|
||||
String row = key.getRow().toString();
|
||||
if (row.startsWith(Meta.METRIC_PREFIX)) {
|
||||
return Meta.parse(key, null, Meta.METRIC_PREFIX);
|
||||
} else if (row.startsWith(Meta.TAG_PREFIX)) {
|
||||
return Meta.parse(key, null, Meta.TAG_PREFIX);
|
||||
} else if (row.startsWith(Meta.VALUE_PREFIX)) {
|
||||
return Meta.parse(key, null, Meta.VALUE_PREFIX);
|
||||
}
|
||||
throw new IllegalStateException("Invalid key in meta " + key.toString());
|
||||
}
|
||||
|
||||
public static String decodeRowKey(Key key) {
|
||||
return parse(key).getMetric();
|
||||
}
|
||||
}
|
||||
@@ -55,16 +55,43 @@ public class Meta implements Comparable<Meta> {
|
||||
return keys;
|
||||
}
|
||||
|
||||
public static Meta parse(Key k, Value v) {
|
||||
public static String prefix(Key key) {
|
||||
String row = key.getRow().toString();
|
||||
if (row.startsWith(Meta.METRIC_PREFIX)) {
|
||||
return Meta.METRIC_PREFIX;
|
||||
} else if (row.startsWith(Meta.TAG_PREFIX)) {
|
||||
return Meta.TAG_PREFIX;
|
||||
} else if (row.startsWith(Meta.VALUE_PREFIX)) {
|
||||
return Meta.VALUE_PREFIX;
|
||||
}
|
||||
throw new IllegalStateException("Invalid key in meta " + key.toString());
|
||||
}
|
||||
|
||||
public static Meta parse(Key key) {
|
||||
return parse(key, null);
|
||||
}
|
||||
|
||||
public static Meta parse(Key key, Value value) {
|
||||
String row = key.getRow().toString();
|
||||
if (row.startsWith(Meta.METRIC_PREFIX)) {
|
||||
return Meta.parse(key, value, Meta.METRIC_PREFIX);
|
||||
} else if (row.startsWith(Meta.TAG_PREFIX)) {
|
||||
return Meta.parse(key, value, Meta.TAG_PREFIX);
|
||||
} else if (row.startsWith(Meta.VALUE_PREFIX)) {
|
||||
return Meta.parse(key, value, Meta.VALUE_PREFIX);
|
||||
}
|
||||
throw new IllegalStateException("Invalid key in meta " + key.toString());
|
||||
}
|
||||
|
||||
public static Meta parse(Key k, Value v, String prefix) {
|
||||
if (k.getColumnQualifier().getLength() > 0) {
|
||||
return new Meta(k.getRow().toString().substring(METRIC_PREFIX.length()), k.getColumnFamily().toString(),
|
||||
return new Meta(k.getRow().toString().substring(prefix.length()), k.getColumnFamily().toString(),
|
||||
k.getColumnQualifier().toString());
|
||||
} else if (k.getColumnFamily().getLength() > 0) {
|
||||
return new Meta(k.getRow().toString().substring(METRIC_PREFIX.length()), k.getColumnFamily().toString(),
|
||||
null);
|
||||
return new Meta(k.getRow().toString().substring(prefix.length()), k.getColumnFamily().toString(), null);
|
||||
|
||||
} else {
|
||||
return new Meta(k.getRow().toString().substring(METRIC_PREFIX.length()), null, null);
|
||||
return new Meta(k.getRow().toString().substring(prefix.length()), null, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ public interface TcpRequest extends Request {
|
||||
|
||||
/**
|
||||
* Parse a line of text received and populate this object
|
||||
*
|
||||
* @param line
|
||||
*/
|
||||
public void parse(String line);
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@ public interface UdpRequest {
|
||||
|
||||
/**
|
||||
* Parse a line of text received and populate this object
|
||||
*
|
||||
* @param line
|
||||
*/
|
||||
public void parse(String line);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
|
||||
@@ -129,8 +129,8 @@ public class MetricsResponse {
|
||||
}
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
|
||||
Unpooled.copiedBuffer(buf));
|
||||
response.headers().set(Names.CONTENT_TYPE, responseType);
|
||||
response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, responseType);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,32 +23,67 @@ public class AuthCache {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AuthCache.class);
|
||||
private static Cache<String, TimelyPrincipal> CACHE = null;
|
||||
|
||||
private static int sessionMaxAge = -1;
|
||||
private static int cacheExpirationMinutes = -1;
|
||||
private static int cacheRefreshMinutes = -1;
|
||||
|
||||
/**
|
||||
* For tests only
|
||||
*/
|
||||
public static void resetSessionMaxAge() {
|
||||
sessionMaxAge = -1;
|
||||
public static void resetConfiguration() {
|
||||
cacheExpirationMinutes = -1;
|
||||
cacheRefreshMinutes = -1;
|
||||
}
|
||||
|
||||
public static void setSessionMaxAge(Security security) {
|
||||
if (-1 != sessionMaxAge) {
|
||||
throw new IllegalStateException("Cache session max age already configured.");
|
||||
public static void configure(Security security) {
|
||||
if (-1 != cacheExpirationMinutes || -1 != cacheRefreshMinutes) {
|
||||
throw new IllegalStateException("Cache already configured.");
|
||||
}
|
||||
sessionMaxAge = security.getSessionMaxAge();
|
||||
cacheExpirationMinutes = security.getCacheExpirationMinutes();
|
||||
cacheRefreshMinutes = security.getCacheRefreshMinutes();
|
||||
}
|
||||
|
||||
private static Cache<String, TimelyPrincipal> getCache() {
|
||||
if (-1 == sessionMaxAge) {
|
||||
if (-1 == cacheExpirationMinutes) {
|
||||
throw new IllegalStateException("Cache session max age not configured.");
|
||||
}
|
||||
if (null == CACHE) {
|
||||
CACHE = Caffeine.newBuilder().expireAfterAccess(sessionMaxAge, TimeUnit.SECONDS).build();
|
||||
Caffeine<Object, Object> caffeine = Caffeine.newBuilder();
|
||||
caffeine.expireAfterWrite(cacheExpirationMinutes, TimeUnit.MINUTES);
|
||||
if (cacheRefreshMinutes > 0) {
|
||||
caffeine.refreshAfterWrite(cacheRefreshMinutes, TimeUnit.MINUTES);
|
||||
CACHE = caffeine.build(key -> getTimelyPrincipal(key));
|
||||
} else {
|
||||
CACHE = caffeine.build();
|
||||
}
|
||||
}
|
||||
return CACHE;
|
||||
}
|
||||
|
||||
private static TimelyPrincipal getTimelyPrincipal(String key) {
|
||||
LOG.debug("Refreshing TimelyPrincipal {}", key);
|
||||
TimelyPrincipal timelyPrincipal = null;
|
||||
String[] dnArray = key.split(" -> ");
|
||||
if (dnArray.length == 1) {
|
||||
SubjectIssuerDNPair pair = SubjectIssuerDNPair.parse(dnArray[0]);
|
||||
TimelyAuthenticationToken token = AuthenticationService.getAuthenticationToken(new Object(),
|
||||
pair.subjectDN(), pair.issuerDN());
|
||||
timelyPrincipal = AuthenticationService.authenticate(token, pair, token.getTimelyPrincipal().getName(),
|
||||
false);
|
||||
} else if (dnArray.length > 1) {
|
||||
Collection<TimelyUser> timelyUsers = new ArrayList<>();
|
||||
for (String s : dnArray) {
|
||||
SubjectIssuerDNPair pair = SubjectIssuerDNPair.parse(s);
|
||||
TimelyAuthenticationToken token = AuthenticationService.getAuthenticationToken(new Object(),
|
||||
pair.subjectDN(), pair.issuerDN());
|
||||
TimelyPrincipal p = AuthenticationService.authenticate(token, pair,
|
||||
token.getTimelyPrincipal().getName(), false);
|
||||
timelyUsers.addAll(p.getProxiedUsers());
|
||||
}
|
||||
timelyPrincipal = new TimelyPrincipal(timelyUsers);
|
||||
}
|
||||
return timelyPrincipal;
|
||||
}
|
||||
|
||||
public static boolean containsKey(String key) {
|
||||
return getCache().getIfPresent(key) != null;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.authentication.preauth.x509.SubjectDnX509PrincipalExtractor;
|
||||
import timely.api.request.AuthenticatedRequest;
|
||||
import timely.api.response.TimelyException;
|
||||
import timely.auth.util.DnUtils;
|
||||
@@ -35,7 +34,6 @@ public class AuthenticationService {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AuthenticationService.class);
|
||||
private static ApplicationContext springContext = null;
|
||||
private static AuthenticationManager authManager = null;
|
||||
private static SubjectDnX509PrincipalExtractor x509 = null;
|
||||
private static ConcurrentHashMap<String, Object> fetchingEntity = new ConcurrentHashMap<>();
|
||||
private static ConcurrentHashMap<String, Object> fetchingPrincipal = new ConcurrentHashMap<>();
|
||||
private static Collection<String> requiredRoles;
|
||||
@@ -45,10 +43,13 @@ public class AuthenticationService {
|
||||
try {
|
||||
springContext = new ClassPathXmlApplicationContext("security.xml");
|
||||
authManager = springContext.getBean("authenticationManager", AuthenticationManager.class);
|
||||
x509 = springContext.getBean("x509PrincipalExtractor", SubjectDnX509PrincipalExtractor.class);
|
||||
requiredRoles = springContext.getBean("requiredRoles", List.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> uncheckedRoles = springContext.getBean("requiredRoles", List.class);
|
||||
requiredRoles = uncheckedRoles;
|
||||
requiredRoles.removeIf(String::isEmpty);
|
||||
requiredAuths = springContext.getBean("requiredAuths", List.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> uncheckedAuths = springContext.getBean("requiredAuths", List.class);
|
||||
requiredAuths = uncheckedAuths;
|
||||
requiredAuths.removeIf(String::isEmpty);
|
||||
} catch (BeansException e) {
|
||||
throw new ServiceConfigurationError("Error setting up Authentication objects: " + e.getMessage(),
|
||||
@@ -65,9 +66,17 @@ public class AuthenticationService {
|
||||
}
|
||||
|
||||
public static TimelyPrincipal authenticate(Authentication authentication, SubjectIssuerDNPair pair, String entity) {
|
||||
return authenticate(authentication, pair, entity, true);
|
||||
}
|
||||
|
||||
public static TimelyPrincipal authenticate(Authentication authentication, SubjectIssuerDNPair pair, String entity,
|
||||
boolean useCache) {
|
||||
|
||||
// only one thread should call the authenticationManager for a given entity
|
||||
TimelyPrincipal principal = AuthCache.get(entity);
|
||||
TimelyPrincipal principal = null;
|
||||
if (useCache) {
|
||||
principal = AuthCache.get(entity);
|
||||
}
|
||||
// once an entity is in the AuthCache, we can bypass all of this
|
||||
if (principal == null) {
|
||||
Object newObj = new Object();
|
||||
@@ -79,12 +88,16 @@ public class AuthenticationService {
|
||||
synchronized (o) {
|
||||
// if multiple threads are waiting on this synchronized, then the 2nd and all
|
||||
// others will get the principal here
|
||||
principal = AuthCache.get(entity);
|
||||
if (useCache) {
|
||||
principal = AuthCache.get(entity);
|
||||
}
|
||||
if (principal == null) {
|
||||
Authentication token = getAuthenticationManager().authenticate(authentication);
|
||||
principal = getTimelyPrincipal(token, pair);
|
||||
LOG.trace("Got entity principal for {} from AuthenticationManager", entity);
|
||||
AuthCache.put(entity, principal);
|
||||
if (useCache) {
|
||||
AuthCache.put(entity, principal);
|
||||
}
|
||||
} else {
|
||||
LOG.trace("Got entity principal for {} from AuthCache on 2nd attempt", entity);
|
||||
}
|
||||
@@ -232,7 +245,7 @@ public class AuthenticationService {
|
||||
return authenticationToken;
|
||||
}
|
||||
|
||||
public static TimelyAuthenticationToken getAuthenticationToken(X509Certificate clientCert, String subjectDn,
|
||||
public static TimelyAuthenticationToken getAuthenticationToken(Object clientCert, String subjectDn,
|
||||
String issuerDn) {
|
||||
TimelyAuthenticationToken authenticationToken = null;
|
||||
try {
|
||||
|
||||
@@ -16,8 +16,6 @@ import org.apache.accumulo.core.data.Value;
|
||||
import org.apache.accumulo.core.data.thrift.IterInfo;
|
||||
import org.apache.accumulo.core.security.Authorizations;
|
||||
import org.apache.hadoop.io.Text;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* A simple wrapper around a {@link ScannerBase} that overrides the methods that
|
||||
@@ -27,7 +25,6 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
public class ScannerBaseDelegate implements ScannerBase {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ScannerBaseDelegate.class);
|
||||
private static final String SYSTEM_ITERATOR_NAME_PREFIX = "sys_";
|
||||
|
||||
protected final ScannerBase delegate;
|
||||
@@ -139,10 +136,11 @@ public class ScannerBaseDelegate implements ScannerBase {
|
||||
@Override
|
||||
public void clearScanIterators() {
|
||||
if (delegate instanceof ScannerOptions) {
|
||||
ScannerOptionsHelper opts = new ScannerOptionsHelper((ScannerOptions) delegate);
|
||||
for (IteratorSetting iteratorSetting : opts.getIterators()) {
|
||||
if (!iteratorSetting.getName().startsWith(SYSTEM_ITERATOR_NAME_PREFIX)) {
|
||||
delegate.removeScanIterator(iteratorSetting.getName());
|
||||
try (ScannerOptionsHelper opts = new ScannerOptionsHelper((ScannerOptions) delegate)) {
|
||||
for (IteratorSetting iteratorSetting : opts.getIterators()) {
|
||||
if (!iteratorSetting.getName().startsWith(SYSTEM_ITERATOR_NAME_PREFIX)) {
|
||||
delegate.removeScanIterator(iteratorSetting.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -13,6 +13,7 @@ import timely.auth.util.ProxiedEntityUtils;
|
||||
*/
|
||||
public class SubjectIssuerDNPair implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String subjectDN;
|
||||
private final String issuerDN;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import timely.auth.util.DnUtils;
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
public class TimelyPrincipal implements Principal, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String username;
|
||||
private final TimelyUser primaryUser;
|
||||
@XmlElement
|
||||
@@ -103,7 +104,7 @@ public class TimelyPrincipal implements Principal, Serializable {
|
||||
|
||||
public Set<String> getProxyServers() {
|
||||
|
||||
// @formatter:off
|
||||
// @formatter:off
|
||||
Set<String> proxyServers = getProxiedUsers().stream()
|
||||
.filter(u -> u.getUserType() == TimelyUser.UserType.SERVER)
|
||||
.map(TimelyUser::getDn)
|
||||
|
||||
@@ -20,6 +20,8 @@ import timely.auth.util.DnUtils;
|
||||
*/
|
||||
public class TimelyUser implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public enum UserType {
|
||||
USER, SERVER
|
||||
}
|
||||
|
||||
@@ -13,7 +13,9 @@ public class HttpHeaderUtils {
|
||||
Multimap<String, String> headerMultimap = HashMultimap.create();
|
||||
if (headers != null) {
|
||||
for (Map.Entry<String, String> e : headers.entries()) {
|
||||
headerMultimap.put(e.getKey(), e.getValue());
|
||||
// lower case for HTTP/2 compatibility; even for HTTP/1, these were always
|
||||
// case-insensitive
|
||||
headerMultimap.put(e.getKey().toLowerCase(), e.getValue());
|
||||
}
|
||||
}
|
||||
return headerMultimap;
|
||||
@@ -22,6 +24,9 @@ public class HttpHeaderUtils {
|
||||
public static String getSingleHeader(Multimap<String, String> headers, String headerName, boolean enforceOneValue)
|
||||
throws IllegalArgumentException {
|
||||
String value = null;
|
||||
// lower case for HTTP/2 compatibility; even for HTTP/1, these were always
|
||||
// case-insensitive
|
||||
headerName = headerName.toLowerCase();
|
||||
Collection<String> values = (headers == null) ? null : headers.get(headerName);
|
||||
if (values != null && !values.isEmpty()) {
|
||||
if (values.size() > 1 && enforceOneValue) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package timely.configuration;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
import org.hibernate.validator.constraints.NotBlank;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
|
||||
public class Accumulo {
|
||||
|
||||
@@ -9,7 +9,9 @@ import javax.validation.Valid;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@Validated
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "timely")
|
||||
public class Configuration {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package timely.configuration;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.hibernate.validator.constraints.NotBlank;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
|
||||
public class Http {
|
||||
|
||||
@@ -2,9 +2,9 @@ package timely.configuration;
|
||||
|
||||
public class MetaCache {
|
||||
|
||||
private long expirationMinutes = 60;
|
||||
private int initialCapacity = 2000;
|
||||
private long maxCapacity = 10000;
|
||||
private long expirationMinutes = 1440;
|
||||
private int cacheRefreshMinutes = -1;
|
||||
private long maxTagValues = 100;
|
||||
|
||||
public long getExpirationMinutes() {
|
||||
return expirationMinutes;
|
||||
@@ -14,19 +14,19 @@ public class MetaCache {
|
||||
this.expirationMinutes = expirationMinutes;
|
||||
}
|
||||
|
||||
public int getInitialCapacity() {
|
||||
return initialCapacity;
|
||||
public void setCacheRefreshMinutes(int cacheRefreshMinutes) {
|
||||
this.cacheRefreshMinutes = cacheRefreshMinutes;
|
||||
}
|
||||
|
||||
public void setInitialCapacity(int initialCapacity) {
|
||||
this.initialCapacity = initialCapacity;
|
||||
public int getCacheRefreshMinutes() {
|
||||
return cacheRefreshMinutes;
|
||||
}
|
||||
|
||||
public long getMaxCapacity() {
|
||||
return maxCapacity;
|
||||
public long getMaxTagValues() {
|
||||
return maxTagValues;
|
||||
}
|
||||
|
||||
public void setMaxCapacity(long maxCapacity) {
|
||||
this.maxCapacity = maxCapacity;
|
||||
public void setMaxTagValues(long maxTagValues) {
|
||||
this.maxTagValues = maxTagValues;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ public class Security {
|
||||
private boolean allowAnonymousHttpAccess = false;
|
||||
private boolean allowAnonymousWsAccess = false;
|
||||
private int sessionMaxAge = 86400;
|
||||
private int cacheExpirationMinutes = 60;
|
||||
private int cacheRefreshMinutes = 5;
|
||||
@Valid
|
||||
@NestedConfigurationProperty
|
||||
private ServerSsl serverSsl = new ServerSsl();
|
||||
@@ -37,6 +39,22 @@ public class Security {
|
||||
this.sessionMaxAge = sessionMaxAge;
|
||||
}
|
||||
|
||||
public void setCacheExpirationMinutes(int cacheExpirationMinutes) {
|
||||
this.cacheExpirationMinutes = cacheExpirationMinutes;
|
||||
}
|
||||
|
||||
public int getCacheExpirationMinutes() {
|
||||
return cacheExpirationMinutes;
|
||||
}
|
||||
|
||||
public void setCacheRefreshMinutes(int cacheRefreshMinutes) {
|
||||
this.cacheRefreshMinutes = cacheRefreshMinutes;
|
||||
}
|
||||
|
||||
public int getCacheRefreshMinutes() {
|
||||
return cacheRefreshMinutes;
|
||||
}
|
||||
|
||||
public ServerSsl getServerSsl() {
|
||||
return serverSsl;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package timely.configuration;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.hibernate.validator.constraints.NotBlank;
|
||||
|
||||
public class Server {
|
||||
|
||||
@NotBlank
|
||||
@@ -42,8 +41,6 @@ public class Server {
|
||||
/**
|
||||
* Time to wait (in seconds) for connections to finish and to make sure no new
|
||||
* connections happen before shutting down Netty event loop groups.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getShutdownQuietPeriod() {
|
||||
return this.shutdownQuietPeriod;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package timely.configuration;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.hibernate.validator.constraints.NotBlank;
|
||||
|
||||
public class Websocket {
|
||||
|
||||
@NotBlank
|
||||
|
||||
@@ -5,7 +5,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import timely.api.request.CacheRequest;
|
||||
@@ -35,8 +35,8 @@ public class HttpCacheRequestHandler extends SimpleChannelInboundHandler<CacheRe
|
||||
}
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
|
||||
Unpooled.copiedBuffer(buf));
|
||||
response.headers().set(Names.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
|
||||
sendResponse(ctx, response);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import org.slf4j.Logger;
|
||||
@@ -35,8 +35,8 @@ public class HttpMetricPutHandler extends SimpleChannelInboundHandler<MetricRequ
|
||||
}
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
|
||||
Unpooled.EMPTY_BUFFER);
|
||||
response.headers().set(Names.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
|
||||
sendResponse(ctx, response);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.QueryStringDecoder;
|
||||
@@ -52,7 +52,7 @@ public class HttpRequestDecoder extends MessageToMessageDecoder<FullHttpRequest>
|
||||
|
||||
public static String getSessionId(FullHttpRequest msg) {
|
||||
Multimap<String, String> headers = HttpHeaderUtils.toMultimap(msg.headers());
|
||||
Collection<String> cookies = headers.get(Names.COOKIE);
|
||||
Collection<String> cookies = headers.get(HttpHeaderNames.COOKIE.toString());
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
cookies.forEach(h -> {
|
||||
ServerCookieDecoder.STRICT.decode(h).forEach(c -> {
|
||||
@@ -75,7 +75,7 @@ public class HttpRequestDecoder extends MessageToMessageDecoder<FullHttpRequest>
|
||||
|
||||
LOG.trace(LOG_RECEIVED_REQUEST, msg);
|
||||
|
||||
final String uri = msg.getUri();
|
||||
final String uri = msg.uri();
|
||||
final QueryStringDecoder decoder = new QueryStringDecoder(uri);
|
||||
if (decoder.path().equals(nonSecureRedirectAddress)) {
|
||||
out.add(new StrictTransportResponse());
|
||||
@@ -87,10 +87,10 @@ public class HttpRequestDecoder extends MessageToMessageDecoder<FullHttpRequest>
|
||||
|
||||
HttpRequest request;
|
||||
try {
|
||||
if (msg.getMethod().equals(HttpMethod.GET)) {
|
||||
if (msg.method().equals(HttpMethod.GET)) {
|
||||
HttpGetRequest get = AnnotationResolver.getClassForHttpGet(decoder.path());
|
||||
request = get.parseQueryParameters(decoder);
|
||||
} else if (msg.getMethod().equals(HttpMethod.POST)) {
|
||||
} else if (msg.method().equals(HttpMethod.POST)) {
|
||||
HttpPostRequest post = AnnotationResolver.getClassForHttpPost(decoder.path());
|
||||
String content = "";
|
||||
ByteBuf body = msg.content();
|
||||
@@ -101,8 +101,9 @@ public class HttpRequestDecoder extends MessageToMessageDecoder<FullHttpRequest>
|
||||
} else {
|
||||
TimelyException e = new TimelyException(HttpResponseStatus.METHOD_NOT_ALLOWED.code(),
|
||||
"unhandled method type", "");
|
||||
e.addResponseHeader(Names.ALLOW, HttpMethod.GET.name() + "," + HttpMethod.POST.name());
|
||||
LOG.warn("Unhandled HTTP request type {}", msg.getMethod());
|
||||
e.addResponseHeader(HttpHeaderNames.ALLOW.toString(),
|
||||
HttpMethod.GET.name() + "," + HttpMethod.POST.name());
|
||||
LOG.warn("Unhandled HTTP request type {}", msg.method());
|
||||
throw e;
|
||||
}
|
||||
if (request instanceof AuthenticatedRequest) {
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
*/
|
||||
package timely.netty.http;
|
||||
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CACHE_CONTROL;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.DATE;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.EXPIRES;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.IF_MODIFIED_SINCE;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.LAST_MODIFIED;
|
||||
import static io.netty.handler.codec.http.HttpHeaders.Names.LOCATION;
|
||||
import static io.netty.handler.codec.http.HttpHeaderNames.CACHE_CONTROL;
|
||||
import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION;
|
||||
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE;
|
||||
import static io.netty.handler.codec.http.HttpHeaderNames.DATE;
|
||||
import static io.netty.handler.codec.http.HttpHeaderNames.EXPIRES;
|
||||
import static io.netty.handler.codec.http.HttpHeaderNames.IF_MODIFIED_SINCE;
|
||||
import static io.netty.handler.codec.http.HttpHeaderNames.LAST_MODIFIED;
|
||||
import static io.netty.handler.codec.http.HttpHeaderNames.LOCATION;
|
||||
import static io.netty.handler.codec.http.HttpMethod.GET;
|
||||
import static io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
|
||||
import static io.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN;
|
||||
@@ -59,9 +59,10 @@ import io.netty.handler.codec.http.DefaultHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpChunkedInput;
|
||||
import io.netty.handler.codec.http.HttpHeaders;
|
||||
import io.netty.handler.codec.http.HttpHeaderValues;
|
||||
import io.netty.handler.codec.http.HttpResponse;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpUtil;
|
||||
import io.netty.handler.stream.ChunkedFile;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import io.netty.util.internal.SystemPropertyUtil;
|
||||
@@ -94,7 +95,7 @@ import timely.netty.Constants;
|
||||
* Request #1 Headers
|
||||
* ===================
|
||||
* GET /file1.txt HTTP/1.1
|
||||
*
|
||||
*
|
||||
* Response #1 Headers
|
||||
* ===================
|
||||
* HTTP/1.1 200 OK
|
||||
@@ -102,12 +103,12 @@ import timely.netty.Constants;
|
||||
* Last-Modified: Wed, 30 Jun 2010 21:36:48 GMT
|
||||
* Expires: Tue, 01 Mar 2012 22:44:26 GMT
|
||||
* Cache-Control: private, max-age=31536000
|
||||
*
|
||||
*
|
||||
* Request #2 Headers
|
||||
* ===================
|
||||
* GET /file1.txt HTTP/1.1
|
||||
* If-Modified-Since: Wed, 30 Jun 2010 21:36:48 GMT
|
||||
*
|
||||
*
|
||||
* Response #2 Headers
|
||||
* ===================
|
||||
* HTTP/1.1 304 Not Modified
|
||||
@@ -125,17 +126,17 @@ public class HttpStaticFileServerHandler extends SimpleChannelInboundHandler<Ful
|
||||
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
|
||||
if (!request.getDecoderResult().isSuccess()) {
|
||||
if (!request.decoderResult().isSuccess()) {
|
||||
sendError(ctx, BAD_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
if (request.getMethod() != GET) {
|
||||
if (request.method() != GET) {
|
||||
sendError(ctx, METHOD_NOT_ALLOWED);
|
||||
return;
|
||||
}
|
||||
|
||||
String uri = request.getUri();
|
||||
String uri = request.uri();
|
||||
if (uri.startsWith("/favicon.ico")) {
|
||||
uri = uri.replaceFirst("\\/", "/webapp/");
|
||||
}
|
||||
@@ -201,12 +202,12 @@ public class HttpStaticFileServerHandler extends SimpleChannelInboundHandler<Ful
|
||||
long fileLength = raf.length();
|
||||
|
||||
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
|
||||
HttpHeaders.setContentLength(response, fileLength);
|
||||
HttpUtil.setContentLength(response, fileLength);
|
||||
setContentTypeHeader(response, file);
|
||||
setDateAndCacheHeaders(response, file);
|
||||
HttpHeaders.setTransferEncodingChunked(response);
|
||||
if (HttpHeaders.isKeepAlive(request)) {
|
||||
response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
|
||||
HttpUtil.setTransferEncodingChunked(response, true);
|
||||
if (HttpUtil.isKeepAlive(request)) {
|
||||
response.headers().set(CONNECTION, HttpHeaderValues.KEEP_ALIVE);
|
||||
}
|
||||
|
||||
// Write the initial line and the header.
|
||||
|
||||
@@ -7,7 +7,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import timely.api.request.VersionRequest;
|
||||
@@ -20,8 +20,8 @@ public class HttpVersionRequestHandler extends SimpleChannelInboundHandler<Versi
|
||||
protected void channelRead0(ChannelHandlerContext ctx, VersionRequest v) throws Exception {
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
|
||||
Unpooled.copiedBuffer(VersionRequest.VERSION.getBytes(StandardCharsets.UTF_8)));
|
||||
response.headers().set(Names.CONTENT_TYPE, Constants.TEXT_TYPE);
|
||||
response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, Constants.TEXT_TYPE);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
|
||||
sendResponse(ctx, response);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpResponseEncoder;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
@@ -51,7 +51,7 @@ public class NonSslRedirectHandler extends OptionalSslHandler implements TimelyH
|
||||
LOG.trace("Received non-SSL request, returning redirect");
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
|
||||
HttpResponseStatus.MOVED_PERMANENTLY, Unpooled.EMPTY_BUFFER);
|
||||
response.headers().set(Names.LOCATION, redirectAddress);
|
||||
response.headers().set(HttpHeaderNames.LOCATION, redirectAddress);
|
||||
LOG.trace(Constants.LOG_RETURNING_RESPONSE, response);
|
||||
encoder.write(ctx, response, ctx.voidPromise());
|
||||
ctx.flush();
|
||||
|
||||
@@ -6,7 +6,7 @@ import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import org.slf4j.Logger;
|
||||
@@ -25,8 +25,8 @@ public interface TimelyHttpHandler {
|
||||
.writeValueAsBytes("ResponseCode: " + e.getCode() + " Message: " + e.getMessage());
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
|
||||
HttpResponseStatus.valueOf(e.getCode()), Unpooled.copiedBuffer(buf));
|
||||
response.headers().set(Names.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
|
||||
e.getResponseHeaders().entrySet().forEach(entry -> response.headers().set(entry.getKey(), entry.getValue()));
|
||||
// Send the error response
|
||||
sendResponse(ctx, response);
|
||||
|
||||
@@ -17,24 +17,26 @@ import timely.auth.util.HttpHeaderUtils;
|
||||
|
||||
public class TimelyAuthenticationToken extends PreAuthenticatedAuthenticationToken {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TimelyAuthenticationToken.class);
|
||||
public static final String PROXIED_ENTITIES_HEADER = "X-ProxiedEntitiesChain";
|
||||
public static final String PROXIED_ISSUERS_HEADER = "X-ProxiedIssuersChain";
|
||||
public static final String PROXIED_ENTITIES_HEADER = "x-proxiedentitieschain";
|
||||
public static final String PROXIED_ISSUERS_HEADER = "x-proxiedissuerschain";
|
||||
|
||||
private Multimap<String, String> httpHeaders = null;
|
||||
private X509Certificate clientCert;
|
||||
private X509Certificate clientCert = null;
|
||||
private TimelyPrincipal timelyPrincipal;
|
||||
|
||||
public TimelyAuthenticationToken(String subjectDn, X509Certificate clientCert,
|
||||
Multimap<String, String> httpHeaders) {
|
||||
public TimelyAuthenticationToken(String subjectDn, Object clientCert, Multimap<String, String> httpHeaders) {
|
||||
super(subjectDn, clientCert);
|
||||
if (httpHeaders == null) {
|
||||
this.httpHeaders = HashMultimap.create();
|
||||
} else {
|
||||
this.httpHeaders = httpHeaders;
|
||||
}
|
||||
this.clientCert = clientCert;
|
||||
String issuerDn = clientCert == null ? null : clientCert.getIssuerDN().getName();
|
||||
if (clientCert instanceof X509Certificate) {
|
||||
this.clientCert = (X509Certificate) clientCert;
|
||||
}
|
||||
String issuerDn = clientCert == null ? null : this.clientCert.getIssuerDN().getName();
|
||||
String proxiedEntities;
|
||||
String proxiedIssuers;
|
||||
try {
|
||||
@@ -61,9 +63,11 @@ public class TimelyAuthenticationToken extends PreAuthenticatedAuthenticationTok
|
||||
LOG.trace("Created TimelyAuthenticationToken: {}", timelyPrincipal.getName());
|
||||
}
|
||||
|
||||
public TimelyAuthenticationToken(String subjectDn, String issuerDn, X509Certificate clientCert) {
|
||||
public TimelyAuthenticationToken(String subjectDn, String issuerDn, Object clientCert) {
|
||||
super(subjectDn, clientCert);
|
||||
this.clientCert = clientCert;
|
||||
if (clientCert instanceof X509Certificate) {
|
||||
this.clientCert = (X509Certificate) clientCert;
|
||||
}
|
||||
TimelyUser.UserType userType = DnUtils.isServerDN(subjectDn) ? TimelyUser.UserType.SERVER
|
||||
: TimelyUser.UserType.USER;
|
||||
TimelyUser timelyUser = new TimelyUser(SubjectIssuerDNPair.of(subjectDn, issuerDn), userType, null, null, null,
|
||||
|
||||
@@ -8,7 +8,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.cookie.DefaultCookie;
|
||||
@@ -43,22 +43,22 @@ public abstract class TimelyLoginRequestHandler<T> extends SimpleChannelInboundH
|
||||
principal.getPrimaryUser().getDn().subjectDN());
|
||||
String sessionIdEncoded = URLEncoder.encode(sessionId, StandardCharsets.UTF_8.name());
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
|
||||
response.headers().set(Names.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
|
||||
DefaultCookie cookie = new DefaultCookie(Constants.COOKIE_NAME, sessionIdEncoded);
|
||||
cookie.setDomain(domain);
|
||||
cookie.setMaxAge(maxAge);
|
||||
cookie.setPath("/");
|
||||
cookie.setHttpOnly(true);
|
||||
cookie.setSecure(true);
|
||||
response.headers().set(Names.SET_COOKIE, ServerCookieEncoder.STRICT.encode(cookie));
|
||||
response.headers().set(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(cookie));
|
||||
sendResponse(ctx, response);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Login failure", e);
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
|
||||
HttpResponseStatus.UNAUTHORIZED);
|
||||
response.headers().set(Names.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
|
||||
sendResponse(ctx, response);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import timely.api.request.timeseries.AggregatorsRequest;
|
||||
@@ -22,8 +22,8 @@ public class HttpAggregatorsRequestHandler extends SimpleChannelInboundHandler<A
|
||||
byte[] buf = JsonUtil.getObjectMapper().writeValueAsBytes(AggregatorsResponse.RESPONSE);
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
|
||||
Unpooled.copiedBuffer(buf));
|
||||
response.headers().set(Names.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
|
||||
sendResponse(ctx, response);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package timely.netty.http.timeseries;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import timely.api.request.timeseries.MetricsRequest;
|
||||
import timely.api.response.timeseries.MetricsResponse;
|
||||
import timely.configuration.Configuration;
|
||||
@@ -20,7 +20,7 @@ public class HttpMetricsRequestHandler extends SimpleChannelInboundHandler<Metri
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, MetricsRequest msg) throws Exception {
|
||||
MetricsResponse r = new MetricsResponse(conf);
|
||||
String acceptHeader = msg.getRequestHeader(Names.ACCEPT);
|
||||
String acceptHeader = msg.getRequestHeader(HttpHeaderNames.ACCEPT.toString());
|
||||
sendResponse(ctx, r.toHttpResponse(acceptHeader));
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import org.slf4j.Logger;
|
||||
@@ -42,8 +42,8 @@ public class HttpQueryRequestHandler extends SimpleChannelInboundHandler<QueryRe
|
||||
}
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
|
||||
Unpooled.copiedBuffer(buf));
|
||||
response.headers().set(Names.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
|
||||
sendResponse(ctx, response);
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import org.slf4j.Logger;
|
||||
@@ -39,8 +39,8 @@ public class HttpSearchLookupRequestHandler extends SimpleChannelInboundHandler<
|
||||
}
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
|
||||
Unpooled.copiedBuffer(buf));
|
||||
response.headers().set(Names.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
|
||||
sendResponse(ctx, response);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import org.slf4j.Logger;
|
||||
@@ -39,8 +39,8 @@ public class HttpSuggestRequestHandler extends SimpleChannelInboundHandler<Sugge
|
||||
}
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
|
||||
Unpooled.copiedBuffer(buf));
|
||||
response.headers().set(Names.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, Constants.JSON_TYPE);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
|
||||
sendResponse(ctx, response);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,6 @@ public class AggregationIterator extends WrappingIterator {
|
||||
private Set<Tag> tags;
|
||||
private Key last;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void init(SortedKeyValueIterator<Key, Value> source, Map<String, String> options, IteratorEnvironment env)
|
||||
throws IOException {
|
||||
@@ -45,7 +44,10 @@ public class AggregationIterator extends WrappingIterator {
|
||||
String aggClassname = options.get(AGGCLASS);
|
||||
Class<? extends Aggregator> aggClass = null;
|
||||
try {
|
||||
aggClass = (Class<? extends Aggregator>) this.getClass().getClassLoader().loadClass(aggClassname);
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends Aggregator> uncheckedAggClass = (Class<? extends Aggregator>) this.getClass()
|
||||
.getClassLoader().loadClass(aggClassname);
|
||||
aggClass = uncheckedAggClass;
|
||||
tags = new HashSet<>(new TagListParser().parse(options.get(TAGS)));
|
||||
aggregation = new Aggregation(aggClass.newInstance());
|
||||
} catch (ClassNotFoundException e) {
|
||||
@@ -119,10 +121,11 @@ public class AggregationIterator extends WrappingIterator {
|
||||
is.addOption(AGGCLASS, classname);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<Set<Tag>, Aggregation> decodeValue(Value value) throws IOException, ClassNotFoundException {
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(value.get());
|
||||
ObjectInputStream ois = new ObjectInputStream(bis);
|
||||
return (Map<Set<Tag>, Aggregation>) ois.readObject();
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Set<Tag>, Aggregation> unchecked = (Map<Set<Tag>, Aggregation>) ois.readObject();
|
||||
return unchecked;
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,6 @@ public class DownsampleIterator extends WrappingIterator {
|
||||
|
||||
private DownsampleMemoryEstimator memoryEstimator = null;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void init(SortedKeyValueIterator<Key, Value> source, Map<String, String> options, IteratorEnvironment env)
|
||||
throws IOException {
|
||||
@@ -73,7 +72,9 @@ public class DownsampleIterator extends WrappingIterator {
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
factory = new DownsampleFactory(start, end, period, (Class<? extends Aggregator>) aggClass);
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends Aggregator> uncheckedAggClass = (Class<? extends Aggregator>) aggClass;
|
||||
factory = new DownsampleFactory(start, end, period, uncheckedAggClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,11 +155,12 @@ public class DownsampleIterator extends WrappingIterator {
|
||||
is.addOption(AGGCLASS, classname);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<Set<Tag>, Downsample> decodeValue(Value value) throws IOException, ClassNotFoundException {
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(value.get());
|
||||
ObjectInputStream ois = new ObjectInputStream(bis);
|
||||
return (Map<Set<Tag>, Downsample>) ois.readObject();
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Set<Tag>, Downsample> unchecked = (Map<Set<Tag>, Downsample>) ois.readObject();
|
||||
return unchecked;
|
||||
}
|
||||
|
||||
public static long getDownsamplePeriod(QueryRequest.SubQuery query) {
|
||||
|
||||
@@ -48,14 +48,17 @@ import org.apache.accumulo.core.client.TableExistsException;
|
||||
import org.apache.accumulo.core.client.TableNotFoundException;
|
||||
import org.apache.accumulo.core.client.ZooKeeperInstance;
|
||||
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
|
||||
import org.apache.accumulo.core.data.*;
|
||||
import org.apache.accumulo.core.data.Key;
|
||||
import org.apache.accumulo.core.data.Mutation;
|
||||
import org.apache.accumulo.core.data.PartialKey;
|
||||
import org.apache.accumulo.core.data.Range;
|
||||
import org.apache.accumulo.core.data.Value;
|
||||
import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
|
||||
import org.apache.accumulo.core.iterators.user.RegExFilter;
|
||||
import org.apache.accumulo.core.security.Authorizations;
|
||||
import org.apache.accumulo.core.security.ColumnVisibility;
|
||||
import org.apache.accumulo.core.security.VisibilityEvaluator;
|
||||
import org.apache.accumulo.core.util.Pair;
|
||||
import org.apache.commons.configuration.BaseConfiguration;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hadoop.io.Text;
|
||||
import org.slf4j.Logger;
|
||||
@@ -140,11 +143,11 @@ public class DataStoreImpl implements DataStore {
|
||||
public DataStoreImpl(Configuration conf, int numWriteThreads) throws TimelyException {
|
||||
|
||||
try {
|
||||
final BaseConfiguration apacheConf = new BaseConfiguration();
|
||||
final Map<String, String> properties = new HashMap<>();
|
||||
Accumulo accumuloConf = conf.getAccumulo();
|
||||
apacheConf.setProperty("instance.name", accumuloConf.getInstanceName());
|
||||
apacheConf.setProperty("instance.zookeeper.host", accumuloConf.getZookeepers());
|
||||
final ClientConfiguration aconf = new ClientConfiguration(Collections.singletonList(apacheConf));
|
||||
properties.put("instance.name", accumuloConf.getInstanceName());
|
||||
properties.put("instance.zookeeper.host", accumuloConf.getZookeepers());
|
||||
final ClientConfiguration aconf = ClientConfiguration.fromMap(properties);
|
||||
final Instance instance = new ZooKeeperInstance(aconf);
|
||||
connector = instance.getConnector(accumuloConf.getUsername(),
|
||||
new PasswordToken(accumuloConf.getPassword()));
|
||||
@@ -208,7 +211,7 @@ public class DataStoreImpl implements DataStore {
|
||||
}
|
||||
try {
|
||||
this.removeAgeOffIterators(connector, metricsTable);
|
||||
this.applyAgeOffIterator(connector, metricsTable, true);
|
||||
this.applyMetricAgeOffIterator(connector, metricsTable);
|
||||
} catch (Exception e1) {
|
||||
Throwable cause = e1.getCause();
|
||||
if (cause.getMessage().contains("conflict")) {
|
||||
@@ -229,7 +232,7 @@ public class DataStoreImpl implements DataStore {
|
||||
}
|
||||
try {
|
||||
this.removeAgeOffIterators(connector, metaTable);
|
||||
this.applyAgeOffIterator(connector, metaTable, false);
|
||||
this.applyMetaAgeOffIterator(connector, metaTable);
|
||||
} catch (Exception e1) {
|
||||
Throwable cause = e1.getCause();
|
||||
if (cause.getMessage().contains("conflict")) {
|
||||
@@ -282,13 +285,15 @@ public class DataStoreImpl implements DataStore {
|
||||
}
|
||||
}
|
||||
|
||||
private void applyAgeOffIterator(Connector con, String tableName, boolean useIterator) throws Exception {
|
||||
IteratorSetting ageOffIteratorSettings = null;
|
||||
if (useIterator) {
|
||||
ageOffIteratorSettings = new IteratorSetting(100, "ageoff", MetricAgeOffIterator.class, this.ageOff);
|
||||
} else {
|
||||
ageOffIteratorSettings = new IteratorSetting(100, "ageoff", MetricAgeOffFilter.class, this.ageOff);
|
||||
}
|
||||
private void applyMetricAgeOffIterator(Connector con, String tableName) throws Exception {
|
||||
IteratorSetting ageOffIteratorSettings = new IteratorSetting(100, "ageoffmetrics", MetricAgeOffIterator.class,
|
||||
this.ageOff);
|
||||
connector.tableOperations().attachIterator(tableName, ageOffIteratorSettings, AGEOFF_SCOPES);
|
||||
}
|
||||
|
||||
private void applyMetaAgeOffIterator(Connector con, String tableName) throws Exception {
|
||||
IteratorSetting ageOffIteratorSettings = new IteratorSetting(100, "ageoffmeta", MetaAgeOffIterator.class,
|
||||
this.ageOff);
|
||||
connector.tableOperations().attachIterator(tableName, ageOffIteratorSettings, AGEOFF_SCOPES);
|
||||
}
|
||||
|
||||
@@ -438,6 +443,7 @@ public class DataStoreImpl implements DataStore {
|
||||
@Override
|
||||
public SuggestResponse suggest(SuggestRequest request) throws TimelyException {
|
||||
SuggestResponse result = new SuggestResponse();
|
||||
Scanner scanner = null;
|
||||
try {
|
||||
if (request.getType().equals("metrics")) {
|
||||
Range range;
|
||||
@@ -457,7 +463,7 @@ public class DataStoreImpl implements DataStore {
|
||||
end.append(lastBytes, 0, lastBytes.length);
|
||||
range = new Range(start, end);
|
||||
}
|
||||
Scanner scanner = connector.createScanner(metaTable, Authorizations.EMPTY);
|
||||
scanner = connector.createScanner(metaTable, Authorizations.EMPTY);
|
||||
scanner.setRange(range);
|
||||
List<String> metrics = new ArrayList<>();
|
||||
for (Entry<Key, Value> metric : scanner) {
|
||||
@@ -472,6 +478,10 @@ public class DataStoreImpl implements DataStore {
|
||||
LOG.error("Error during suggest: " + ex.getMessage(), ex);
|
||||
throw new TimelyException(HttpResponseStatus.INTERNAL_SERVER_ERROR.code(),
|
||||
"Error during suggest: " + ex.getMessage(), ex.getMessage(), ex);
|
||||
} finally {
|
||||
if (scanner != null) {
|
||||
scanner.close();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -506,28 +516,34 @@ public class DataStoreImpl implements DataStore {
|
||||
tagPatterns.put(k, Pattern.compile(v));
|
||||
});
|
||||
try {
|
||||
List<Result> resultField = new ArrayList<>();
|
||||
Scanner scanner = connector.createScanner(metaTable, Authorizations.EMPTY);
|
||||
Key start = new Key(Meta.VALUE_PREFIX + msg.getQuery());
|
||||
Key end = start.followingKey(PartialKey.ROW);
|
||||
Range range = new Range(start, end);
|
||||
scanner.setRange(range);
|
||||
tags.keySet().forEach(k -> scanner.fetchColumnFamily(new Text(k)));
|
||||
int total = 0;
|
||||
for (Entry<Key, Value> entry : scanner) {
|
||||
Meta metaEntry = Meta.parse(entry.getKey(), entry.getValue());
|
||||
if (matches(metaEntry.getTagKey(), metaEntry.getTagValue(), tagPatterns)) {
|
||||
if (resultField.size() < msg.getLimit()) {
|
||||
Result r = new Result();
|
||||
r.putTag(metaEntry.getTagKey(), metaEntry.getTagValue());
|
||||
resultField.add(r);
|
||||
final Scanner scanner = connector.createScanner(metaTable, Authorizations.EMPTY);
|
||||
try {
|
||||
List<Result> resultField = new ArrayList<>();
|
||||
Key start = new Key(Meta.VALUE_PREFIX + msg.getQuery());
|
||||
Key end = start.followingKey(PartialKey.ROW);
|
||||
Range range = new Range(start, end);
|
||||
scanner.setRange(range);
|
||||
tags.keySet().forEach(k -> scanner.fetchColumnFamily(new Text(k)));
|
||||
int total = 0;
|
||||
for (Entry<Key, Value> entry : scanner) {
|
||||
Meta metaEntry = Meta.parse(entry.getKey(), entry.getValue());
|
||||
if (matches(metaEntry.getTagKey(), metaEntry.getTagValue(), tagPatterns)) {
|
||||
if (resultField.size() < msg.getLimit()) {
|
||||
Result r = new Result();
|
||||
r.putTag(metaEntry.getTagKey(), metaEntry.getTagValue());
|
||||
resultField.add(r);
|
||||
}
|
||||
total++;
|
||||
}
|
||||
total++;
|
||||
}
|
||||
result.setResults(resultField);
|
||||
result.setTotalResults(total);
|
||||
result.setTime((int) (System.currentTimeMillis() - startMillis));
|
||||
} finally {
|
||||
if (scanner != null) {
|
||||
scanner.close();
|
||||
}
|
||||
}
|
||||
result.setResults(resultField);
|
||||
result.setTotalResults(total);
|
||||
result.setTime((int) (System.currentTimeMillis() - startMillis));
|
||||
} catch (Exception ex) {
|
||||
LOG.error("Error during lookup: " + ex.getMessage(), ex);
|
||||
throw new TimelyException(HttpResponseStatus.INTERNAL_SERVER_ERROR.code(),
|
||||
@@ -796,72 +812,80 @@ public class DataStoreImpl implements DataStore {
|
||||
return !REGEX_TEST.matcher(value).matches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Tag> getColumnFamilies(String metric, Map<String, String> requestedTags) throws TableNotFoundException {
|
||||
|
||||
Map<String, String> tags = (requestedTags == null) ? new LinkedHashMap<>() : requestedTags;
|
||||
LOG.trace("Looking for requested tags: {}", tags);
|
||||
Scanner meta = connector.createScanner(metaTable, Authorizations.EMPTY);
|
||||
Text start = new Text(Meta.VALUE_PREFIX + metric);
|
||||
Text end = new Text(Meta.VALUE_PREFIX + metric + "\\x0000");
|
||||
end.append(new byte[] { (byte) 0xff }, 0, 1);
|
||||
meta.setRange(new Range(start, end));
|
||||
// Only look for the meta entries that match our tags, if any
|
||||
boolean onlyFirstRow = false;
|
||||
Entry<String, String> first = null;
|
||||
// Set the columns on the meta scanner based on the first tag
|
||||
// in the set of tags passed in the query. If no tags are present
|
||||
// then we are only going to return the first tag name present in the
|
||||
// meta table.
|
||||
Iterator<Entry<String, String>> tagIter = tags.entrySet().iterator();
|
||||
if (tagIter.hasNext()) {
|
||||
first = tagIter.next();
|
||||
if (isTagValueRegex(first.getValue())) {
|
||||
meta.fetchColumnFamily(new Text(first.getKey()));
|
||||
} else {
|
||||
meta.fetchColumn(new Text(first.getKey()), new Text(first.getValue()));
|
||||
}
|
||||
} else {
|
||||
// grab all of the values found for the first tag for the metric
|
||||
onlyFirstRow = true;
|
||||
}
|
||||
final boolean ONLY_RETURN_FIRST_TAG = onlyFirstRow;
|
||||
Iterator<Entry<Key, Value>> iter = meta.iterator();
|
||||
Iterator<Pair<String, String>> knownKeyValues = new Iterator<Pair<String, String>>() {
|
||||
|
||||
Text firstTag = null;
|
||||
Text tagName = null;
|
||||
Text tagValue = null;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (iter.hasNext()) {
|
||||
Entry<Key, Value> metaEntry = iter.next();
|
||||
if (null == firstTag) {
|
||||
firstTag = metaEntry.getKey().getColumnFamily();
|
||||
}
|
||||
tagName = metaEntry.getKey().getColumnFamily();
|
||||
tagValue = metaEntry.getKey().getColumnQualifier();
|
||||
LOG.trace("Found tag entry {}={}", tagName, tagValue);
|
||||
|
||||
if (ONLY_RETURN_FIRST_TAG && !tagName.equals(firstTag)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
Scanner meta = null;
|
||||
try {
|
||||
Map<String, String> tags = (requestedTags == null) ? new LinkedHashMap<>() : requestedTags;
|
||||
LOG.trace("Looking for requested tags: {}", tags);
|
||||
meta = connector.createScanner(metaTable, Authorizations.EMPTY);
|
||||
Text start = new Text(Meta.VALUE_PREFIX + metric);
|
||||
Text end = new Text(Meta.VALUE_PREFIX + metric + "\\x0000");
|
||||
end.append(new byte[] { (byte) 0xff }, 0, 1);
|
||||
meta.setRange(new Range(start, end));
|
||||
// Only look for the meta entries that match our tags, if any
|
||||
boolean onlyFirstRow = false;
|
||||
Entry<String, String> first = null;
|
||||
// Set the columns on the meta scanner based on the first tag
|
||||
// in the set of tags passed in the query. If no tags are present
|
||||
// then we are only going to return the first tag name present in the
|
||||
// meta table.
|
||||
Iterator<Entry<String, String>> tagIter = tags.entrySet().iterator();
|
||||
if (tagIter.hasNext()) {
|
||||
first = tagIter.next();
|
||||
if (isTagValueRegex(first.getValue())) {
|
||||
meta.fetchColumnFamily(new Text(first.getKey()));
|
||||
} else {
|
||||
meta.fetchColumn(new Text(first.getKey()), new Text(first.getValue()));
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
// grab all of the values found for the first tag for the metric
|
||||
onlyFirstRow = true;
|
||||
}
|
||||
final boolean ONLY_RETURN_FIRST_TAG = onlyFirstRow;
|
||||
Iterator<Entry<Key, Value>> iter = meta.iterator();
|
||||
Iterator<Pair<String, String>> knownKeyValues = new Iterator<Pair<String, String>>() {
|
||||
|
||||
@Override
|
||||
public Pair<String, String> next() {
|
||||
LOG.trace("Returning tag {}={}", tagName, tagValue);
|
||||
return new Pair<>(tagName.toString(), tagValue.toString());
|
||||
Text firstTag = null;
|
||||
Text tagName = null;
|
||||
Text tagValue = null;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (iter.hasNext()) {
|
||||
Entry<Key, Value> metaEntry = iter.next();
|
||||
if (null == firstTag) {
|
||||
firstTag = metaEntry.getKey().getColumnFamily();
|
||||
}
|
||||
tagName = metaEntry.getKey().getColumnFamily();
|
||||
tagValue = metaEntry.getKey().getColumnQualifier();
|
||||
LOG.trace("Found tag entry {}={}", tagName, tagValue);
|
||||
|
||||
if (ONLY_RETURN_FIRST_TAG && !tagName.equals(firstTag)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<String, String> next() {
|
||||
LOG.trace("Returning tag {}={}", tagName, tagValue);
|
||||
return new Pair<>(tagName.toString(), tagValue.toString());
|
||||
}
|
||||
};
|
||||
// Expand the list of tags in the meta table for this metric that
|
||||
// matches
|
||||
// the pattern of the first tag in the query. The resulting set of tags
|
||||
// will be used to fetch specific columns from the metric table.
|
||||
return expandTagValues(first, knownKeyValues);
|
||||
} finally {
|
||||
if (meta != null) {
|
||||
meta.close();
|
||||
}
|
||||
};
|
||||
// Expand the list of tags in the meta table for this metric that
|
||||
// matches
|
||||
// the pattern of the first tag in the query. The resulting set of tags
|
||||
// will be used to fetch specific columns from the metric table.
|
||||
return expandTagValues(first, knownKeyValues);
|
||||
}
|
||||
}
|
||||
|
||||
private void setQueryColumns(ScannerBase scanner, String metric, Map<String, String> tags, Set<Tag> colFamValues)
|
||||
@@ -932,6 +956,7 @@ public class DataStoreImpl implements DataStore {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Range> getQueryRanges(String metric, long start, long end, Set<Tag> colFamValues) {
|
||||
List<Range> ranges = new ArrayList<>();
|
||||
long beginRangeRounded = MetricAdapter.roundTimestampToLastHour(start);
|
||||
@@ -994,6 +1019,7 @@ public class DataStoreImpl implements DataStore {
|
||||
return AuthCache.getAuthorizations(request, security);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAgeOffForMetric(String metricName) {
|
||||
String age = this.ageOff.get(MetricAgeOffIterator.AGE_OFF_PREFIX + metricName);
|
||||
if (null == age) {
|
||||
@@ -1003,6 +1029,7 @@ public class DataStoreImpl implements DataStore {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scanner createScannerForMetric(AuthenticatedRequest request, String metric, Map<String, String> tags,
|
||||
int scannerBatchSize, int scannerReadAhead) throws TimelyException {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
package timely.store;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.accumulo.core.data.ByteSequence;
|
||||
import org.apache.accumulo.core.data.Key;
|
||||
import org.apache.accumulo.core.data.Range;
|
||||
import org.apache.accumulo.core.data.Value;
|
||||
import org.apache.accumulo.core.iterators.IteratorEnvironment;
|
||||
import org.apache.accumulo.core.iterators.OptionDescriber;
|
||||
import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
|
||||
import org.apache.accumulo.core.iterators.WrappingIterator;
|
||||
import org.apache.commons.collections4.trie.PatriciaTrie;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import timely.api.model.Meta;
|
||||
|
||||
public class MetaAgeOffIterator extends WrappingIterator implements OptionDescriber {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MetaAgeOffIterator.class);
|
||||
public static final String AGE_OFF_PREFIX = "ageoff.";
|
||||
public static final String DEFAULT_AGEOFF_KEY = "default";
|
||||
|
||||
/* set in init */
|
||||
private PatriciaTrie<Long> ageoffs = null;
|
||||
private Long currentTime = 0L;
|
||||
private Long defaultAgeOff = 0L;
|
||||
private Long minAgeOff = Long.MAX_VALUE;
|
||||
private Long maxAgeOff = Long.MIN_VALUE;
|
||||
|
||||
@Override
|
||||
public SortedKeyValueIterator<Key, Value> deepCopy(IteratorEnvironment env) {
|
||||
MetaAgeOffIterator iter = new MetaAgeOffIterator();
|
||||
iter.ageoffs = this.ageoffs;
|
||||
iter.defaultAgeOff = this.defaultAgeOff;
|
||||
iter.currentTime = this.currentTime;
|
||||
iter.minAgeOff = this.minAgeOff;
|
||||
iter.maxAgeOff = this.maxAgeOff;
|
||||
return iter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(SortedKeyValueIterator<Key, Value> source, Map<String, String> options, IteratorEnvironment env)
|
||||
throws IOException {
|
||||
super.init(source, options, env);
|
||||
validateOptions(options);
|
||||
ageoffs = new PatriciaTrie<>();
|
||||
options.forEach((k, v) -> {
|
||||
if (k.startsWith(AGE_OFF_PREFIX)) {
|
||||
String name = k.substring(AGE_OFF_PREFIX.length());
|
||||
LOG.trace("Adding {} to Trie with value {}", name, Long.parseLong(v));
|
||||
long ageoff = Long.parseLong(v);
|
||||
this.minAgeOff = Math.min(this.minAgeOff, ageoff);
|
||||
this.maxAgeOff = Math.max(this.maxAgeOff, ageoff);
|
||||
ageoffs.put(name, ageoff);
|
||||
}
|
||||
});
|
||||
defaultAgeOff = ageoffs.get(DEFAULT_AGEOFF_KEY);
|
||||
currentTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void next() throws IOException {
|
||||
super.next();
|
||||
skipExpiredData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(Range range, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException {
|
||||
super.seek(range, columnFamilies, inclusive);
|
||||
skipExpiredData();
|
||||
}
|
||||
|
||||
private void skipExpiredData() throws IOException {
|
||||
|
||||
boolean done = false;
|
||||
while (!done && super.hasTop()) {
|
||||
Key top = super.getTopKey();
|
||||
long dataAge = this.currentTime - top.getTimestamp();
|
||||
// If less than any configured ageoff, then we want to return this K,V
|
||||
if (dataAge < this.minAgeOff) {
|
||||
done = true;
|
||||
} else {
|
||||
String metricName = Meta.parse(top).getMetric();
|
||||
long metaAgeOff = ageoffs.getOrDefault(metricName, defaultAgeOff);
|
||||
if (dataAge > metaAgeOff) {
|
||||
// data beyond ageOff, so skip
|
||||
super.next();
|
||||
} else {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IteratorOptions describeOptions() {
|
||||
return new IteratorOptions("meta-age-off", "Iterator that ages off meta entries for Timely metrics",
|
||||
Collections.singletonMap(AGE_OFF_PREFIX + DEFAULT_AGEOFF_KEY, "default age off days"),
|
||||
Collections.singletonList("Additional meta age off properties where the value is specified as "
|
||||
+ AGE_OFF_PREFIX
|
||||
+ " the metric name and the value is an integer representing the number of days to keep"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateOptions(Map<String, String> options) {
|
||||
if (null == options.get(AGE_OFF_PREFIX + DEFAULT_AGEOFF_KEY)) {
|
||||
throw new IllegalArgumentException(DEFAULT_AGEOFF_KEY + " must be configured for MetaAgeOffFilter");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +1,121 @@
|
||||
package timely.store;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import org.apache.accumulo.core.client.ClientConfiguration;
|
||||
import org.apache.accumulo.core.client.Connector;
|
||||
import org.apache.accumulo.core.client.Instance;
|
||||
import org.apache.accumulo.core.client.Scanner;
|
||||
import org.apache.accumulo.core.client.ZooKeeperInstance;
|
||||
import org.apache.accumulo.core.client.security.tokens.PasswordToken;
|
||||
import org.apache.accumulo.core.data.Key;
|
||||
import org.apache.accumulo.core.data.Range;
|
||||
import org.apache.accumulo.core.data.Value;
|
||||
import org.apache.accumulo.core.security.Authorizations;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import timely.api.model.Meta;
|
||||
import timely.configuration.Accumulo;
|
||||
import timely.configuration.Configuration;
|
||||
|
||||
public class MetaCacheImpl implements MetaCache {
|
||||
|
||||
private static Logger LOG = LoggerFactory.getLogger(MetaCacheImpl.class);
|
||||
private static final Object DUMMY = new Object();
|
||||
private volatile boolean closed = false;
|
||||
private Cache<Meta, Object> cache = null;
|
||||
private Configuration configuration;
|
||||
private Timer timer = new Timer("MetaCacheImpl", true);
|
||||
|
||||
@Override
|
||||
public void init(Configuration config) {
|
||||
long expirationMinutes = config.getMetaCache().getExpirationMinutes();
|
||||
int initialCapacity = config.getMetaCache().getInitialCapacity();
|
||||
long maxCapacity = config.getMetaCache().getMaxCapacity();
|
||||
cache = Caffeine.newBuilder().expireAfterAccess(expirationMinutes, TimeUnit.MINUTES)
|
||||
.initialCapacity(initialCapacity).maximumSize(maxCapacity).build();
|
||||
configuration = config;
|
||||
cache = Caffeine.newBuilder().initialCapacity(1000).build();
|
||||
long cacheRefreshMinutes = configuration.getMetaCache().getCacheRefreshMinutes();
|
||||
if (cacheRefreshMinutes > 0) {
|
||||
timer.schedule(new TimerTask() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
refreshCache(config.getMetaCache().getExpirationMinutes());
|
||||
}
|
||||
}, 60000, cacheRefreshMinutes * 60 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshCache(long expirationMinutes) {
|
||||
long oldestTimestamp = System.currentTimeMillis() - (expirationMinutes * 60 * 1000);
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
Accumulo accumuloConf = configuration.getAccumulo();
|
||||
properties.put("instance.name", accumuloConf.getInstanceName());
|
||||
properties.put("instance.zookeeper.host", accumuloConf.getZookeepers());
|
||||
final ClientConfiguration aConf = ClientConfiguration.fromMap(properties);
|
||||
String metaTable = configuration.getMetaTable();
|
||||
Map<String, Map<String, Long>> metricMap = new HashMap<>();
|
||||
Scanner scanner = null;
|
||||
try {
|
||||
final Instance instance = new ZooKeeperInstance(aConf);
|
||||
Connector connector = instance.getConnector(accumuloConf.getUsername(),
|
||||
new PasswordToken(accumuloConf.getPassword()));
|
||||
scanner = connector.createScanner(metaTable, Authorizations.EMPTY);
|
||||
LOG.debug("Begin scanning " + metaTable);
|
||||
Range metricRange = new Range(new Key(Meta.METRIC_PREFIX), true, new Key(Meta.METRIC_PREFIX + '\0'), false);
|
||||
scanner.setRange(metricRange);
|
||||
Set<String> allMetrics = new TreeSet<>();
|
||||
for (Map.Entry<Key, Value> entry : scanner) {
|
||||
Meta meta = Meta.parse(entry.getKey(), entry.getValue(), Meta.METRIC_PREFIX);
|
||||
allMetrics.add(meta.getMetric());
|
||||
}
|
||||
for (String currMetric : allMetrics) {
|
||||
Key begin = new Key(Meta.VALUE_PREFIX + currMetric);
|
||||
Key end = new Key(Meta.VALUE_PREFIX + currMetric + '\0');
|
||||
Range range = new Range(begin, true, end, false);
|
||||
scanner.setRange(range);
|
||||
Iterator<Map.Entry<Key, Value>> itr = scanner.iterator();
|
||||
boolean maxedOutValues = false;
|
||||
while (itr.hasNext() && !maxedOutValues) {
|
||||
Map.Entry<Key, Value> entry = itr.next();
|
||||
Meta meta = Meta.parse(entry.getKey(), entry.getValue(), Meta.VALUE_PREFIX);
|
||||
String metric = meta.getMetric();
|
||||
String tagKey = meta.getTagKey();
|
||||
Map<String, Long> tagMap = metricMap.get(metric);
|
||||
if (tagMap == null) {
|
||||
tagMap = new HashMap<>();
|
||||
metricMap.put(metric, tagMap);
|
||||
}
|
||||
long numTagValues = tagMap.getOrDefault(tagKey, 0l);
|
||||
if (entry.getKey().getTimestamp() > oldestTimestamp) {
|
||||
tagMap.put(tagKey, ++numTagValues);
|
||||
if (numTagValues <= configuration.getMetaCache().getMaxTagValues()) {
|
||||
cache.put(meta, DUMMY);
|
||||
} else {
|
||||
// found maxTagValues on this refresh, so remove this key
|
||||
cache.invalidate(meta);
|
||||
maxedOutValues = true;
|
||||
}
|
||||
} else {
|
||||
// this entry is more than expirationMinutes old, so remove it
|
||||
cache.invalidate(meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG.debug("Finished scanning " + metaTable);
|
||||
} catch (Exception e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
} finally {
|
||||
if (scanner != null) {
|
||||
scanner.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,5 +147,4 @@ public class MetaCacheImpl implements MetaCache {
|
||||
public boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -143,8 +143,8 @@ public class MetricAgeOffIterator extends WrappingIterator implements OptionDesc
|
||||
byte[] newStartRow = MetricAdapter.encodeRowKey(start.getFirst(), timeTarget);
|
||||
// @formatter:off
|
||||
Key newStartKey = new Key(newStartRow,
|
||||
null != startKey.getColumnFamily() ? startKey.getColumnFamilyData().getBackingArray() : null,
|
||||
null != startKey.getColumnQualifier() ? startKey.getColumnQualifierData().getBackingArray() : null,
|
||||
null != startKey.getColumnFamily() ? startKey.getColumnFamilyData().getBackingArray() : null,
|
||||
null != startKey.getColumnQualifier() ? startKey.getColumnQualifierData().getBackingArray() : null,
|
||||
null != startKey.getColumnVisibility() ? startKey.getColumnVisibility().getBytes() : null,
|
||||
timeTarget, startKey.isDeleted());
|
||||
// @formatter:on
|
||||
|
||||
@@ -41,7 +41,7 @@ public class OrderedTags {
|
||||
}
|
||||
|
||||
public Map<String, String> getTags() {
|
||||
Map<String, String> t = new LinkedHashMap();
|
||||
Map<String, String> t = new LinkedHashMap<>();
|
||||
for (Pair<String, String> p : tagSet) {
|
||||
t.put(p.getLeft(), p.getRight());
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.apache.commons.lang3.Range;
|
||||
|
||||
public class WrappedGorillaCompressor implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private boolean closed = false;
|
||||
private long numEntries = 0;
|
||||
private long oldestTimestamp;
|
||||
@@ -19,10 +20,6 @@ public class WrappedGorillaCompressor implements Serializable {
|
||||
private long[] backingArray = null;
|
||||
private GorillaCompressor compressor;
|
||||
|
||||
private WrappedGorillaCompressor() {
|
||||
|
||||
}
|
||||
|
||||
public WrappedGorillaCompressor(long timestamp) {
|
||||
this.compressorOutput = new LongArrayOutput(16);
|
||||
this.compressor = new GorillaCompressor(timestamp, this.compressorOutput);
|
||||
|
||||
@@ -2,7 +2,14 @@ package timely.store.iterators;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.accumulo.core.data.ByteSequence;
|
||||
import org.apache.accumulo.core.data.Key;
|
||||
@@ -28,19 +35,19 @@ import timely.model.Metric;
|
||||
* number of elements in the filter. So, if you have a five day moving average
|
||||
* filter and a time series as 100 data points, then you will receive 95
|
||||
* results.
|
||||
*
|
||||
*
|
||||
* For multiple time series, K/V pairs will be reported in time order where time
|
||||
* is taken from the key of the last element in the filter. For example, if you
|
||||
* have series {A,B,C} and {A,C} are on the same time interval and B is lagging
|
||||
* behind them, then this iterator will return K/V answers for the time series
|
||||
* in the following manner:
|
||||
*
|
||||
*
|
||||
* A, C, B, A, C, B, ...
|
||||
*
|
||||
*
|
||||
* Also of note is that this iterator handles new time series appearing in the
|
||||
* middle of the time range. Time series that disappear during the time range
|
||||
* will stop reporting an answer.
|
||||
*
|
||||
*
|
||||
* NOTE: This iterator does not handle being re-seeked. It is currently designed
|
||||
* to be used with the DownsampleIterator above it.
|
||||
*
|
||||
@@ -222,8 +229,6 @@ public class TimeSeriesGroupingIterator extends WrappingIterator {
|
||||
/**
|
||||
* This will parse the next set of keys with the same timestamp (encoded in the
|
||||
* row) from the underlying source.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
private void refillBuffer() throws IOException {
|
||||
LOG.trace("refill()");
|
||||
|
||||
@@ -153,7 +153,7 @@ public class MetricQueryLoadTest {
|
||||
|
||||
long numQueries = 1000;
|
||||
long queriesCompleted = 0;
|
||||
List<Future> futures = new ArrayList<>();
|
||||
List<Future<?>> futures = new ArrayList<>();
|
||||
|
||||
while (!testDone) {
|
||||
testDone = (System.currentTimeMillis() - beginQueries) >= (testDurationMins * 60 * 1000);
|
||||
@@ -164,9 +164,9 @@ public class MetricQueryLoadTest {
|
||||
while (futures.size() < numQueries) {
|
||||
futures.add(executorService.submit(runnableTask));
|
||||
}
|
||||
Iterator<Future> itr = futures.iterator();
|
||||
Iterator<Future<?>> itr = futures.iterator();
|
||||
while (itr.hasNext()) {
|
||||
Future f = itr.next();
|
||||
Future<?> f = itr.next();
|
||||
if (f.isDone()) {
|
||||
itr.remove();
|
||||
queriesCompleted++;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package timely.util;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.accumulo.core.client.ClientConfiguration;
|
||||
@@ -12,8 +13,8 @@ import org.apache.accumulo.core.client.security.tokens.PasswordToken;
|
||||
import org.apache.accumulo.core.data.Key;
|
||||
import org.apache.accumulo.core.data.Range;
|
||||
import org.apache.accumulo.core.data.Value;
|
||||
import org.apache.commons.configuration.BaseConfiguration;
|
||||
import org.springframework.boot.Banner.Mode;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import timely.api.model.Meta;
|
||||
@@ -26,14 +27,14 @@ public class GetMetricTableSplitPoints {
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
try (ConfigurableApplicationContext ctx = new SpringApplicationBuilder(SpringBootstrap.class)
|
||||
.bannerMode(Mode.OFF).web(false).run(args)) {
|
||||
.bannerMode(Mode.OFF).web(WebApplicationType.NONE).run(args)) {
|
||||
Configuration conf = ctx.getBean(Configuration.class);
|
||||
|
||||
final BaseConfiguration apacheConf = new BaseConfiguration();
|
||||
final Map<String, String> properties = new HashMap<>();
|
||||
Accumulo accumuloConf = conf.getAccumulo();
|
||||
apacheConf.setProperty("instance.name", accumuloConf.getInstanceName());
|
||||
apacheConf.setProperty("instance.zookeeper.host", accumuloConf.getZookeepers());
|
||||
final ClientConfiguration aconf = new ClientConfiguration(Collections.singletonList(apacheConf));
|
||||
properties.put("instance.name", accumuloConf.getInstanceName());
|
||||
properties.put("instance.zookeeper.host", accumuloConf.getZookeepers());
|
||||
final ClientConfiguration aconf = ClientConfiguration.fromMap(properties);
|
||||
final Instance instance = new ZooKeeperInstance(aconf);
|
||||
Connector con = instance.getConnector(accumuloConf.getUsername(),
|
||||
new PasswordToken(accumuloConf.getPassword()));
|
||||
|
||||
@@ -4,16 +4,22 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import timely.configuration.Configuration;
|
||||
import timely.configuration.SpringBootstrap;
|
||||
|
||||
public class ConfigurationTest {
|
||||
|
||||
private final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void createContext() {
|
||||
context = new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@After
|
||||
public void closeContext() {
|
||||
@@ -24,7 +30,7 @@ public class ConfigurationTest {
|
||||
public void testMinimalConfiguration() throws Exception {
|
||||
context.register(SpringBootstrap.class);
|
||||
// @formatter:off
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
TestPropertyValues.of(
|
||||
"timely.server.ip:127.0.0.1",
|
||||
"timely.server.tcp-port:54321",
|
||||
"timely.server.udp-port:54325",
|
||||
@@ -38,7 +44,7 @@ public class ConfigurationTest {
|
||||
"timely.accumulo.password:secret",
|
||||
"timely.http.host:localhost",
|
||||
"timely.security.serverSsl.use-generated-keypair:true",
|
||||
"timely.metric-age-off-days[default]:7");
|
||||
"timely.metric-age-off-days[default]:7").applyTo(this.context);
|
||||
// @formatter:on
|
||||
context.refresh();
|
||||
Configuration config = this.context.getBean(Configuration.class);
|
||||
@@ -62,7 +68,7 @@ public class ConfigurationTest {
|
||||
public void testMissingSSLProperty() throws Exception {
|
||||
context.register(SpringBootstrap.class);
|
||||
// @formatter:off
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
TestPropertyValues.of(
|
||||
"timely.server.ip:127.0.0.1",
|
||||
"timely.server.tcp-port:54321",
|
||||
"timely.server.udp-port:54325",
|
||||
@@ -74,7 +80,7 @@ public class ConfigurationTest {
|
||||
"timely.accumulo.instance-name:test",
|
||||
"timely.accumulo.username:root",
|
||||
"timely.accumulo.password:secret",
|
||||
"timely.http.host:localhost");
|
||||
"timely.http.host:localhost").applyTo(this.context);
|
||||
// @formatter:on
|
||||
context.refresh();
|
||||
}
|
||||
@@ -83,7 +89,7 @@ public class ConfigurationTest {
|
||||
public void testSSLProperty() throws Exception {
|
||||
context.register(SpringBootstrap.class);
|
||||
// @formatter:off
|
||||
EnvironmentTestUtils.addEnvironment(this.context,
|
||||
TestPropertyValues.of(
|
||||
"timely.server.ip:127.0.0.1",
|
||||
"timely.server.tcp-port:54321",
|
||||
"timely.server.udp-port:54325",
|
||||
@@ -97,7 +103,7 @@ public class ConfigurationTest {
|
||||
"timely.accumulo.password:secret",
|
||||
"timely.http.host:localhost",
|
||||
"timely.security.serverSsl.certificate-file:/tmp/foo",
|
||||
"timely.security.serverSsl.key-file:/tmp/bar");
|
||||
"timely.security.serverSsl.key-file:/tmp/bar").applyTo(this.context);
|
||||
// @formatter:on
|
||||
context.refresh();
|
||||
}
|
||||
|
||||
+53
-53
@@ -12,11 +12,11 @@ public class WebSocketRequestDeserializationTest {
|
||||
@Test
|
||||
public void testCreateDeserialization() throws Exception {
|
||||
// @formatter:off
|
||||
String json = "{ "
|
||||
+ "\"operation\" : \"create\","
|
||||
+ " \"sessionId\": \"1234\""
|
||||
+ "}";
|
||||
// @formatter:on
|
||||
String json = "{ "
|
||||
+ "\"operation\" : \"create\","
|
||||
+ " \"sessionId\": \"1234\""
|
||||
+ "}";
|
||||
// @formatter:on
|
||||
WebSocketRequest request = JsonUtil.getObjectMapper().readValue(json.getBytes(), WebSocketRequest.class);
|
||||
Assert.assertNotNull(request);
|
||||
Assert.assertEquals(CreateSubscription.class, request.getClass());
|
||||
@@ -26,12 +26,12 @@ public class WebSocketRequestDeserializationTest {
|
||||
@Test
|
||||
public void testRemoveDeserialization() throws Exception {
|
||||
// @formatter:off
|
||||
String json = "{ "
|
||||
+ "\"operation\" : \"remove\","
|
||||
+ " \"sessionId\": \"1234\","
|
||||
+ " \"metric\" : \"sys.cpu.user\""
|
||||
+ "}";
|
||||
// @formatter:on
|
||||
String json = "{ "
|
||||
+ "\"operation\" : \"remove\","
|
||||
+ " \"sessionId\": \"1234\","
|
||||
+ " \"metric\" : \"sys.cpu.user\""
|
||||
+ "}";
|
||||
// @formatter:on
|
||||
WebSocketRequest request = JsonUtil.getObjectMapper().readValue(json.getBytes(), WebSocketRequest.class);
|
||||
Assert.assertNotNull(request);
|
||||
Assert.assertEquals(RemoveSubscription.class, request.getClass());
|
||||
@@ -42,11 +42,11 @@ public class WebSocketRequestDeserializationTest {
|
||||
@Test
|
||||
public void testCloseDeserialization() throws Exception {
|
||||
// @formatter:off
|
||||
String json = "{ "
|
||||
+ "\"operation\" : \"close\","
|
||||
+ " \"sessionId\": \"1234\""
|
||||
+ "}";
|
||||
// @formatter:on
|
||||
String json = "{ "
|
||||
+ "\"operation\" : \"close\","
|
||||
+ " \"sessionId\": \"1234\""
|
||||
+ "}";
|
||||
// @formatter:on
|
||||
WebSocketRequest request = JsonUtil.getObjectMapper().readValue(json.getBytes(), WebSocketRequest.class);
|
||||
Assert.assertNotNull(request);
|
||||
Assert.assertEquals(CloseSubscription.class, request.getClass());
|
||||
@@ -56,12 +56,12 @@ public class WebSocketRequestDeserializationTest {
|
||||
@Test
|
||||
public void testAddDeserialization() throws Exception {
|
||||
// @formatter:off
|
||||
String json = "{" +
|
||||
"\"operation\" : \"add\"," +
|
||||
"\"sessionId\" : \"1234\"," +
|
||||
" \"metric\" : \"sys.cpu.user\"" +
|
||||
"}";
|
||||
// @formatter:on
|
||||
String json = "{" +
|
||||
"\"operation\" : \"add\"," +
|
||||
"\"sessionId\" : \"1234\"," +
|
||||
" \"metric\" : \"sys.cpu.user\"" +
|
||||
"}";
|
||||
// @formatter:on
|
||||
WebSocketRequest request = JsonUtil.getObjectMapper().readValue(json.getBytes(), WebSocketRequest.class);
|
||||
Assert.assertNotNull(request);
|
||||
Assert.assertEquals(AddSubscription.class, request.getClass());
|
||||
@@ -74,13 +74,13 @@ public class WebSocketRequestDeserializationTest {
|
||||
@Test
|
||||
public void testAddDeserializationWithTime() throws Exception {
|
||||
// @formatter:off
|
||||
String json = "{" +
|
||||
"\"operation\" : \"add\"," +
|
||||
"\"sessionId\" : \"1234\"," +
|
||||
"\"metric\" : \"sys.cpu.user\"," +
|
||||
"\"startTime\" : \"1000\"" +
|
||||
"}";
|
||||
// @formatter:on
|
||||
String json = "{" +
|
||||
"\"operation\" : \"add\"," +
|
||||
"\"sessionId\" : \"1234\"," +
|
||||
"\"metric\" : \"sys.cpu.user\"," +
|
||||
"\"startTime\" : \"1000\"" +
|
||||
"}";
|
||||
// @formatter:on
|
||||
WebSocketRequest request = JsonUtil.getObjectMapper().readValue(json.getBytes(), WebSocketRequest.class);
|
||||
Assert.assertNotNull(request);
|
||||
Assert.assertEquals(AddSubscription.class, request.getClass());
|
||||
@@ -95,18 +95,18 @@ public class WebSocketRequestDeserializationTest {
|
||||
@Test
|
||||
public void testAddDeserializationWithTimeAndTags() throws Exception {
|
||||
// @formatter:off
|
||||
String json = "{" +
|
||||
"\"operation\" : \"add\"," +
|
||||
"\"sessionId\" : \"1234\"," +
|
||||
"\"metric\" : \"sys.cpu.user\"," +
|
||||
"\"tags\" : {" +
|
||||
"\"tag2\" : \"value2\"," +
|
||||
"\"tag1\" : \"value1\"" +
|
||||
"}," +
|
||||
"\"startTime\" : \"1000\"," +
|
||||
"\"endTime\" : \"2000\""+
|
||||
"}";
|
||||
// @formatter:on
|
||||
String json = "{" +
|
||||
"\"operation\" : \"add\"," +
|
||||
"\"sessionId\" : \"1234\"," +
|
||||
"\"metric\" : \"sys.cpu.user\"," +
|
||||
"\"tags\" : {" +
|
||||
"\"tag2\" : \"value2\"," +
|
||||
"\"tag1\" : \"value1\"" +
|
||||
"}," +
|
||||
"\"startTime\" : \"1000\"," +
|
||||
"\"endTime\" : \"2000\""+
|
||||
"}";
|
||||
// @formatter:on
|
||||
WebSocketRequest request = JsonUtil.getObjectMapper().readValue(json.getBytes(), WebSocketRequest.class);
|
||||
Assert.assertNotNull(request);
|
||||
Assert.assertEquals(AddSubscription.class, request.getClass());
|
||||
@@ -129,18 +129,18 @@ public class WebSocketRequestDeserializationTest {
|
||||
@Test
|
||||
public void testAddDeserializationWithStartAndDelayTimeAndTags() throws Exception {
|
||||
// @formatter:off
|
||||
String json = "{" +
|
||||
"\"operation\" : \"add\"," +
|
||||
"\"sessionId\" : \"1234\"," +
|
||||
"\"metric\" : \"sys.cpu.user\"," +
|
||||
"\"tags\" : {" +
|
||||
"\"tag2\" : \"value2\"," +
|
||||
"\"tag1\" : \"value1\"" +
|
||||
"}," +
|
||||
"\"startTime\" : \"1000\"," +
|
||||
"\"delayTime\" : \"500\"" +
|
||||
"}";
|
||||
// @formatter:on
|
||||
String json = "{" +
|
||||
"\"operation\" : \"add\"," +
|
||||
"\"sessionId\" : \"1234\"," +
|
||||
"\"metric\" : \"sys.cpu.user\"," +
|
||||
"\"tags\" : {" +
|
||||
"\"tag2\" : \"value2\"," +
|
||||
"\"tag1\" : \"value1\"" +
|
||||
"}," +
|
||||
"\"startTime\" : \"1000\"," +
|
||||
"\"delayTime\" : \"500\"" +
|
||||
"}";
|
||||
// @formatter:on
|
||||
WebSocketRequest request = JsonUtil.getObjectMapper().readValue(json.getBytes(), WebSocketRequest.class);
|
||||
Assert.assertNotNull(request);
|
||||
Assert.assertEquals(AddSubscription.class, request.getClass());
|
||||
|
||||
@@ -30,19 +30,19 @@ public class AuthCacheTest {
|
||||
|
||||
@AfterClass
|
||||
public static void after() {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
AuthCache.setSessionMaxAge(config.getSecurity());
|
||||
AuthCache.configure(config.getSecurity());
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("test", "test1");
|
||||
AuthenticationService.authenticate(token, cookie);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
|
||||
@@ -22,8 +22,8 @@ public class AuthenticationServiceTest {
|
||||
public static void before() {
|
||||
config = TestConfiguration.createMinimalConfigurationForTest();
|
||||
config.getSecurity().setSessionMaxAge(Integer.MAX_VALUE);
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.setSessionMaxAge(config.getSecurity());
|
||||
AuthCache.resetConfiguration();
|
||||
AuthCache.configure(config.getSecurity());
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -34,7 +34,7 @@ public class AuthenticationServiceTest {
|
||||
|
||||
@AfterClass
|
||||
public static void after() {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Test(expected = BadCredentialsException.class)
|
||||
|
||||
@@ -12,7 +12,7 @@ import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http.cookie.ClientCookieEncoder;
|
||||
@@ -70,14 +70,14 @@ public class HttpRequestDecoderTest {
|
||||
anonConfig = TestConfiguration.createMinimalConfigurationForTest();
|
||||
anonConfig.getSecurity().setAllowAnonymousHttpAccess(true);
|
||||
cookie = URLEncoder.encode(UUID.randomUUID().toString(), StandardCharsets.UTF_8.name());
|
||||
AuthCache.setSessionMaxAge(config.getSecurity());
|
||||
AuthCache.configure(config.getSecurity());
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("test", "test1");
|
||||
AuthenticationService.authenticate(token, cookie);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after() {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -86,7 +86,7 @@ public class HttpRequestDecoderTest {
|
||||
}
|
||||
|
||||
private void addCookie(FullHttpRequest request) {
|
||||
request.headers().set(Names.COOKIE, ClientCookieEncoder.STRICT.encode(Constants.COOKIE_NAME, cookie));
|
||||
request.headers().set(HttpHeaderNames.COOKIE, ClientCookieEncoder.STRICT.encode(Constants.COOKIE_NAME, cookie));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -218,10 +218,10 @@ public class HttpRequestDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testLookupPostWithNoLimit() throws Exception {
|
||||
// @formatter:off
|
||||
String content =
|
||||
// @formatter:off
|
||||
String content =
|
||||
"{\n" +
|
||||
" \"metric\": \"sys.cpu.user\"\n" +
|
||||
" \"metric\": \"sys.cpu.user\"\n" +
|
||||
"}";
|
||||
// @formatter:on
|
||||
decoder = new TestHttpQueryDecoder(config);
|
||||
@@ -255,8 +255,8 @@ public class HttpRequestDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testLookupPostWithLimit() throws Exception {
|
||||
// @formatter:off
|
||||
String content =
|
||||
// @formatter:off
|
||||
String content =
|
||||
"{\n" +
|
||||
" \"metric\": \"sys.cpu.user\",\n" +
|
||||
" \"limit\": 3000\n" +
|
||||
@@ -296,8 +296,8 @@ public class HttpRequestDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testLookupPostWithLimitAndTags() throws Exception {
|
||||
// @formatter:off
|
||||
String content =
|
||||
// @formatter:off
|
||||
String content =
|
||||
"{\n" +
|
||||
" \"metric\": \"sys.cpu.user\",\n" +
|
||||
" \"limit\": 3000,\n" +
|
||||
@@ -411,8 +411,8 @@ public class HttpRequestDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testSuggestPostWithValidType() throws Exception {
|
||||
// @formatter:off
|
||||
String content =
|
||||
// @formatter:off
|
||||
String content =
|
||||
"{\n" +
|
||||
" \"type\": \"metrics\"\n" +
|
||||
"}";
|
||||
@@ -450,8 +450,8 @@ public class HttpRequestDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testSuggestPostWithValidTypeAndQuery() throws Exception {
|
||||
// @formatter:off
|
||||
String content =
|
||||
// @formatter:off
|
||||
String content =
|
||||
"{\n" +
|
||||
" \"type\": \"metrics\",\n" +
|
||||
" \"q\": \"sys.cpu.user\"\n" +
|
||||
@@ -490,8 +490,8 @@ public class HttpRequestDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testSuggestPostWithValidTypeAndQueryAndMax() throws Exception {
|
||||
// @formatter:off
|
||||
String content =
|
||||
// @formatter:off
|
||||
String content =
|
||||
"{\n" +
|
||||
" \"type\": \"metrics\",\n" +
|
||||
" \"q\": \"sys.cpu.user\",\n" +
|
||||
@@ -616,7 +616,7 @@ public class HttpRequestDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testQueryEmptyTags() throws Exception {
|
||||
// @formatter:off
|
||||
// @formatter:off
|
||||
String content =
|
||||
"{\n"+
|
||||
" \"start\": 1356998400,\n"+
|
||||
@@ -665,7 +665,7 @@ public class HttpRequestDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testQueryPostAll() throws Exception {
|
||||
// @formatter:off
|
||||
// @formatter:off
|
||||
String content =
|
||||
"{\n"+
|
||||
" \"start\": 1356998400,\n"+
|
||||
@@ -762,7 +762,7 @@ public class HttpRequestDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testQueryPostGlobalAnnotations() throws Exception {
|
||||
// @formatter:off
|
||||
// @formatter:off
|
||||
String content = "" +
|
||||
"{"
|
||||
+ "\"start\":1447767369171,"
|
||||
@@ -803,8 +803,8 @@ public class HttpRequestDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testQueryPostRateOption() throws Exception {
|
||||
// @formatter:off
|
||||
String content =
|
||||
// @formatter:off
|
||||
String content =
|
||||
"{"
|
||||
+ "\"start\":1447767369171,"
|
||||
+ "\"queries\":"
|
||||
@@ -861,7 +861,7 @@ public class HttpRequestDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testPutMetricPost() throws Exception {
|
||||
// @formatter:off
|
||||
// @formatter:off
|
||||
Metric m = Metric.newBuilder()
|
||||
.name("sys.cpu.user")
|
||||
.value(TEST_TIME, 1.0D)
|
||||
|
||||
+19
-19
@@ -8,7 +8,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.HttpHeaders.Names;
|
||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
@@ -47,12 +47,12 @@ public class BasicAuthLoginRequestHandlerTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void before() throws Exception {
|
||||
AuthCache.setSessionMaxAge(TestConfiguration.createMinimalConfigurationForTest().getSecurity());
|
||||
AuthCache.configure(TestConfiguration.createMinimalConfigurationForTest().getSecurity());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void after() throws Exception {
|
||||
AuthCache.resetSessionMaxAge();
|
||||
AuthCache.resetConfiguration();
|
||||
}
|
||||
|
||||
@Before
|
||||
@@ -66,12 +66,12 @@ public class BasicAuthLoginRequestHandlerTest {
|
||||
Configuration config = TestConfiguration.createMinimalConfigurationForTest();
|
||||
|
||||
// @formatter:off
|
||||
String form =
|
||||
String form =
|
||||
"{\n" +
|
||||
" \"username\": \"test\",\n" +
|
||||
" \"username\": \"test\",\n" +
|
||||
" \"password\": \"test1\"\n" +
|
||||
"}";
|
||||
// @formatter:on
|
||||
"}";
|
||||
// @formatter:on
|
||||
DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/login");
|
||||
request.content().writeBytes(form.getBytes());
|
||||
|
||||
@@ -87,11 +87,11 @@ public class BasicAuthLoginRequestHandlerTest {
|
||||
Assert.assertNotNull(ctx.msg);
|
||||
Assert.assertTrue(ctx.msg instanceof DefaultFullHttpResponse);
|
||||
DefaultFullHttpResponse response = (DefaultFullHttpResponse) ctx.msg;
|
||||
Assert.assertEquals(HttpResponseStatus.OK, response.getStatus());
|
||||
Assert.assertTrue(response.headers().contains(Names.CONTENT_TYPE));
|
||||
Assert.assertEquals(Constants.JSON_TYPE, response.headers().get(Names.CONTENT_TYPE));
|
||||
Assert.assertTrue(response.headers().contains(Names.SET_COOKIE));
|
||||
Cookie c = ClientCookieDecoder.STRICT.decode(response.headers().get(Names.SET_COOKIE));
|
||||
Assert.assertEquals(HttpResponseStatus.OK, response.status());
|
||||
Assert.assertTrue(response.headers().contains(HttpHeaderNames.CONTENT_TYPE));
|
||||
Assert.assertEquals(Constants.JSON_TYPE, response.headers().get(HttpHeaderNames.CONTENT_TYPE));
|
||||
Assert.assertTrue(response.headers().contains(HttpHeaderNames.SET_COOKIE));
|
||||
Cookie c = ClientCookieDecoder.STRICT.decode(response.headers().get(HttpHeaderNames.SET_COOKIE));
|
||||
Assert.assertEquals(TestConfiguration.TIMELY_HTTP_ADDRESS_DEFAULT, c.domain());
|
||||
Assert.assertEquals(86400, c.maxAge());
|
||||
Assert.assertTrue(c.isHttpOnly());
|
||||
@@ -105,12 +105,12 @@ public class BasicAuthLoginRequestHandlerTest {
|
||||
Configuration config = TestConfiguration.createMinimalConfigurationForTest();
|
||||
|
||||
// @formatter:off
|
||||
String form =
|
||||
String form =
|
||||
"{\n" +
|
||||
" \"username\": \"test\",\n" +
|
||||
" \"username\": \"test\",\n" +
|
||||
" \"password\": \"test2\"\n" +
|
||||
"}";
|
||||
// @formatter:on
|
||||
"}";
|
||||
// @formatter:on
|
||||
DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/login");
|
||||
request.content().writeBytes(form.getBytes());
|
||||
|
||||
@@ -126,9 +126,9 @@ public class BasicAuthLoginRequestHandlerTest {
|
||||
Assert.assertNotNull(ctx.msg);
|
||||
Assert.assertTrue(ctx.msg instanceof DefaultFullHttpResponse);
|
||||
DefaultFullHttpResponse response = (DefaultFullHttpResponse) ctx.msg;
|
||||
Assert.assertEquals(HttpResponseStatus.UNAUTHORIZED, response.getStatus());
|
||||
Assert.assertTrue(response.headers().contains(Names.CONTENT_TYPE));
|
||||
Assert.assertEquals(Constants.JSON_TYPE, response.headers().get(Names.CONTENT_TYPE));
|
||||
Assert.assertEquals(HttpResponseStatus.UNAUTHORIZED, response.status());
|
||||
Assert.assertTrue(response.headers().contains(HttpHeaderNames.CONTENT_TYPE));
|
||||
Assert.assertEquals(Constants.JSON_TYPE, response.headers().get(HttpHeaderNames.CONTENT_TYPE));
|
||||
}
|
||||
|
||||
}
|
||||
Loaded 100 of 122 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user