diff options
20 files changed, 136 insertions, 261 deletions
diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSource.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSource.java index 90709951dec..b1ffc05e70c 100644 --- a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSource.java +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSource.java @@ -5,7 +5,6 @@ import com.google.inject.Inject; import com.yahoo.vespa.configserver.flags.db.BootstrapFlagSource; import com.yahoo.vespa.configserver.flags.db.ZooKeeperFlagSource; import com.yahoo.vespa.flags.OrderedFlagSource; -import com.yahoo.vespa.flags.persistence.FlagsDb; import java.nio.file.FileSystem; import java.nio.file.FileSystems; diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/FlagsDb.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/FlagsDb.java new file mode 100644 index 00000000000..2c29ae0b818 --- /dev/null +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/FlagsDb.java @@ -0,0 +1,25 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.configserver.flags; + +import com.yahoo.vespa.flags.FlagId; +import com.yahoo.vespa.flags.json.FlagData; + +import java.util.Map; +import java.util.Optional; + +/** + * @author hakonhall + */ +public interface FlagsDb { + /** Get the String value of the flag. */ + Optional<FlagData> getValue(FlagId flagId); + + /** Set the String value of the flag. */ + void setValue(FlagId flagId, FlagData data); + + /** Remove the flag value if it exists. */ + void removeValue(FlagId flagId); + + /** Get all flags that have been set. */ + Map<FlagId, FlagData> getAllFlags(); +} diff --git a/flags/src/main/java/com/yahoo/vespa/flags/persistence/FlagsDb.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImpl.java index 2ed762f2895..5058358ba03 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/persistence/FlagsDb.java +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImpl.java @@ -1,8 +1,9 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.flags.persistence; +package com.yahoo.vespa.configserver.flags.db; import com.google.inject.Inject; import com.yahoo.path.Path; +import com.yahoo.vespa.configserver.flags.FlagsDb; import com.yahoo.vespa.curator.Curator; import com.yahoo.vespa.flags.FlagId; import com.yahoo.vespa.flags.json.FlagData; @@ -19,15 +20,14 @@ import java.util.stream.Collectors; /** * @author hakonhall */ -public class FlagsDb { - +public class FlagsDbImpl implements FlagsDb { private static final Path ROOT_PATH = Path.fromString("/flags/v1"); private final Curator curator; private final Curator.DirectoryCache cache; @Inject - public FlagsDb(Curator curator) { + public FlagsDbImpl(Curator curator) { this.curator = curator; curator.create(ROOT_PATH); ExecutorService executorService = Executors.newFixedThreadPool(1); @@ -35,28 +35,28 @@ public class FlagsDb { cache.start(); } - /** Get the String value of the flag. */ + @Override public Optional<FlagData> getValue(FlagId flagId) { return Optional.ofNullable(cache.getCurrentData(getZkPathFor(flagId))) - .map(ChildData::getData) - .map(FlagData::deserializeUtf8Json); + .map(ChildData::getData) + .map(FlagData::deserializeUtf8Json); } - /** Set the String value of the flag. */ + @Override public void setValue(FlagId flagId, FlagData data) { curator.set(getZkPathFor(flagId), data.serializeToUtf8Json()); } - /** Get all flags that have been set. */ + @Override public Map<FlagId, FlagData> getAllFlags() { List<ChildData> dataList = cache.getCurrentData(); return dataList.stream() - .map(ChildData::getData) - .map(FlagData::deserializeUtf8Json) - .collect(Collectors.toMap(FlagData::id, Function.identity())); + .map(ChildData::getData) + .map(FlagData::deserializeUtf8Json) + .collect(Collectors.toMap(FlagData::id, Function.identity())); } - /** Remove the flag value if it exists. */ + @Override public void removeValue(FlagId flagId) { curator.delete(getZkPathFor(flagId)); } @@ -64,5 +64,4 @@ public class FlagsDb { private static Path getZkPathFor(FlagId flagId) { return ROOT_PATH.append(flagId.toString()); } - } diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/ZooKeeperFlagSource.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/ZooKeeperFlagSource.java index e6ab3f5b387..4a9d604b4bd 100644 --- a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/ZooKeeperFlagSource.java +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/ZooKeeperFlagSource.java @@ -1,7 +1,7 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.configserver.flags.db; -import com.yahoo.vespa.flags.persistence.FlagsDb; +import com.yahoo.vespa.configserver.flags.FlagsDb; import com.yahoo.vespa.flags.FetchVector; import com.yahoo.vespa.flags.FlagId; import com.yahoo.vespa.flags.FlagSource; diff --git a/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSourceTest.java b/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSourceTest.java index b2f891326fc..d0d1d61628c 100644 --- a/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSourceTest.java +++ b/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSourceTest.java @@ -7,7 +7,6 @@ import com.yahoo.vespa.flags.FetchVector; import com.yahoo.vespa.flags.FlagId; import com.yahoo.vespa.flags.Flags; import com.yahoo.vespa.flags.RawFlag; -import com.yahoo.vespa.flags.persistence.FlagsDb; import com.yahoo.vespa.test.file.TestFileSystem; import org.junit.After; import org.junit.Before; @@ -104,4 +103,4 @@ public class ConfigServerFlagSourceTest { assertFalse(rawFlag2.isPresent()); verify(flagsDb, times(1)).getValue(flagId2); } -} +}
\ No newline at end of file diff --git a/flags/src/test/java/com/yahoo/vespa/flags/persistence/FlagsDbTest.java b/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImplTest.java index 5102305af90..ecc9bacb081 100644 --- a/flags/src/test/java/com/yahoo/vespa/flags/persistence/FlagsDbTest.java +++ b/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImplTest.java @@ -1,5 +1,5 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.flags.persistence; +package com.yahoo.vespa.configserver.flags.db; import com.yahoo.vespa.curator.mock.MockCurator; import com.yahoo.vespa.flags.FetchVector; @@ -23,11 +23,11 @@ import static org.junit.Assert.assertTrue; /** * @author hakonhall */ -public class FlagsDbTest { +public class FlagsDbImplTest { @Test public void test() { MockCurator curator = new MockCurator(); - FlagsDb db = new FlagsDb(curator); + FlagsDbImpl db = new FlagsDbImpl(curator); Condition condition1 = new Condition(Condition.Type.WHITELIST, FetchVector.Dimension.HOSTNAME, "host1"); Rule rule1 = new Rule(Optional.of(JsonNodeRawFlag.fromJson("13")), condition1); @@ -39,8 +39,8 @@ public class FlagsDbTest { assertTrue(dataCopy.isPresent()); assertEquals("{\"id\":\"id\",\"rules\":[{\"conditions\":[{\"type\":\"whitelist\",\"dimension\":\"hostname\"," + - "\"values\":[\"host1\"]}],\"value\":13}],\"attributes\":{\"zone\":\"zone-a\"}}", - dataCopy.get().serializeToJson()); + "\"values\":[\"host1\"]}],\"value\":13}],\"attributes\":{\"zone\":\"zone-a\"}}", + dataCopy.get().serializeToJson()); FlagId flagId2 = new FlagId("id2"); FlagData data2 = new FlagData(flagId2, new FetchVector().with(FetchVector.Dimension.ZONE_ID, "zone-a"), rule1); @@ -53,4 +53,4 @@ public class FlagsDbTest { db.removeValue(flagId2); assertFalse(db.getValue(flagId2).isPresent()); } -} +}
\ No newline at end of file diff --git a/flags/src/main/java/com/yahoo/vespa/flags/http/DefinedFlag.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/DefinedFlag.java index 8234e9df725..92397fc84a7 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/http/DefinedFlag.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/DefinedFlag.java @@ -1,11 +1,12 @@ // Copyright 2019 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.flags.http; +package com.yahoo.vespa.config.server.http.flags; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.jdisc.Response; +import com.yahoo.vespa.config.server.http.HttpConfigResponse; import com.yahoo.vespa.flags.FlagDefinition; import com.yahoo.vespa.flags.json.DimensionHelper; @@ -41,7 +42,6 @@ public class DefinedFlag extends HttpResponse { @Override public String getContentType() { - return "application/json"; + return HttpConfigResponse.JSON_CONTENT_TYPE; } - } diff --git a/flags/src/main/java/com/yahoo/vespa/flags/http/DefinedFlags.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/DefinedFlags.java index e1db7dda6e0..9604c51ee4b 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/http/DefinedFlags.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/DefinedFlags.java @@ -1,10 +1,11 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.flags.http; +package com.yahoo.vespa.config.server.http.flags; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.jdisc.Response; +import com.yahoo.vespa.config.server.http.HttpConfigResponse; import com.yahoo.vespa.flags.FlagDefinition; import java.io.IOException; @@ -17,7 +18,8 @@ import java.util.List; */ public class DefinedFlags extends HttpResponse { private static ObjectMapper mapper = new ObjectMapper(); - private static final Comparator<FlagDefinition> sortByFlagId = Comparator.comparing(flagDefinition -> flagDefinition.getUnboundFlag().id()); + private static final Comparator<FlagDefinition> sortByFlagId = + (left, right) -> left.getUnboundFlag().id().compareTo(right.getUnboundFlag().id()); private final List<FlagDefinition> flags; @@ -38,6 +40,6 @@ public class DefinedFlags extends HttpResponse { @Override public String getContentType() { - return "application/json"; + return HttpConfigResponse.JSON_CONTENT_TYPE; } } diff --git a/flags/src/main/java/com/yahoo/vespa/flags/http/FlagDataListResponse.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/FlagDataListResponse.java index 5af97007997..b33fc7c2b04 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/http/FlagDataListResponse.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/FlagDataListResponse.java @@ -1,11 +1,12 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.flags.http; +package com.yahoo.vespa.config.server.http.flags; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.jdisc.Response; +import com.yahoo.vespa.config.server.http.HttpConfigResponse; import com.yahoo.vespa.flags.FlagId; import com.yahoo.vespa.flags.json.FlagData; import com.yahoo.vespa.flags.json.wire.WireFlagDataList; @@ -53,6 +54,6 @@ public class FlagDataListResponse extends HttpResponse { @Override public String getContentType() { - return "application/json"; + return HttpConfigResponse.JSON_CONTENT_TYPE; } } diff --git a/flags/src/main/java/com/yahoo/vespa/flags/http/FlagDataResponse.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/FlagDataResponse.java index f6e81e030c7..054b218ff2d 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/http/FlagDataResponse.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/FlagDataResponse.java @@ -1,8 +1,9 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.flags.http; +package com.yahoo.vespa.config.server.http.flags; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.jdisc.Response; +import com.yahoo.vespa.config.server.http.HttpConfigResponse; import com.yahoo.vespa.flags.json.FlagData; import java.io.OutputStream; @@ -25,6 +26,6 @@ public class FlagDataResponse extends HttpResponse { @Override public String getContentType() { - return "application/json"; + return HttpConfigResponse.JSON_CONTENT_TYPE; } } diff --git a/flags/src/main/java/com/yahoo/vespa/flags/http/FlagsHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/FlagsHandler.java index 76f74cbe931..00f3d457d3d 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/http/FlagsHandler.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/FlagsHandler.java @@ -1,17 +1,19 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.flags.http; +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.log.LogLevel; import com.yahoo.restapi.Path; +import com.yahoo.vespa.config.server.http.HttpErrorResponse; +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.FlagDefinition; import com.yahoo.vespa.flags.FlagId; import com.yahoo.vespa.flags.Flags; import com.yahoo.vespa.flags.json.FlagData; -import com.yahoo.vespa.flags.persistence.FlagsDb; import com.yahoo.yolean.Exceptions; import java.io.UncheckedIOException; @@ -23,8 +25,7 @@ import java.util.Objects; * * @author hakonhall */ -public class FlagsHandler extends LoggingRequestHandler { - +public class FlagsHandler extends HttpHandler { private final FlagsDb flagsDb; @Inject @@ -34,44 +35,28 @@ public class FlagsHandler extends LoggingRequestHandler { } @Override - public HttpResponse handle(HttpRequest request) { - try { - switch (request.getMethod()) { - case GET: return handleGET(request); - case DELETE: return handleDELETE(request); - case PUT: return handlePUT(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(LogLevel.WARNING, "Unexpected error handling '" + request.getUri() + "'", e); - return ErrorResponse.internalServerError(Exceptions.toMessageString(e)); - } - } - - private HttpResponse handleGET(HttpRequest request) { + protected HttpResponse handleGET(HttpRequest request) { Path path = new Path(request.getUri()); if (path.matches("/flags/v1")) return new V1Response(flagsV1Uri(request), "data", "defined"); if (path.matches("/flags/v1/data")) return getFlagDataList(request); if (path.matches("/flags/v1/data/{flagId}")) return getFlagData(findFlagId(request, path)); if (path.matches("/flags/v1/defined")) return new DefinedFlags(Flags.getAllFlags()); if (path.matches("/flags/v1/defined/{flagId}")) return getDefinedFlag(findFlagId(request, path)); - return ErrorResponse.notFoundError("Nothing at path '" + path + "'"); + throw new NotFoundException("Nothing at path '" + path + "'"); } - private HttpResponse handlePUT(HttpRequest request) { + @Override + protected HttpResponse handlePUT(HttpRequest request) { Path path = new Path(request.getUri()); if (path.matches("/flags/v1/data/{flagId}")) return putFlagData(request, findFlagId(request, path)); - return ErrorResponse.notFoundError("Nothing at path '" + path + "'"); + throw new NotFoundException("Nothing at path '" + path + "'"); } - private HttpResponse handleDELETE(HttpRequest request) { + @Override + protected HttpResponse handleDELETE(HttpRequest request) { Path path = new Path(request.getUri()); if (path.matches("/flags/v1/data/{flagId}")) return deleteFlagData(findFlagId(request, path)); - return ErrorResponse.notFoundError("Nothing at path '" + path + "'"); + throw new NotFoundException("Nothing at path '" + path + "'"); } private String flagsV1Uri(HttpRequest request) { @@ -81,11 +66,9 @@ public class FlagsHandler extends LoggingRequestHandler { } private HttpResponse getDefinedFlag(FlagId flagId) { - var definedFlag = Flags.getFlag(flagId).map(DefinedFlag::new); - if (definedFlag.isPresent()) { - return definedFlag.get(); - } - return ErrorResponse.notFoundError("Flag " + flagId + " not defined"); + FlagDefinition definition = Flags.getFlag(flagId) + .orElseThrow(() -> new NotFoundException("Flag " + flagId + " not defined")); + return new DefinedFlag(definition); } private HttpResponse getFlagDataList(HttpRequest request) { @@ -94,11 +77,8 @@ public class FlagsHandler extends LoggingRequestHandler { } private HttpResponse getFlagData(FlagId flagId) { - var data = flagsDb.getValue(flagId).map(FlagDataResponse::new); - if (data.isPresent()) { - return data.get(); - } - return ErrorResponse.notFoundError("Flag " + flagId + " not set"); + FlagData data = flagsDb.getValue(flagId).orElseThrow(() -> new NotFoundException("Flag " + flagId + " not set")); + return new FlagDataResponse(data); } private HttpResponse putFlagData(HttpRequest request, FlagId flagId) { @@ -106,7 +86,7 @@ public class FlagsHandler extends LoggingRequestHandler { try { data = FlagData.deserialize(request.getData()); } catch (UncheckedIOException e) { - return ErrorResponse.badRequest("Failed to deserialize request data: " + Exceptions.toMessageString(e)); + return HttpErrorResponse.badRequest("Failed to deserialize request data: " + Exceptions.toMessageString(e)); } if (!isForce(request)) { @@ -125,14 +105,16 @@ public class FlagsHandler extends LoggingRequestHandler { private FlagId findFlagId(HttpRequest request, Path path) { FlagId flagId = new FlagId(path.get("flagId")); - if (!isForce(request) && Flags.getFlag(flagId).isEmpty()) { - throw new IllegalArgumentException("There is no flag '" + flagId + "' (use ?force=true to override)"); + + if (!isForce(request)) { + Flags.getFlag(flagId).orElseThrow(() -> + new NotFoundException("There is no flag '" + flagId + "' (use ?force=true to override)")); } + return flagId; } private boolean isForce(HttpRequest request) { return Objects.equals(request.getProperty("force"), "true"); } - } diff --git a/flags/src/main/java/com/yahoo/vespa/flags/http/OKResponse.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/OKResponse.java index d094e2d5734..87c02ae56f1 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/http/OKResponse.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/OKResponse.java @@ -1,8 +1,9 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.flags.http; +package com.yahoo.vespa.config.server.http.flags; import com.yahoo.container.jdisc.EmptyResponse; import com.yahoo.jdisc.Response; +import com.yahoo.vespa.config.server.http.HttpConfigResponse; /** * @author hakonhall @@ -14,6 +15,6 @@ public class OKResponse extends EmptyResponse { @Override public String getContentType() { - return "application/json"; + return HttpConfigResponse.JSON_CONTENT_TYPE; } } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/V1Response.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/V1Response.java new file mode 100644 index 00000000000..3594c801ca8 --- /dev/null +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/flags/V1Response.java @@ -0,0 +1,34 @@ +// 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.yahoo.jdisc.Response; +import com.yahoo.slime.Cursor; +import com.yahoo.slime.Slime; +import com.yahoo.text.Utf8; +import com.yahoo.vespa.config.SlimeUtils; +import com.yahoo.vespa.config.server.http.HttpConfigResponse; +import com.yahoo.vespa.config.server.http.StaticResponse; + +import java.util.Arrays; +import java.util.List; + +import static com.yahoo.yolean.Exceptions.uncheck; + +/** + * @author hakonhall + */ +public class V1Response extends StaticResponse { + public V1Response(String flagsV1Uri, String... names) { + super(Response.Status.OK, HttpConfigResponse.JSON_CONTENT_TYPE, generateBody(flagsV1Uri, Arrays.asList(names))); + } + + private static String generateBody(String flagsV1Uri, List<String> names) { + Slime slime = new Slime(); + Cursor root = slime.setObject(); + names.forEach(name -> { + Cursor data = root.setObject(name); + data.setString("url", flagsV1Uri + "/" + name); + }); + return Utf8.toString(uncheck(() -> SlimeUtils.toJsonBytes(slime))); + } +} diff --git a/configserver/src/main/resources/configserver-app/services.xml b/configserver/src/main/resources/configserver-app/services.xml index b429e220c33..cfacd6ff8c9 100644 --- a/configserver/src/main/resources/configserver-app/services.xml +++ b/configserver/src/main/resources/configserver-app/services.xml @@ -54,7 +54,7 @@ <preprocess:include file='model-integration.xml' required='true' /> <component id="com.yahoo.vespa.configserver.flags.ConfigServerFlagSource" bundle="configserver-flags"/> - <component id="com.yahoo.vespa.flags.persistence.FlagsDb" bundle="flags"/> + <component id="com.yahoo.vespa.configserver.flags.db.FlagsDbImpl" bundle="configserver-flags"/> <preprocess:include file='metrics-packets.xml' required='false' /> <preprocess:include file='container.xml' required='false' /> @@ -92,6 +92,10 @@ <handler id='com.yahoo.vespa.config.server.http.status.StatusHandler' bundle='configserver'> <binding>http://*/status</binding> </handler> + <handler id='com.yahoo.vespa.config.server.http.flags.FlagsHandler' bundle='configserver'> + <binding>http://*/flags/v1</binding> + <binding>http://*/flags/v1/*</binding> + </handler> <handler id='com.yahoo.vespa.config.server.http.v2.TenantHandler' bundle='configserver'> <binding>http://*/application/v2/tenant/</binding> <binding>http://*/application/v2/tenant/*</binding> diff --git a/flags/src/test/java/com/yahoo/vespa/flags/http/FlagsHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/flags/FlagsHandlerTest.java index 8ae1008ba22..5ae6ce9820b 100644 --- a/flags/src/test/java/com/yahoo/vespa/flags/http/FlagsHandlerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/flags/FlagsHandlerTest.java @@ -1,26 +1,25 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.flags.http; +package com.yahoo.vespa.config.server.http.flags; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.jdisc.http.HttpRequest.Method; import com.yahoo.text.Utf8; +import com.yahoo.vespa.config.server.http.SessionHandlerTest; +import com.yahoo.vespa.configserver.flags.db.FlagsDbImpl; import com.yahoo.vespa.curator.mock.MockCurator; import com.yahoo.vespa.flags.FetchVector; import com.yahoo.vespa.flags.FlagId; import com.yahoo.vespa.flags.Flags; import com.yahoo.vespa.flags.UnboundBooleanFlag; -import com.yahoo.vespa.flags.persistence.FlagsDb; -import com.yahoo.yolean.Exceptions; import org.junit.Test; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.InputStream; -import java.nio.charset.StandardCharsets; import java.util.stream.Collectors; import java.util.stream.Stream; +import static com.yahoo.yolean.Exceptions.uncheck; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; @@ -38,7 +37,7 @@ public class FlagsHandlerTest { private static final String FLAGS_V1_URL = "https://foo.com:4443/flags/v1"; - private final FlagsDb flagsDb = new FlagsDb(new MockCurator()); + private final FlagsDbImpl flagsDb = new FlagsDbImpl(new MockCurator()); private final FlagsHandler handler = new FlagsHandler(FlagsHandler.testOnlyContext(), flagsDb); @Test @@ -162,7 +161,7 @@ public class FlagsHandlerTest { @Test public void testForcing() { - assertThat(handle(Method.PUT, "/data/" + new FlagId("undef"), "", 400), + assertThat(handle(Method.PUT, "/data/" + new FlagId("undef"), "", 404), containsString("There is no flag 'undef'")); assertThat(handle(Method.PUT, "/data/" + new FlagId("undef") + "?force=true", "", 400), @@ -192,12 +191,10 @@ public class FlagsHandlerTest { HttpResponse response = handler.handle(request); assertEquals(expectedStatus, response.getStatus()); assertEquals("application/json", response.getContentType()); - var outputStream = new ByteArrayOutputStream(); - Exceptions.uncheck(() -> response.render(outputStream)); - return outputStream.toString(StandardCharsets.UTF_8); + return uncheck(() -> SessionHandlerTest.getRenderedString(response)); } private InputStream makeInputStream(String content) { return new ByteArrayInputStream(Utf8.toBytes(content)); } -} +}
\ No newline at end of file diff --git a/flags/pom.xml b/flags/pom.xml index 7ef082cc1bc..c1e9eca20ab 100644 --- a/flags/pom.xml +++ b/flags/pom.xml @@ -59,18 +59,7 @@ <classifier>no_aop</classifier> <scope>provided</scope> </dependency> - <dependency> - <groupId>com.yahoo.vespa</groupId> - <artifactId>container-dev</artifactId> - <version>${project.version}</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>com.yahoo.vespa</groupId> - <artifactId>zkfacade</artifactId> - <version>${project.version}</version> - <scope>provided</scope> - </dependency> + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> diff --git a/flags/src/main/java/com/yahoo/vespa/flags/http/ErrorResponse.java b/flags/src/main/java/com/yahoo/vespa/flags/http/ErrorResponse.java deleted file mode 100644 index 969903093a4..00000000000 --- a/flags/src/main/java/com/yahoo/vespa/flags/http/ErrorResponse.java +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.flags.http; - -import com.yahoo.slime.Cursor; -import com.yahoo.slime.Slime; - -import static com.yahoo.jdisc.Response.Status.BAD_REQUEST; -import static com.yahoo.jdisc.Response.Status.FORBIDDEN; -import static com.yahoo.jdisc.Response.Status.INTERNAL_SERVER_ERROR; -import static com.yahoo.jdisc.Response.Status.METHOD_NOT_ALLOWED; -import static com.yahoo.jdisc.Response.Status.NOT_FOUND; -import static com.yahoo.jdisc.Response.Status.UNAUTHORIZED; - -/** - * A HTTP JSON response containing an error code and a message - * - * @author bratseth - */ -public class ErrorResponse extends SlimeJsonResponse { - - public enum errorCodes { - NOT_FOUND, - BAD_REQUEST, - FORBIDDEN, - METHOD_NOT_ALLOWED, - INTERNAL_SERVER_ERROR, - UNAUTHORIZED - } - - public ErrorResponse(int statusCode, String errorType, String message) { - super(statusCode, asSlimeMessage(errorType, message)); - } - - private static Slime asSlimeMessage(String errorType, String message) { - Slime slime = new Slime(); - Cursor root = slime.setObject(); - root.setString("error-code", errorType); - root.setString("message", message); - return slime; - } - - public static ErrorResponse notFoundError(String message) { - return new ErrorResponse(NOT_FOUND, errorCodes.NOT_FOUND.name(), message); - } - - public static ErrorResponse internalServerError(String message) { - return new ErrorResponse(INTERNAL_SERVER_ERROR, errorCodes.INTERNAL_SERVER_ERROR.name(), message); - } - - public static ErrorResponse badRequest(String message) { - return new ErrorResponse(BAD_REQUEST, errorCodes.BAD_REQUEST.name(), message); - } - - public static ErrorResponse forbidden(String message) { - return new ErrorResponse(FORBIDDEN, errorCodes.FORBIDDEN.name(), message); - } - - public static ErrorResponse unauthorized(String message) { - return new ErrorResponse(UNAUTHORIZED, errorCodes.UNAUTHORIZED.name(), message); - } - - public static ErrorResponse methodNotAllowed(String message) { - return new ErrorResponse(METHOD_NOT_ALLOWED, errorCodes.METHOD_NOT_ALLOWED.name(), message); - } - -} diff --git a/flags/src/main/java/com/yahoo/vespa/flags/http/SlimeJsonResponse.java b/flags/src/main/java/com/yahoo/vespa/flags/http/SlimeJsonResponse.java deleted file mode 100644 index dd71795ae43..00000000000 --- a/flags/src/main/java/com/yahoo/vespa/flags/http/SlimeJsonResponse.java +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.flags.http; - -import com.yahoo.container.jdisc.HttpResponse; -import com.yahoo.slime.JsonFormat; -import com.yahoo.slime.Slime; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * A generic Json response using Slime for JSON encoding - * - * @author bratseth - */ -public class SlimeJsonResponse extends HttpResponse { - - private final Slime slime; - - public SlimeJsonResponse(Slime slime) { - super(200); - this.slime = slime; - } - - public SlimeJsonResponse(int statusCode, Slime slime) { - super(statusCode); - this.slime = slime; - } - - @Override - public void render(OutputStream stream) throws IOException { - new JsonFormat(true).encode(stream, slime); - } - - @Override - public String getContentType() { return "application/json"; } - -} diff --git a/flags/src/main/java/com/yahoo/vespa/flags/http/V1Response.java b/flags/src/main/java/com/yahoo/vespa/flags/http/V1Response.java deleted file mode 100644 index e8ff0bd99a4..00000000000 --- a/flags/src/main/java/com/yahoo/vespa/flags/http/V1Response.java +++ /dev/null @@ -1,46 +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.flags.http; - -import com.yahoo.container.jdisc.HttpResponse; -import com.yahoo.jdisc.Response; -import com.yahoo.slime.Cursor; -import com.yahoo.slime.JsonFormat; -import com.yahoo.slime.Slime; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.List; - -/** - * @author hakonhall - */ -public class V1Response extends HttpResponse { - - private final Slime slime; - - public V1Response(String flagsV1Uri, String... names) { - super(Response.Status.OK); - this.slime = generateBody(flagsV1Uri, List.of(names)); - } - - @Override - public void render(OutputStream stream) throws IOException { - new JsonFormat(true).encode(stream, slime); - } - - @Override - public String getContentType() { - return "application/json"; - } - - private static Slime generateBody(String flagsV1Uri, List<String> names) { - Slime slime = new Slime(); - Cursor root = slime.setObject(); - names.forEach(name -> { - Cursor data = root.setObject(name); - data.setString("url", flagsV1Uri + "/" + name); - }); - return slime; - } - -} diff --git a/flags/src/main/java/com/yahoo/vespa/flags/persistence/package-info.java b/flags/src/main/java/com/yahoo/vespa/flags/persistence/package-info.java deleted file mode 100644 index d4753ed1756..00000000000 --- a/flags/src/main/java/com/yahoo/vespa/flags/persistence/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -/** - * @author mpolden - */ -@ExportPackage -package com.yahoo.vespa.flags.persistence; - -import com.yahoo.osgi.annotation.ExportPackage; |