aboutsummaryrefslogtreecommitdiffstats
path: root/clustercontroller-apps
diff options
context:
space:
mode:
authorHarald Musum <musum@verizonmedia.com>2020-12-01 14:13:13 +0100
committerHarald Musum <musum@verizonmedia.com>2020-12-01 14:13:13 +0100
commit9c3c3967f9574c08da66b5d2bea26e6c298f0546 (patch)
tree32fcd726dad3c760c658852f6790857ad1c57027 /clustercontroller-apps
parent008477111ac92e2eec81596a5037a205bbea53ff (diff)
Move code in clustercontroller-apputils into clustercontroller-apps
Code in clustercontroller-apputils is now only used from clustercontroller-apps, so those two modules can be merged
Diffstat (limited to 'clustercontroller-apps')
-rw-r--r--clustercontroller-apps/pom.xml6
-rw-r--r--clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscHttpRequestHandler.java128
-rw-r--r--clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscMetricWrapper.java52
-rw-r--r--clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/package-info.java5
-rw-r--r--clustercontroller-apps/src/test/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscHttpRequestHandlerTest.java47
-rw-r--r--clustercontroller-apps/src/test/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscMetricWrapperTest.java46
6 files changed, 278 insertions, 6 deletions
diff --git a/clustercontroller-apps/pom.xml b/clustercontroller-apps/pom.xml
index 38f10dd74b6..10fa263a8db 100644
--- a/clustercontroller-apps/pom.xml
+++ b/clustercontroller-apps/pom.xml
@@ -31,12 +31,6 @@
</dependency>
<dependency>
<groupId>com.yahoo.vespa</groupId>
- <artifactId>clustercontroller-apputil</artifactId>
- <version>${project.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>com.yahoo.vespa</groupId>
<artifactId>clustercontroller-core</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
diff --git a/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscHttpRequestHandler.java b/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscHttpRequestHandler.java
new file mode 100644
index 00000000000..f518fe23fe6
--- /dev/null
+++ b/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscHttpRequestHandler.java
@@ -0,0 +1,128 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.clustercontroller.apputil.communication.http;
+
+import com.yahoo.container.jdisc.LoggingRequestHandler;
+import com.yahoo.jdisc.HeaderFields;
+import com.yahoo.jdisc.Response;
+import com.yahoo.jdisc.handler.CompletionHandler;
+import com.yahoo.text.Utf8;
+import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequest;
+import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequestHandler;
+import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpResult;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+import java.util.logging.Logger;
+
+/**
+ * Note. This class is tested through apache http instance test, using this as other endpoint.
+ *
+ * @author Haakon Humberset
+ * @author Harald Musum
+ * @author Vegard Sjonfjell
+ */
+public class JDiscHttpRequestHandler extends LoggingRequestHandler {
+
+ private static final Logger log = Logger.getLogger(JDiscHttpRequestHandler.class.getName());
+ private final HttpRequestHandler requestHandler;
+
+ public JDiscHttpRequestHandler(HttpRequestHandler handler, LoggingRequestHandler.Context parentCtx) {
+ super(parentCtx);
+ this.requestHandler = handler;
+ }
+
+ static class EmptyCompletionHandler implements CompletionHandler {
+ @Override
+ public void completed() { }
+ @Override
+ public void failed(Throwable throwable) { }
+ }
+
+ @Override
+ public com.yahoo.container.jdisc.HttpResponse handle(com.yahoo.container.jdisc.HttpRequest request) {
+ final HttpRequest legacyRequest = new HttpRequest();
+ final com.yahoo.jdisc.http.HttpRequest jDiscRequest = request.getJDiscRequest();
+
+ legacyRequest.setScheme(request.getUri().getScheme());
+ legacyRequest.setHost(request.getUri().getHost());
+ setOperation(legacyRequest, request.getMethod());
+ legacyRequest.setPort(request.getUri().getPort());
+ legacyRequest.setPath(request.getUri().getPath());
+ copyPostData(request, legacyRequest);
+ copyRequestHeaders(legacyRequest, jDiscRequest);
+ copyParameters(legacyRequest, jDiscRequest);
+ legacyRequest.setTimeout(Duration.ofMinutes(60).toMillis());
+
+ try {
+ final HttpResult result = requestHandler.handleRequest(legacyRequest);
+ log.fine("Got result " + result.toString(true));
+ return copyResponse(result);
+ } catch (Exception e) {
+ log.warning("Caught exception while handling request: " + e.getMessage());
+ return new com.yahoo.container.jdisc.HttpResponse(500) {
+ @Override
+ public void render(OutputStream outputStream) throws IOException {
+ outputStream.write(Utf8.toBytes(e.getMessage()));
+ }
+ };
+ }
+ }
+
+ static HttpRequest setOperation(HttpRequest request, com.yahoo.jdisc.http.HttpRequest.Method method) {
+ switch (method) {
+ case GET: return request.setHttpOperation(HttpRequest.HttpOp.GET);
+ case POST: return request.setHttpOperation(HttpRequest.HttpOp.POST);
+ case PUT: return request.setHttpOperation(HttpRequest.HttpOp.PUT);
+ case DELETE: return request.setHttpOperation(HttpRequest.HttpOp.DELETE);
+ default: throw new IllegalStateException("Unhandled method " + method);
+ }
+ }
+
+ private com.yahoo.container.jdisc.HttpResponse copyResponse(final HttpResult result) {
+ return new com.yahoo.container.jdisc.HttpResponse(result.getHttpReturnCode()) {
+ @Override
+ public void render(OutputStream outputStream) throws IOException {
+ outputStream.write(Utf8.toBytes(result.getContent().toString()));
+ }
+
+ @Override
+ public void complete(){
+ copyResponseHeaders(result, getJdiscResponse());
+ }
+ };
+ }
+
+ private void copyPostData(com.yahoo.container.jdisc.HttpRequest request, HttpRequest legacyRequest) {
+ try {
+ legacyRequest.setPostContent(new String(request.getData().readAllBytes(), StandardCharsets.UTF_8));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static void copyParameters(HttpRequest legacyRequest, com.yahoo.jdisc.http.HttpRequest jDiscRequest) {
+ for (String key : jDiscRequest.parameters().keySet()) {
+ for (String value : jDiscRequest.parameters().get(key)) {
+ legacyRequest.addUrlOption(key, value);
+ }
+ }
+ }
+
+ private static void copyRequestHeaders(HttpRequest legacyRequest, com.yahoo.jdisc.http.HttpRequest jDiscRequest) {
+ for (String key : jDiscRequest.headers().keySet()) {
+ for (String value : jDiscRequest.headers().get(key)) {
+ legacyRequest.addHttpHeader(key, value);
+ }
+ }
+ }
+
+ private static HeaderFields copyResponseHeaders(HttpResult result, Response response) {
+ HeaderFields headers = new HeaderFields();
+ for (HttpRequest.KeyValuePair keyValuePair : result.getHeaders()) {
+ response.headers().put((keyValuePair.getKey()), keyValuePair.getValue());
+ }
+ return headers;
+ }
+
+}
diff --git a/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscMetricWrapper.java b/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscMetricWrapper.java
new file mode 100644
index 00000000000..559eaee4821
--- /dev/null
+++ b/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscMetricWrapper.java
@@ -0,0 +1,52 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.clustercontroller.apputil.communication.http;
+
+import com.yahoo.jdisc.Metric;
+import com.yahoo.vespa.clustercontroller.utils.util.MetricReporter;
+
+import java.util.logging.Logger;
+
+public class JDiscMetricWrapper implements MetricReporter {
+
+ private final Object lock = new Object();
+ private Metric m;
+
+ private static class ContextWrapper implements MetricReporter.Context {
+ Metric.Context wrappedContext;
+
+ public ContextWrapper(Metric.Context wrapped) {
+ this.wrappedContext = wrapped;
+ }
+ }
+
+ public JDiscMetricWrapper(Metric m) {
+ this.m = m;
+ }
+
+ public void updateMetricImplementation(Metric m) {
+ synchronized (lock) {
+ this.m = m;
+ }
+ }
+
+ public void set(String s, Number number, MetricReporter.Context context) {
+ synchronized (lock) {
+ ContextWrapper cw = (ContextWrapper) context;
+ m.set(s, number, cw == null ? null : cw.wrappedContext);
+ }
+ }
+
+ public void add(String s, Number number, MetricReporter.Context context) {
+ synchronized (lock) {
+ ContextWrapper cw = (ContextWrapper) context;
+ m.add(s, number, cw == null ? null : cw.wrappedContext);
+ }
+ }
+
+ public MetricReporter.Context createContext(java.util.Map<java.lang.String,?> stringMap) {
+ synchronized (lock) {
+ return new ContextWrapper(m.createContext(stringMap));
+ }
+ }
+
+}
diff --git a/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/package-info.java b/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/package-info.java
new file mode 100644
index 00000000000..5d09603bea6
--- /dev/null
+++ b/clustercontroller-apps/src/main/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/package-info.java
@@ -0,0 +1,5 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+@ExportPackage
+package com.yahoo.vespa.clustercontroller.apputil.communication.http;
+
+import com.yahoo.osgi.annotation.ExportPackage;
diff --git a/clustercontroller-apps/src/test/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscHttpRequestHandlerTest.java b/clustercontroller-apps/src/test/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscHttpRequestHandlerTest.java
new file mode 100644
index 00000000000..2326189a369
--- /dev/null
+++ b/clustercontroller-apps/src/test/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscHttpRequestHandlerTest.java
@@ -0,0 +1,47 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.clustercontroller.apputil.communication.http;
+
+import com.yahoo.vespa.clustercontroller.utils.communication.http.HttpRequest;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * The handler is mostly tested through the apache tests, using it as endpoint here..
+ * This test class is just to test some special cases.
+ */
+public class JDiscHttpRequestHandlerTest {
+
+ private ThreadPoolExecutor executor;
+
+ @Before
+ public void setUp() {
+ executor = new ThreadPoolExecutor(10, 100, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1000));
+ }
+
+ public void tearDown() {
+ executor.shutdown();
+ }
+
+ @Test
+ public void testInvalidMethod() throws Exception {
+ try{
+ HttpRequest request = new HttpRequest();
+ JDiscHttpRequestHandler.setOperation(request, com.yahoo.jdisc.http.HttpRequest.Method.CONNECT);
+ fail("Control should not reach here");
+ } catch (IllegalStateException e) {
+ assertEquals("Unhandled method CONNECT", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testNothingButAddCoverage() throws Exception {
+ new JDiscHttpRequestHandler.EmptyCompletionHandler().failed(null);
+ }
+}
diff --git a/clustercontroller-apps/src/test/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscMetricWrapperTest.java b/clustercontroller-apps/src/test/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscMetricWrapperTest.java
new file mode 100644
index 00000000000..13abfa0ecd5
--- /dev/null
+++ b/clustercontroller-apps/src/test/java/com/yahoo/vespa/clustercontroller/apputil/communication/http/JDiscMetricWrapperTest.java
@@ -0,0 +1,46 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.clustercontroller.apputil.communication.http;
+
+import com.yahoo.jdisc.Metric;
+import org.junit.Test;
+
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class JDiscMetricWrapperTest {
+
+ class MetricImpl implements Metric {
+ int calls = 0;
+ @Override
+ public void set(String s, Number number, Context context) { ++calls; }
+ @Override
+ public void add(String s, Number number, Context context) { ++calls; }
+ @Override
+ public Context createContext(Map<String, ?> stringMap) {
+ ++calls;
+ return new Context() {};
+ }
+ };
+
+ @Test
+ public void testSimple() {
+ MetricImpl impl1 = new MetricImpl();
+ MetricImpl impl2 = new MetricImpl();
+ JDiscMetricWrapper wrapper = new JDiscMetricWrapper(impl1);
+ wrapper.add("foo", 234, null);
+ wrapper.set("bar", 234, null);
+ assertTrue(wrapper.createContext(null) != null);
+ assertEquals(3, impl1.calls);
+ impl1.calls = 0;
+ wrapper.updateMetricImplementation(impl2);
+ wrapper.add("foo", 234, wrapper.createContext(null));
+ wrapper.set("bar", 234, wrapper.createContext(null));
+ assertTrue(wrapper.createContext(null) != null);
+ assertEquals(0, impl1.calls);
+ assertEquals(5, impl2.calls);
+
+ }
+
+}