summaryrefslogtreecommitdiffstats
path: root/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/FlagsHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/FlagsHandler.java')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/FlagsHandler.java94
1 files changed, 94 insertions, 0 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/FlagsHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/FlagsHandler.java
new file mode 100644
index 00000000000..3b4194fc474
--- /dev/null
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/FlagsHandler.java
@@ -0,0 +1,94 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.config.server.http.flags;
+
+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.restapi.Path;
+import com.yahoo.vespa.config.server.http.HttpHandler;
+import com.yahoo.vespa.config.server.http.NotFoundException;
+import com.yahoo.vespa.configserver.flags.FlagsDb;
+import com.yahoo.vespa.flags.FlagId;
+import com.yahoo.vespa.flags.Flags;
+import com.yahoo.vespa.flags.json.FlagData;
+
+import java.net.URI;
+import java.util.Objects;
+
+/**
+ * Handles /flags/v1 requests
+ *
+ * @author hakonhall
+ */
+public class FlagsHandler extends HttpHandler {
+ private final FlagsDb flagsDb;
+
+ @Inject
+ public FlagsHandler(LoggingRequestHandler.Context context, FlagsDb flagsDb) {
+ super(context);
+ this.flagsDb = flagsDb;
+ }
+
+ @Override
+ protected HttpResponse handleGET(HttpRequest request) {
+ Path path = new Path(request.getUri().getPath());
+ if (path.matches("/flags/v1")) return new V1Response(flagsV1Uri(request));
+ if (path.matches("/flags/v1/data")) return getFlagDataList(request);
+ if (path.matches("/flags/v1/data/{flagId}")) return getFlagData(findFlagId(request, path));
+ throw new NotFoundException("Nothing at path '" + path + "'");
+ }
+
+ @Override
+ protected HttpResponse handlePUT(HttpRequest request) {
+ Path path = new Path(request.getUri().getPath());
+ if (path.matches("/flags/v1/data/{flagId}")) return putFlagData(request, findFlagId(request, path));
+ throw new NotFoundException("Nothing at path '" + path + "'");
+ }
+
+ @Override
+ protected HttpResponse handleDELETE(HttpRequest request) {
+ Path path = new Path(request.getUri().getPath());
+ if (path.matches("/flags/v1/data/{flagId}")) return deleteFlagData(findFlagId(request, path));
+ throw new NotFoundException("Nothing at path '" + path + "'");
+ }
+
+ private String flagsV1Uri(HttpRequest request) {
+ URI uri = request.getUri();
+ return uri.getScheme() + "://" + uri.getHost() + ":" + uri.getPort() + "/flags/v1";
+ }
+
+ private HttpResponse getFlagDataList(HttpRequest request) {
+ return new FlagDataListResponse(flagsV1Uri(request), flagsDb.getAllFlags(),
+ Objects.equals(request.getProperty("recursive"), "true"));
+ }
+
+ private HttpResponse getFlagData(FlagId flagId) {
+ FlagData data = flagsDb.getValue(flagId).orElseThrow(() -> new NotFoundException("Flag " + flagId + " not set"));
+ return new FlagDataResponse(data);
+ }
+
+ private HttpResponse putFlagData(HttpRequest request, FlagId flagId) {
+ flagsDb.setValue(flagId, FlagData.deserialize(request.getData()));
+
+ // The set & get is not atomic, but no harm is done in showing an outdated flag value in the response.
+ return getFlagData(flagId);
+ }
+
+ private HttpResponse deleteFlagData(FlagId flagId) {
+ flagsDb.removeValue(flagId);
+ return new OKResponse();
+ }
+
+ private FlagId findFlagId(HttpRequest request, Path path) {
+ FlagId flagId = new FlagId(path.get("flagId"));
+
+ if (!Objects.equals(request.getProperty("force"), "true")) {
+ if (Flags.getAllFlags().stream().noneMatch(definition -> flagId.equals(definition.getUnboundFlag().id()))) {
+ throw new NotFoundException("There is no flag '" + flagId + "' (use ?force=true to override)");
+ }
+ }
+
+ return flagId;
+ }
+}