diff options
Diffstat (limited to 'configserver-flags/src')
6 files changed, 187 insertions, 0 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 new file mode 100644 index 00000000000..9768c42b477 --- /dev/null +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/ConfigServerFlagSource.java @@ -0,0 +1,18 @@ +// 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.google.inject.Inject; +import com.yahoo.vespa.configserver.flags.db.FlagsDbImpl; +import com.yahoo.vespa.configserver.flags.db.ZooKeeperFlagSource; +import com.yahoo.vespa.flags.FileFlagSource; +import com.yahoo.vespa.flags.OrderedFlagSource; + +/** + * @author hakonhall + */ +public class ConfigServerFlagSource extends OrderedFlagSource { + @Inject + public ConfigServerFlagSource(FlagsDbImpl flagsDb) { + super(new FileFlagSource(), new ZooKeeperFlagSource(flagsDb)); + } +} 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/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 new file mode 100644 index 00000000000..7b0a2f632cc --- /dev/null +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImpl.java @@ -0,0 +1,56 @@ +// 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.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; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +/** + * @author hakonhall + */ +public class FlagsDbImpl implements FlagsDb { + private static final Path ROOT_PATH = Path.fromString("/flags/v1"); + + private final Curator curator; + + @Inject + public FlagsDbImpl(Curator curator) { + this.curator = curator; + } + + @Override + public Optional<FlagData> getValue(FlagId flagId) { + return curator.getData(getZkPathFor(flagId)).map(FlagData::deserializeUtf8Json); + } + + @Override + public void setValue(FlagId flagId, FlagData data) { + curator.set(getZkPathFor(flagId), data.serializeToUtf8Json()); + } + + @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; + } + + @Override + public void removeValue(FlagId flagId) { + curator.delete(getZkPathFor(flagId)); + } + + 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 new file mode 100644 index 00000000000..bd99ac6eca9 --- /dev/null +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/db/ZooKeeperFlagSource.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.db; + +import com.yahoo.vespa.flags.FetchVector; +import com.yahoo.vespa.flags.FlagId; +import com.yahoo.vespa.flags.FlagSource; +import com.yahoo.vespa.flags.RawFlag; + +import java.util.Optional; + +/** + * @author hakonhall + */ +public class ZooKeeperFlagSource implements FlagSource { + private final FlagsDbImpl flagsDb; + + public ZooKeeperFlagSource(FlagsDbImpl flagsDb) { + this.flagsDb = flagsDb; + } + + @Override + public Optional<RawFlag> fetch(FlagId id, FetchVector vector) { + return flagsDb.getValue(id).flatMap(data -> data.resolve(vector)); + } +} diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/package-info.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/package-info.java new file mode 100644 index 00000000000..97e66d95715 --- /dev/null +++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/package-info.java @@ -0,0 +1,7 @@ +// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +@ExportPackage +package com.yahoo.vespa.configserver.flags; + +import com.yahoo.osgi.annotation.ExportPackage; + +/** The node repository controls and allocates the nodes available in a hosted Vespa zone */ 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 new file mode 100644 index 00000000000..1fe61130348 --- /dev/null +++ b/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImplTest.java @@ -0,0 +1,56 @@ +// 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.curator.mock.MockCurator; +import com.yahoo.vespa.flags.FetchVector; +import com.yahoo.vespa.flags.FlagId; +import com.yahoo.vespa.flags.JsonNodeRawFlag; +import com.yahoo.vespa.flags.json.Condition; +import com.yahoo.vespa.flags.json.FlagData; +import com.yahoo.vespa.flags.json.Rule; +import org.junit.Test; + +import java.util.Map; +import java.util.Optional; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author hakonhall + */ +public class FlagsDbImplTest { + @Test + public void test() { + MockCurator curator = new MockCurator(); + 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); + FlagData data = new FlagData(new FetchVector().with(FetchVector.Dimension.ZONE_ID, "zone-a"), rule1); + FlagId flagId = new FlagId("id"); + db.setValue(flagId, data); + + assertTrue(db.getValue(flagId).isPresent()); + Optional<FlagData> dataCopy = db.getValue(flagId); + assertTrue(dataCopy.isPresent()); + + assertEquals("{\"rules\":[{\"conditions\":[{\"type\":\"whitelist\",\"dimension\":\"hostname\"," + + "\"values\":[\"host1\"]}],\"value\":13}],\"attributes\":{\"zone\":\"zone-a\"}}", + dataCopy.get().serializeToJson()); + + FlagId flagId2 = new FlagId("id2"); + db.setValue(flagId2, data); + Map<FlagId, FlagData> flags = db.getAllFlags(); + assertThat(flags.size(), equalTo(2)); + assertThat(flags.get(flagId), notNullValue()); + assertThat(flags.get(flagId2), notNullValue()); + + db.removeValue(flagId2); + assertFalse(db.getValue(flagId2).isPresent()); + } +}
\ No newline at end of file |