aboutsummaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authorBjørn Meland <bjormel@users.noreply.github.com>2019-12-12 10:58:21 +0100
committerGitHub <noreply@github.com>2019-12-12 10:58:21 +0100
commit2de75cc16ce069fd9b36994101e4dd76de693220 (patch)
treeb8378027f51b341657280487171486ae927d5c6b /controller-server
parentfd90e66adf12ecfa94e55295e2d9657274d952d3 (diff)
parent22e0baee45c3d39b95dc4fdbdfb5f99e863aec69 (diff)
Merge pull request #11529 from vespa-engine/frodelu/remove-statuspage
Remove Statuspage.io proxy
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageClient.java117
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageProxyHandler.java67
-rw-r--r--controller-server/src/main/resources/configdefinitions/statuspage.def4
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageClientTest.java44
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageProxyApiTest.java93
5 files changed, 0 insertions, 325 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageClient.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageClient.java
deleted file mode 100644
index 93213172048..00000000000
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageClient.java
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.controller.restapi.statuspage;
-
-import com.yahoo.slime.Slime;
-import com.yahoo.vespa.config.SlimeUtils;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.time.Duration;
-import java.util.Objects;
-import java.util.Optional;
-
-/**
- * A basic client for the StatusPage API.
- *
- * @author mpolden
- */
-public class StatusPageClient {
-
- private static final Duration requestTimeout = Duration.ofSeconds(30);
-
- private final URI url;
- private final String key;
-
- private StatusPageClient(URI url, String key) {
- this.url = Objects.requireNonNull(url, "url cannot be null");
- this.key = Objects.requireNonNull(key, "key cannot be null");
- }
-
- /** GET given page and return response body as slime */
- public Slime get(String page, Optional<String> since) {
- HttpGet get = new HttpGet(pageUrl(page, since));
- try (CloseableHttpClient client = client()) {
- try (CloseableHttpResponse response = client.execute(get)) {
- if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
- throw new IllegalArgumentException("Received status " + response.getStatusLine().getStatusCode() +
- " from StatusPage");
- }
- byte[] body = EntityUtils.toByteArray(response.getEntity());
- return SlimeUtils.jsonToSlime(body);
- }
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
-
- URI pageUrl(String page, Optional<String> since) {
- if (!allowAccess(page)) {
- throw new IllegalArgumentException("Invalid resource: '" + page + "'");
- }
- URIBuilder builder = new URIBuilder(url)
- .setPath("/api/v2/" + page + ".json")
- .setParameter("api_key", key);
- since.ifPresent(s -> builder.setParameter("since", s));
- try {
- return builder.build();
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static StatusPageClient create(URI url, String secret) {
- String[] parts = secret.split(":");
- if (parts.length != 2) {
- throw new IllegalArgumentException("Invalid secret");
- }
- String pageId = parts[0];
- String apiKey = parts[1];
- if (isDefault(url)) {
- // Rewrite URL to include page ID
- try {
- url = new URIBuilder(url).setHost(pageId + "." + url.getHost()).build();
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
- }
- return new StatusPageClient(url, apiKey);
- }
-
- private static CloseableHttpClient client() {
- HttpClientBuilder builder = HttpClients.custom();
- RequestConfig requestConfig = RequestConfig.custom()
- .setConnectionRequestTimeout((int) requestTimeout.toMillis())
- .setConnectTimeout((int) requestTimeout.toMillis())
- .setSocketTimeout((int) requestTimeout.toMillis())
- .build();
- return builder.setDefaultRequestConfig(requestConfig)
- .setUserAgent("vespa-statuspage-client")
- .build();
- }
-
- /** Returns whether given page is allowed to be accessed */
- private static boolean allowAccess(String page) {
- switch (page) {
- case "incidents":
- case "scheduled-maintenances":
- return true;
- }
- return false;
- }
-
- private static boolean isDefault(URI url) {
- return "statuspage.io".equals(url.getHost());
- }
-
-}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageProxyHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageProxyHandler.java
deleted file mode 100644
index 8c445fe3a0a..00000000000
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageProxyHandler.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.controller.restapi.statuspage;
-
-import com.google.inject.Inject;
-import com.yahoo.container.jdisc.HttpRequest;
-import com.yahoo.container.jdisc.HttpResponse;
-import com.yahoo.container.jdisc.LoggingRequestHandler;
-import com.yahoo.container.jdisc.secretstore.SecretStore;
-import com.yahoo.slime.Slime;
-import com.yahoo.restapi.ErrorResponse;
-import com.yahoo.restapi.Path;
-import com.yahoo.restapi.SlimeJsonResponse;
-import com.yahoo.vespa.hosted.controller.statuspage.config.StatuspageConfig;
-import com.yahoo.yolean.Exceptions;
-
-import java.net.URI;
-import java.util.Optional;
-import java.util.logging.Level;
-
-/**
- * Proxies requests from the controller to StatusPage.
- *
- * @author andreer
- * @author mpolden
- */
-@SuppressWarnings("unused") // Handler
-public class StatusPageProxyHandler extends LoggingRequestHandler {
-
- private static final String secretKey = "vespa_hosted.controller.statuspage_api_key";
-
- private final SecretStore secretStore;
- private final URI apiUrl;
-
- @Inject
- public StatusPageProxyHandler(Context parentCtx, SecretStore secretStore, StatuspageConfig config) {
- super(parentCtx);
- this.secretStore = secretStore;
- this.apiUrl = URI.create(config.apiUrl());
- }
-
- @Override
- public HttpResponse handle(HttpRequest request) {
- try {
- switch (request.getMethod()) {
- case GET: return handleGET(request);
- default: return ErrorResponse.methodNotAllowed("Method '" + request.getMethod() + "' is not supported");
- }
- } catch (IllegalArgumentException e) {
- return ErrorResponse.badRequest(Exceptions.toMessageString(e));
- } catch (RuntimeException e) {
- log.log(Level.WARNING, "Unexpected error handling '" + request.getUri() + "'", e);
- return ErrorResponse.internalServerError(Exceptions.toMessageString(e));
- }
- }
-
- private HttpResponse handleGET(HttpRequest request) {
- Path path = new Path(request.getUri());
- if (!path.matches("/statuspage/v1/{page}")) {
- return ErrorResponse.notFoundError("Nothing at " + path);
- }
- StatusPageClient client = StatusPageClient.create(apiUrl, secretStore.getSecret(secretKey));
- Optional<String> since = Optional.ofNullable(request.getProperty("since"));
- Slime statusPageResponse = client.get(path.get("page"), since);
- return new SlimeJsonResponse(statusPageResponse);
- }
-
-}
diff --git a/controller-server/src/main/resources/configdefinitions/statuspage.def b/controller-server/src/main/resources/configdefinitions/statuspage.def
deleted file mode 100644
index db8b034f99b..00000000000
--- a/controller-server/src/main/resources/configdefinitions/statuspage.def
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-namespace=vespa.hosted.controller.statuspage.config
-
-apiUrl string default=https://statuspage.io
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageClientTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageClientTest.java
deleted file mode 100644
index 378e4298552..00000000000
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageClientTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.controller.restapi.statuspage;
-
-import org.junit.Test;
-
-import java.net.URI;
-import java.util.Optional;
-
-import static org.junit.Assert.*;
-
-/**
- * @author mpolden
- */
-public class StatusPageClientTest {
-
- @Test
- public void test_url_building() {
- {
- URI apiUrl = URI.create("https://statuspage.io");
- String secret = "testpage:testkey";
- assertEquals("https://testpage.statuspage.io/api/v2/incidents.json?api_key=testkey",
- StatusPageClient.create(apiUrl, secret).pageUrl("incidents", Optional.empty()).toString());
- assertEquals("https://testpage.statuspage.io/api/v2/scheduled-maintenances.json?api_key=testkey&since=2015-01-01T00%3A00%2B00%3A00",
- StatusPageClient.create(apiUrl, secret).pageUrl("scheduled-maintenances",
- Optional.of("2015-01-01T00:00+00:00")).toString());
- }
-
- {
- URI apiUrl = URI.create("http://foo.bar");
- assertEquals("http://foo.bar/api/v2/incidents.json?api_key=testkey",
- StatusPageClient.create(apiUrl, "testpage:testkey").pageUrl("incidents", Optional.empty()).toString());
- }
-
- {
- try {
- URI apiUrl = URI.create("http://foo.bar");
- assertEquals("http://foo.bar/api/v2/incidents.json?api_key=testkey",
- StatusPageClient.create(apiUrl, "").pageUrl("incidents", Optional.empty()).toString());
- fail("Expected exception");
- } catch (IllegalArgumentException ignored) {}
- }
- }
-
-}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageProxyApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageProxyApiTest.java
deleted file mode 100644
index f39914fd8fb..00000000000
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/statuspage/StatusPageProxyApiTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.hosted.controller.restapi.statuspage;
-
-import com.github.tomakehurst.wiremock.junit.WireMockRule;
-import com.yahoo.application.Networking;
-import com.yahoo.application.container.JDisc;
-import com.yahoo.application.container.handler.Request;
-import com.yahoo.application.container.handler.Response;
-import com.yahoo.vespa.hosted.controller.integration.SecretStoreMock;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-
-import java.io.IOException;
-
-import static com.github.tomakehurst.wiremock.client.WireMock.get;
-import static com.github.tomakehurst.wiremock.client.WireMock.okJson;
-import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
-import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
-import static org.junit.Assert.assertEquals;
-
-/**
- * @author mpolden
- */
-public class StatusPageProxyApiTest {
-
- private JDisc container;
-
- @Before
- public void startContainer() {
- container = JDisc.fromServicesXml(servicesXml(), Networking.disable);
- secretStore().setSecret("vespa_hosted.controller.statuspage_api_key", "page-id:secret");
- }
-
- @After
- public void stopContainer() {
- container.close();
- secretStore().clear();
- }
-
- @Rule
- public final WireMockRule wireMock = new WireMockRule(options().dynamicPort(), true);
-
- @Test
- public void test_proxy() throws Exception {
- // Invalid requests
- assertResponse("/statuspage/v1/", "{\"error-code\":\"NOT_FOUND\",\"message\":\"Nothing at path '/statuspage/v1'\"}", 404);
- assertResponse("/statuspage/v1/invalid", "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Invalid resource: 'invalid'\"}", 400);
- assertResponse(Request.Method.POST, "/statuspage/v1/invalid", "{\"error-code\":\"METHOD_NOT_ALLOWED\",\"message\":\"Method 'POST' is not supported\"}", 405);
-
- // Mock responses from StatusPage
- wireMock.stubFor(get(urlEqualTo("/api/v2/incidents.json?api_key=secret"))
- .willReturn(okJson("{\"incidents\":[]}")));
- wireMock.stubFor(get(urlEqualTo("/api/v2/scheduled-maintenances.json?api_key=secret"))
- .willReturn(okJson("{\"scheduled_maintenances\":[]}")));
-
- assertResponse("/statuspage/v1/incidents", "{\"incidents\":[]}", 200);
- assertResponse("/statuspage/v1/scheduled-maintenances", "{\"scheduled_maintenances\":[]}", 200);
- }
-
- private void assertResponse(String path, String expectedResponse, int expectedStatusCode) throws IOException {
- assertResponse(Request.Method.GET, path, expectedResponse, expectedStatusCode);
- }
-
- private void assertResponse(Request.Method method, String path, String expectedResponse, int expectedStatusCode) throws IOException {
- Response response = container.handleRequest(new Request("http://localhost:8080" + path, new byte[0], method));
- assertEquals(expectedResponse, response.getBodyAsString());
- assertEquals("Status code", expectedStatusCode, response.getStatus());
- assertEquals("application/json; charset=UTF-8", response.getHeaders().getFirst("Content-Type"));
- }
-
- private SecretStoreMock secretStore() {
- return (SecretStoreMock) container.components().getComponent(SecretStoreMock.class.getName());
- }
-
- private String servicesXml() {
- String statusPageApiUrl = "http://127.0.0.1:" + wireMock.port();
- return "<container version='1.0'>\n" +
- " <config name='vespa.hosted.controller.statuspage.config.statuspage'>\n" +
- " <apiUrl>" + statusPageApiUrl + "</apiUrl>\n" +
- " </config>\n" +
- " <component id='com.yahoo.vespa.hosted.controller.integration.SecretStoreMock'/>\n" +
- " <handler id='com.yahoo.vespa.hosted.controller.restapi.statuspage.StatusPageProxyHandler'>\n" +
- " <binding>http://*/statuspage/v1/*</binding>\n" +
- " </handler>\n" +
- " <http>\n" +
- " <server id='default' port='8080'/>\n" +
- " </http>\n" +
- "</container>";
- }
-
-}