diff options
6 files changed, 39 insertions, 9 deletions
diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImpl.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImpl.java index 7b0a2f632cc..c313a47ad13 100644 --- a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImpl.java +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImpl.java @@ -7,10 +7,15 @@ 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; +import org.apache.curator.framework.recipes.cache.ChildData; -import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.function.Function; +import java.util.stream.Collectors; /** * @author hakonhall @@ -19,15 +24,21 @@ 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 FlagsDbImpl(Curator curator) { this.curator = curator; + curator.create(ROOT_PATH); + ExecutorService executorService = Executors.newFixedThreadPool(1); + this.cache = curator.createDirectoryCache(ROOT_PATH.toString(), true, false, executorService); } @Override public Optional<FlagData> getValue(FlagId flagId) { - return curator.getData(getZkPathFor(flagId)).map(FlagData::deserializeUtf8Json); + return Optional.ofNullable(cache.getCurrentData(getZkPathFor(flagId))) + .map(ChildData::getData) + .map(FlagData::deserializeUtf8Json); } @Override @@ -37,12 +48,11 @@ public class FlagsDbImpl implements FlagsDb { @Override public Map<FlagId, FlagData> getAllFlags() { - Map<FlagId, FlagData> flags = new HashMap<>(); - for (String flagId : curator.getChildren(ROOT_PATH)) { - FlagId id = new FlagId(flagId); - getValue(id).ifPresent(data -> flags.put(id, data)); - } - return flags; + List<ChildData> dataList = cache.getCurrentData(); + return dataList.stream() + .map(ChildData::getData) + .map(FlagData::deserializeUtf8Json) + .collect(Collectors.toMap(FlagData::id, Function.identity())); } @Override diff --git a/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImplTest.java b/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImplTest.java index 0523090c18b..ecc9bacb081 100644 --- a/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImplTest.java +++ b/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImplTest.java @@ -43,7 +43,8 @@ public class FlagsDbImplTest { dataCopy.get().serializeToJson()); FlagId flagId2 = new FlagId("id2"); - db.setValue(flagId2, data); + FlagData data2 = new FlagData(flagId2, new FetchVector().with(FetchVector.Dimension.ZONE_ID, "zone-a"), rule1); + db.setValue(flagId2, data2); Map<FlagId, FlagData> flags = db.getAllFlags(); assertThat(flags.size(), equalTo(2)); assertThat(flags.get(flagId), notNullValue()); diff --git a/zkfacade/abi-spec.json b/zkfacade/abi-spec.json index 5610fb2e9cf..eb8edaa5b97 100644 --- a/zkfacade/abi-spec.json +++ b/zkfacade/abi-spec.json @@ -36,6 +36,7 @@ "public abstract void start()", "public abstract void addListener(org.apache.curator.framework.recipes.cache.PathChildrenCacheListener)", "public abstract java.util.List getCurrentData()", + "public abstract org.apache.curator.framework.recipes.cache.ChildData getCurrentData(com.yahoo.path.Path)", "public abstract void close()" ], "fields": [] diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java index 6ba394c340d..91140fcf713 100644 --- a/zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java +++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/Curator.java @@ -358,6 +358,9 @@ public class Curator implements AutoCloseable { List<ChildData> getCurrentData(); + /** Returns the ChildData, or null if it does not exist. */ + ChildData getCurrentData(Path absolutePath); + void close(); } diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/PathChildrenCacheWrapper.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/PathChildrenCacheWrapper.java index 2340fb1b5a8..e069034e1d8 100644 --- a/zkfacade/src/main/java/com/yahoo/vespa/curator/PathChildrenCacheWrapper.java +++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/PathChildrenCacheWrapper.java @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.curator; +import com.yahoo.path.Path; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.recipes.cache.ChildData; import org.apache.curator.framework.recipes.cache.PathChildrenCache; @@ -44,6 +45,11 @@ class PathChildrenCacheWrapper implements Curator.DirectoryCache { } @Override + public ChildData getCurrentData(Path absolutePath) { + return wrapped.getCurrentData(absolutePath.getAbsolute()); + } + + @Override public void close() { try { wrapped.close(); diff --git a/zkfacade/src/main/java/com/yahoo/vespa/curator/mock/MockCurator.java b/zkfacade/src/main/java/com/yahoo/vespa/curator/mock/MockCurator.java index 4013cf1d649..85fa0ded838 100644 --- a/zkfacade/src/main/java/com/yahoo/vespa/curator/mock/MockCurator.java +++ b/zkfacade/src/main/java/com/yahoo/vespa/curator/mock/MockCurator.java @@ -572,6 +572,15 @@ public class MockCurator extends Curator { return childData; } + @Override + public ChildData getCurrentData(Path fullPath) { + if (!fullPath.getParentPath().equals(path)) { + throw new IllegalArgumentException("Path '" + fullPath + "' is not a child path of '" + path + "'"); + } + + return getData(fullPath).map(bytes -> new ChildData(fullPath.getAbsolute(), null, bytes)).orElse(null); + } + private void collectData(Node parent, Path parentPath, List<ChildData> data) { for (Node child : parent.children().values()) { Path childPath = parentPath.append(child.name()); |