aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2022-11-02 06:04:19 +0100
committerGitHub <noreply@github.com>2022-11-02 06:04:19 +0100
commit82a57bbed60b624999da93f18eb05746d0ede3f7 (patch)
treeabbc93e5b0e09bb313e1c90b339716abba1ddcb4
parentfe4ec91963557a8c02de81b0acf3cf55282d00ac (diff)
parentacd1c014cf612b5a370e78c9c7ab6e6cae3a8737 (diff)
Merge pull request #24702 from vespa-engine/jonmv/config-lib-more-sync-2
Jonmv/config lib more sync 2
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/ConfigSet.java2
-rwxr-xr-xconfig/src/main/java/com/yahoo/config/subscription/ConfigSourceSet.java2
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java11
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/ConfigURI.java4
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/DirSource.java6
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/FileSource.java18
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/ConfigSetSubscription.java9
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java41
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java21
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/package-info.java5
-rw-r--r--config/src/test/java/com/yahoo/config/subscription/impl/FileConfigSubscriptionTest.java8
-rw-r--r--container-core/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java12
-rw-r--r--container-core/src/test/java/com/yahoo/container/di/ContainerTest.java48
-rw-r--r--container-core/src/test/java/com/yahoo/container/di/ContainerTestBase.java11
-rw-r--r--container-core/src/test/java/com/yahoo/container/di/DirConfigSource.java70
-rw-r--r--container-disc/src/main/java/com/yahoo/container/jdisc/ContainerThreadFactory.java10
-rw-r--r--container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricProvider.java9
-rw-r--r--jdisc_core/src/main/java/com/yahoo/jdisc/application/MetricImpl.java6
-rwxr-xr-xmessagebus/src/test/java/com/yahoo/messagebus/ConfigAgentTestCase.java9
19 files changed, 145 insertions, 157 deletions
diff --git a/config/src/main/java/com/yahoo/config/subscription/ConfigSet.java b/config/src/main/java/com/yahoo/config/subscription/ConfigSet.java
index 1b86db6b299..0fb0462e84e 100644
--- a/config/src/main/java/com/yahoo/config/subscription/ConfigSet.java
+++ b/config/src/main/java/com/yahoo/config/subscription/ConfigSet.java
@@ -23,7 +23,6 @@ public class ConfigSet implements ConfigSource {
@SuppressWarnings({"unchecked", "rawtypes"})
public void addBuilder(String configId, ConfigInstance.Builder builder) {
Class<?> configClass = builder.getClass().getDeclaringClass();
- //System.out.println("Declaring class for builder " + builder + " is " + configClass);
ConfigKey<?> key = new ConfigKey(configClass, configId);
configs.put(key, builder);
}
@@ -56,4 +55,5 @@ public class ConfigSet implements ConfigSource {
}
return sb.toString();
}
+
}
diff --git a/config/src/main/java/com/yahoo/config/subscription/ConfigSourceSet.java b/config/src/main/java/com/yahoo/config/subscription/ConfigSourceSet.java
index 81aeda52b54..597f83a605c 100755
--- a/config/src/main/java/com/yahoo/config/subscription/ConfigSourceSet.java
+++ b/config/src/main/java/com/yahoo/config/subscription/ConfigSourceSet.java
@@ -58,7 +58,7 @@ public class ConfigSourceSet implements ConfigSource {
* @param address Connection endpoint on the format "tcp/host:port".
*/
public ConfigSourceSet(String address) {
- this(new String[] {address});
+ this(new String[] { address });
}
/**
diff --git a/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java b/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java
index 5d5ad1f1edc..e2b53879d92 100644
--- a/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java
+++ b/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java
@@ -275,7 +275,7 @@ public class ConfigSubscriber implements AutoCloseable {
ConfigSubscription<? extends ConfigInstance> subscription = h.subscription();
log.log(Level.FINEST, () -> "Calling nextConfig for " + subscription.getKey());
if ( ! subscription.nextConfig(timeLeftMillis)) {
- // This subscriber has no new state and we know it has exhausted all time
+ // This subscriber has no new state, and we know it has exhausted the timeout
log.log(Level.FINEST, () -> "No new config for " + subscription.getKey());
return false;
}
@@ -407,15 +407,6 @@ public class ConfigSubscriber implements AutoCloseable {
}
}
- /**
- * The source used by this subscriber.
- *
- * @return the {@link ConfigSource} used by this subscriber
- */
- public ConfigSource getSource() {
- return source;
- }
-
public boolean isClosed() {
synchronized (monitor) {
return state == State.CLOSED;
diff --git a/config/src/main/java/com/yahoo/config/subscription/ConfigURI.java b/config/src/main/java/com/yahoo/config/subscription/ConfigURI.java
index f0257457902..aa8a8c4a4c2 100644
--- a/config/src/main/java/com/yahoo/config/subscription/ConfigURI.java
+++ b/config/src/main/java/com/yahoo/config/subscription/ConfigURI.java
@@ -12,8 +12,8 @@ import java.io.File;
*/
public class ConfigURI {
- private String configId;
- private ConfigSource source;
+ private final String configId;
+ private final ConfigSource source;
private ConfigURI(String configId, ConfigSource source) {
this.configId = configId;
diff --git a/config/src/main/java/com/yahoo/config/subscription/DirSource.java b/config/src/main/java/com/yahoo/config/subscription/DirSource.java
index fbd65ccf597..87bf51af26f 100644
--- a/config/src/main/java/com/yahoo/config/subscription/DirSource.java
+++ b/config/src/main/java/com/yahoo/config/subscription/DirSource.java
@@ -11,12 +11,12 @@ public class DirSource implements ConfigSource {
private final File dir;
public DirSource(File dir) {
- if (!dir.isDirectory()) throw new IllegalArgumentException("Not a directory: "+dir);
+ if ( ! dir.isDirectory()) throw new IllegalArgumentException("Not a directory: " + dir);
this.dir = dir;
}
- public File getDir() {
- return dir;
+ public FileSource getFile(String name) {
+ return new FileSource(new File(dir, name));
}
}
diff --git a/config/src/main/java/com/yahoo/config/subscription/FileSource.java b/config/src/main/java/com/yahoo/config/subscription/FileSource.java
index 2178c64cca3..9d3c6041f4b 100644
--- a/config/src/main/java/com/yahoo/config/subscription/FileSource.java
+++ b/config/src/main/java/com/yahoo/config/subscription/FileSource.java
@@ -2,23 +2,35 @@
package com.yahoo.config.subscription;
import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.List;
/**
* Source specifying config from one local file
*
* @author Vegard Havdal
+ * @author jonmv
*/
public class FileSource implements ConfigSource {
private final File file;
public FileSource(File file) {
- if ( ! file.isFile()) throw new IllegalArgumentException("Not an ordinary file: "+file);
this.file = file;
+ validateFile();
}
- public File getFile() {
- return file;
+ public long getLastModified() {
+ return file.lastModified();
+ }
+
+ public List<String> getContent() throws IOException {
+ return Files.readAllLines(file.toPath());
+ }
+
+ public void validateFile() {
+ if ( ! file.isFile()) throw new IllegalArgumentException("Not a file: " + file);
}
}
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSetSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSetSubscription.java
index 68f1dc2df17..41bab257248 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSetSubscription.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSetSubscription.java
@@ -18,12 +18,11 @@ public class ConfigSetSubscription<T extends ConfigInstance> extends ConfigSubsc
private final ConfigSet set;
private final ConfigKey<T> subKey;
- ConfigSetSubscription(ConfigKey<T> key, ConfigSource cset) {
+ ConfigSetSubscription(ConfigKey<T> key, ConfigSet cset) {
super(key);
- if (!(cset instanceof ConfigSet)) throw new IllegalArgumentException("Source is not a ConfigSet: " + cset);
- this.set = (ConfigSet) cset;
- subKey = new ConfigKey<>(configClass, key.getConfigId());
- if (!set.contains(subKey)) {
+ this.set = cset;
+ this.subKey = new ConfigKey<>(configClass, key.getConfigId());
+ if ( ! set.contains(subKey)) {
throw new IllegalArgumentException("The given ConfigSet " + set + " does not contain a config for " + subKey);
}
setGeneration(0L);
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java
index 5d720a74b15..2c4e3d40250 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java
@@ -121,10 +121,9 @@ public abstract class ConfigSubscription<T extends ConfigInstance> {
if (source instanceof FileSource || configId.startsWith("file:")) return getFileSub(key, source);
if (source instanceof DirSource || configId.startsWith("dir:")) return getDirFileSub(key, source);
if (source instanceof JarSource || configId.startsWith("jar:")) return getJarSub(key, source);
- if (source instanceof ConfigSet) return new ConfigSetSubscription<>(key, source);
- if (source instanceof ConfigSourceSet) {
- JRTConfigRequester requester = requesters.getRequester((ConfigSourceSet) source, timingValues);
- return new JRTConfigSubscription<>(key, requester, timingValues);
+ if (source instanceof ConfigSet cset) return new ConfigSetSubscription<>(key, cset);
+ if (source instanceof ConfigSourceSet csset) {
+ return new JRTConfigSubscription<>(key, requesters.getRequester(csset, timingValues), timingValues);
}
throw new IllegalArgumentException("Unknown source type: " + source);
}
@@ -132,21 +131,19 @@ public abstract class ConfigSubscription<T extends ConfigInstance> {
private static <T extends ConfigInstance> JarConfigSubscription<T> getJarSub(ConfigKey<T> key, ConfigSource source) {
String jarName;
String path = "config/";
- if (source instanceof JarSource) {
- JarSource js = (JarSource) source;
+ if (source instanceof JarSource js) {
jarName = js.getJarFile().getName();
if (js.getPath() != null) path = js.getPath();
} else {
- jarName = key.getConfigId().replace("jar:", "").replaceFirst("\\!/.*", "");
- if (key.getConfigId().contains("!/")) path = key.getConfigId().replaceFirst(".*\\!/", "");
+ jarName = key.getConfigId().replace("jar:", "").replaceFirst("!/.*", "");
+ if (key.getConfigId().contains("!/")) path = key.getConfigId().replaceFirst(".*!/", "");
}
return new JarConfigSubscription<>(key, jarName, path);
}
private static <T extends ConfigInstance> ConfigSubscription<T> getFileSub(ConfigKey<T> key, ConfigSource source) {
- File file = ((source instanceof FileSource))
- ? ((FileSource) source).getFile()
- : new File(key.getConfigId().replace("file:", ""));
+ FileSource file = source instanceof FileSource fileSource ? fileSource
+ : new FileSource(new File(key.getConfigId().replace("file:", "")));
return new FileConfigSubscription<>(key, file);
}
@@ -158,30 +155,16 @@ public abstract class ConfigSubscription<T extends ConfigInstance> {
}
private static <T extends ConfigInstance> ConfigSubscription<T> getDirFileSub(ConfigKey<T> key, ConfigSource source) {
- String dir = key.getConfigId().replace("dir:", "");
- if (source instanceof DirSource) {
- dir = ((DirSource) source).getDir().toString();
- }
- if (!dir.endsWith(File.separator)) dir = dir + File.separator;
- String name = getConfigFilename(key);
- File file = new File(dir + name);
- if (!file.exists()) {
- throw new IllegalArgumentException("Could not find a config file for '" + key.getName() + "' in '" + dir + "'");
- }
- return new FileConfigSubscription<>(key, file);
+ DirSource dir = source instanceof DirSource dirSource ? dirSource
+ : new DirSource(new File(key.getConfigId().replace("dir:", "")));
+ return new FileConfigSubscription<>(key, dir.getFile(getConfigFilename(key)));
}
- @SuppressWarnings("unchecked")
@Override
public boolean equals(Object o) {
- if (o instanceof ConfigSubscription) {
- ConfigSubscription<T> other = (ConfigSubscription<T>) o;
- return key.equals(other.key);
- }
- return false;
+ return o instanceof ConfigSubscription<?> cs && key.equals(cs.key);
}
-
/**
* Called from {@link ConfigSubscriber} when the changed status of this config is propagated to the clients
*/
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java
index 5311b91c31f..216657a6db3 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java
@@ -5,13 +5,11 @@ import com.yahoo.config.ConfigInstance;
import com.yahoo.config.ConfigurationRuntimeException;
import com.yahoo.config.subscription.CfgConfigPayloadBuilder;
import com.yahoo.config.subscription.ConfigInterruptedException;
-import com.yahoo.io.IOUtils;
+import com.yahoo.config.subscription.FileSource;
import com.yahoo.vespa.config.ConfigKey;
import com.yahoo.vespa.config.ConfigPayload;
-import java.io.File;
import java.io.IOException;
-import java.util.Arrays;
import static java.util.logging.Level.FINE;
@@ -22,20 +20,19 @@ import static java.util.logging.Level.FINE;
*/
public class FileConfigSubscription<T extends ConfigInstance> extends ConfigSubscription<T> {
- final File file;
+ final FileSource file;
long ts;
- FileConfigSubscription(ConfigKey<T> key, File f) {
+ FileConfigSubscription(ConfigKey<T> key, FileSource file) {
super(key);
+ file.validateFile();
setGeneration(0L);
- file = f;
- if (!file.exists() && !file.isFile())
- throw new IllegalArgumentException("Not a file: " + file);
+ this.file = file;
}
@Override
public boolean nextConfig(long timeout) {
- if (!file.exists() && !file.isFile()) throw new IllegalArgumentException("Not a file: " + file);
+ file.validateFile();
if (checkReloaded()) {
log.log(FINE, () -> "User forced config reload at " + System.currentTimeMillis());
// User forced reload
@@ -45,7 +42,7 @@ public class FileConfigSubscription<T extends ConfigInstance> extends ConfigSubs
log.log(FINE, () -> "Config: " + configState.getConfig().toString());
return true;
}
- if (file.lastModified() != ts) {
+ if (file.getLastModified() != ts) {
setConfigIncGen(updateConfig());
return true;
}
@@ -59,9 +56,9 @@ public class FileConfigSubscription<T extends ConfigInstance> extends ConfigSubs
}
private T updateConfig() {
- ts = file.lastModified();
+ ts = file.getLastModified();
try {
- ConfigPayload payload = new CfgConfigPayloadBuilder().deserialize(Arrays.asList(IOUtils.readFile(file).split("\n")));
+ ConfigPayload payload = new CfgConfigPayloadBuilder().deserialize(file.getContent());
return payload.toInstance(configClass, key.getConfigId());
} catch (IOException e) {
throw new ConfigurationRuntimeException(e);
diff --git a/config/src/main/java/com/yahoo/config/subscription/package-info.java b/config/src/main/java/com/yahoo/config/subscription/package-info.java
index bda7649d184..58a47fa4249 100644
--- a/config/src/main/java/com/yahoo/config/subscription/package-info.java
+++ b/config/src/main/java/com/yahoo/config/subscription/package-info.java
@@ -1,8 +1,7 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+/** Classes for subscribing to Vespa config. */
@ExportPackage
-/**
- * Classes for subscribing to Vespa config.
- */
package com.yahoo.config.subscription;
import com.yahoo.osgi.annotation.ExportPackage;
diff --git a/config/src/test/java/com/yahoo/config/subscription/impl/FileConfigSubscriptionTest.java b/config/src/test/java/com/yahoo/config/subscription/impl/FileConfigSubscriptionTest.java
index e37a5d7b36b..aa948f2f0ae 100644
--- a/config/src/test/java/com/yahoo/config/subscription/impl/FileConfigSubscriptionTest.java
+++ b/config/src/test/java/com/yahoo/config/subscription/impl/FileConfigSubscriptionTest.java
@@ -2,6 +2,7 @@
package com.yahoo.config.subscription.impl;
import com.yahoo.config.subscription.DirSource;
+import com.yahoo.config.subscription.FileSource;
import com.yahoo.foo.SimpletypesConfig;
import com.yahoo.foo.TestReferenceConfig;
import com.yahoo.vespa.config.ConfigKey;
@@ -42,7 +43,7 @@ public class FileConfigSubscriptionTest {
writeConfig("intval", "23");
ConfigSubscription<SimpletypesConfig> sub = new FileConfigSubscription<>(
new ConfigKey<>(SimpletypesConfig.class, ""),
- TEST_TYPES_FILE);
+ new FileSource(TEST_TYPES_FILE));
assertTrue(sub.nextConfig(1000));
assertEquals(23, sub.getConfigState().getConfig().intval());
Thread.sleep(1000);
@@ -56,7 +57,7 @@ public class FileConfigSubscriptionTest {
writeConfig("intval", "23");
ConfigSubscription<SimpletypesConfig> sub = new FileConfigSubscription<>(
new ConfigKey<>(SimpletypesConfig.class, ""),
- TEST_TYPES_FILE);
+ new FileSource(TEST_TYPES_FILE));
assertTrue(sub.nextConfig(1000));
assertEquals(23, sub.getConfigState().getConfig().intval());
writeConfig("intval", "33");
@@ -110,9 +111,10 @@ public class FileConfigSubscriptionTest {
writeConfig("intval", "23");
ConfigSubscription<SimpletypesConfig> sub = new FileConfigSubscription<>(
new ConfigKey<>(SimpletypesConfig.class, ""),
- TEST_TYPES_FILE);
+ new FileSource(TEST_TYPES_FILE));
sub.reload(1);
Files.delete(TEST_TYPES_FILE.toPath()); // delete file so the below statement throws exception
sub.nextConfig(0);
}
+
}
diff --git a/container-core/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java b/container-core/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java
index 942555e391d..df92160550c 100644
--- a/container-core/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java
+++ b/container-core/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java
@@ -9,7 +9,6 @@ import com.yahoo.container.di.ConfigRetriever.BootstrapConfigs;
import com.yahoo.container.di.ConfigRetriever.ComponentsConfigs;
import com.yahoo.container.di.ConfigRetriever.ConfigSnapshot;
import com.yahoo.vespa.config.ConfigKey;
-import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -39,12 +38,7 @@ public class ConfigRetrieverTest {
@BeforeEach
public void setup() {
- dirConfigSource = new DirConfigSource(tmpDir, "ConfigRetrieverTest-");
- }
-
- @AfterEach
- public void cleanup() {
- dirConfigSource.cleanup();
+ dirConfigSource = new DirConfigSource(tmpDir);
}
@Test
@@ -54,6 +48,7 @@ public class ConfigRetrieverTest {
ConfigSnapshot bootstrapConfigs = retriever.getConfigs(Collections.emptySet(), 0, true);
assertTrue(bootstrapConfigs instanceof BootstrapConfigs);
+ retriever.shutdown();
}
@Test
@@ -71,12 +66,12 @@ public class ConfigRetrieverTest {
} else {
fail("ComponentsConfigs has unexpected type: " + componentsConfigs);
}
+ retriever.shutdown();
}
@Disabled
@SuppressWarnings("unused")
public void require_exception_upon_modified_components_keys_without_bootstrap() {
-
writeConfigs();
ConfigRetriever retriever = createConfigRetriever();
ConfigKey<? extends ConfigInstance> testConfigKey = new ConfigKey<>(TestConfig.class, dirConfigSource.configId());
@@ -99,6 +94,7 @@ public class ConfigRetrieverTest {
ConfigRetriever retriever = createConfigRetriever();
assertTrue(retriever.getConfigs(Collections.emptySet(), 0, true) instanceof BootstrapConfigs);
assertTrue(retriever.getConfigs(Collections.emptySet(), 0, true) instanceof ComponentsConfigs);
+ retriever.shutdown();
}
public void writeConfigs() {
diff --git a/container-core/src/test/java/com/yahoo/container/di/ContainerTest.java b/container-core/src/test/java/com/yahoo/container/di/ContainerTest.java
index c0d691c8a5a..d869562cc19 100644
--- a/container-core/src/test/java/com/yahoo/container/di/ContainerTest.java
+++ b/container-core/src/test/java/com/yahoo/container/di/ContainerTest.java
@@ -66,6 +66,7 @@ public class ContainerTest extends ContainerTestBase {
assertEquals("reconfigured", component2.config.stringVal());
container.shutdownConfigRetriever();
+ container.shutdown(newComponentGraph);
}
@Test
@@ -90,6 +91,7 @@ public class ContainerTest extends ContainerTestBase {
assertNotNull(ComponentGraph.getNode(newGraph, "id2"));
container.shutdownConfigRetriever();
+ container.shutdown(newGraph);
}
@Test
@@ -107,15 +109,14 @@ public class ContainerTest extends ContainerTestBase {
writeBootstrapConfigsWithBundles(List.of("bundle-2"), List.of(component2));
container.reloadConfig(2);
- getNewComponentGraph(container, graph);
+ ComponentGraph newGraph = getNewComponentGraph(container, graph);
// bundle-2 is installed, bundle-1 has been uninstalled
assertEquals(1, osgi.getBundles().length);
assertEquals("bundle-2", osgi.getBundles()[0].getSymbolicName());
- }
- //@Test TODO
- public void deconstructor_is_given_guice_components() {
+ container.shutdownConfigRetriever();
+ container.shutdown(newGraph);
}
@Test
@@ -129,11 +130,14 @@ public class ContainerTest extends ContainerTestBase {
writeBootstrapConfigs("id2", DestructableComponent.class);
container.reloadConfig(2);
- getNewComponentGraph(container, oldGraph);
+ ComponentGraph newGraph = getNewComponentGraph(container, oldGraph);
assertTrue(componentToDestruct.deconstructed);
+
+ container.shutdownConfigRetriever();
+ container.shutdown(newGraph);
}
- @Disabled // because logAndDie is impossible(?) to verify programmatically
+ @Disabled("because logAndDie is impossible(?) to verify programmatically")
@Test
void manually_verify_what_happens_when_first_graph_contains_component_that_throws_exception_in_ctor() {
writeBootstrapConfigs("thrower", ComponentThrowingExceptionInConstructor.class);
@@ -144,6 +148,8 @@ public class ContainerTest extends ContainerTestBase {
} catch (Throwable t) {
fail("Expected to log and die");
}
+
+ container.shutdownConfigRetriever();
}
// Failure in component construction phase
@@ -172,6 +178,9 @@ public class ContainerTest extends ContainerTestBase {
assertEquals(3, currentGraph.generation());
assertSame(simpleComponent, currentGraph.getInstance(SimpleComponent.class));
assertNotNull(currentGraph.getInstance(ComponentTakingConfig.class));
+
+ container.shutdownConfigRetriever();
+ container.shutdown(currentGraph);
}
@Test
@@ -195,6 +204,9 @@ public class ContainerTest extends ContainerTestBase {
// bundle-1 is kept, bundle-2 has been uninstalled
assertEquals(1, osgi.getBundles().length);
assertEquals("bundle-1", osgi.getBundles()[0].getSymbolicName());
+
+ container.shutdownConfigRetriever();
+ container.shutdown(currentGraph);
}
// Failure in graph creation phase
@@ -213,6 +225,9 @@ public class ContainerTest extends ContainerTestBase {
container.reloadConfig(2);
assertNewComponentGraphFails(container, currentGraph, IllegalArgumentException.class);
assertEquals(1, currentGraph.generation());
+
+ container.shutdownConfigRetriever();
+ container.shutdown(currentGraph);
}
@Test
@@ -238,6 +253,9 @@ public class ContainerTest extends ContainerTestBase {
// bundle-1 is kept, bundle-2 has been uninstalled
assertEquals(1, osgi.getBundles().length);
assertEquals("bundle-1", osgi.getBundles()[0].getSymbolicName());
+
+ container.shutdownConfigRetriever();
+ container.shutdown(currentGraph);
}
private void assertNewComponentGraphFails(Container container, ComponentGraph currentGraph, Class<? extends RuntimeException> exception) {
@@ -261,11 +279,12 @@ public class ContainerTest extends ContainerTestBase {
container.reloadConfig(2);
assertThrows(IllegalArgumentException.class,
- () -> getNewComponentGraph(container, currentGraph));
+ () -> getNewComponentGraph(container, currentGraph));
ExecutorService exec = Executors.newFixedThreadPool(1);
+ dirConfigSource.clearCheckedConfigs();
Future<ComponentGraph> newGraph = exec.submit(() -> getNewComponentGraph(container, currentGraph));
-
+ dirConfigSource.awaitConfigChecked(10_000);
try {
newGraph.get(1, TimeUnit.SECONDS);
fail("Expected waiting for new config.");
@@ -276,11 +295,14 @@ public class ContainerTest extends ContainerTestBase {
writeBootstrapConfigs("myId2", ComponentTakingConfig.class);
container.reloadConfig(3);
- assertNotNull(newGraph.get(5, TimeUnit.MINUTES));
+ assertNotNull(newGraph.get(10, TimeUnit.SECONDS));
+
+ container.shutdownConfigRetriever();
+ container.shutdown(newGraph.get());
}
@Test
- void providers_are_destructed() {
+ void providers_are_destroyed() {
writeBootstrapConfigs("id1", DestructableProvider.class);
ComponentDeconstructor deconstructor = (generation, components, bundles) -> {
@@ -301,9 +323,12 @@ public class ContainerTest extends ContainerTestBase {
writeBootstrapConfigs("id2", DestructableProvider.class);
container.reloadConfig(2);
- getNewComponentGraph(container, oldGraph);
+ ComponentGraph graph = getNewComponentGraph(container, oldGraph);
assertTrue(destructableEntity.deconstructed);
+
+ container.shutdownConfigRetriever();
+ container.shutdown(graph);
}
@Test
@@ -313,6 +338,7 @@ public class ContainerTest extends ContainerTestBase {
Container container = newContainer(dirConfigSource);
ComponentGraph oldGraph = getNewComponentGraph(container);
+ container.shutdown(oldGraph);
}
static class DestructableEntity {
diff --git a/container-core/src/test/java/com/yahoo/container/di/ContainerTestBase.java b/container-core/src/test/java/com/yahoo/container/di/ContainerTestBase.java
index 7442eb2068d..0ad376a13d8 100644
--- a/container-core/src/test/java/com/yahoo/container/di/ContainerTestBase.java
+++ b/container-core/src/test/java/com/yahoo/container/di/ContainerTestBase.java
@@ -6,7 +6,6 @@ import com.yahoo.container.core.config.BundleTestUtil;
import com.yahoo.container.core.config.TestOsgi;
import com.yahoo.container.di.ContainerTest.ComponentTakingConfig;
import com.yahoo.container.di.componentgraph.core.ComponentGraph;
-import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.io.TempDir;
import org.osgi.framework.Bundle;
@@ -31,20 +30,14 @@ public class ContainerTestBase {
@BeforeEach
public void setup() {
- dirConfigSource = new DirConfigSource(tmpDir, "ContainerTest-");
+ dirConfigSource = new DirConfigSource(tmpDir);
componentGraph = new ComponentGraph(0);
osgi = new TestOsgi(BundleTestUtil.testBundles());
}
- @AfterEach
- public void cleanup() {
- dirConfigSource.cleanup();
- }
-
-
protected Container newContainer(DirConfigSource dirConfigSource,
ComponentDeconstructor deconstructor) {
- return new Container(new CloudSubscriberFactory(dirConfigSource.configSource),
+ return new Container(new CloudSubscriberFactory(dirConfigSource.configSource()),
dirConfigSource.configId(),
deconstructor,
osgi);
diff --git a/container-core/src/test/java/com/yahoo/container/di/DirConfigSource.java b/container-core/src/test/java/com/yahoo/container/di/DirConfigSource.java
index db7e93f7c6e..3d1d052b35b 100644
--- a/container-core/src/test/java/com/yahoo/container/di/DirConfigSource.java
+++ b/container-core/src/test/java/com/yahoo/container/di/DirConfigSource.java
@@ -2,60 +2,72 @@
package com.yahoo.container.di;
import com.yahoo.config.subscription.ConfigSource;
-import com.yahoo.config.subscription.ConfigSourceSet;
+import com.yahoo.config.subscription.DirSource;
+import com.yahoo.config.subscription.FileSource;
+import org.junit.jupiter.api.Assertions;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Random;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.util.HashSet;
+import java.util.Set;
/**
* @author Tony Vaagenes
* @author gjoranv
* @author ollivir
*/
-public class DirConfigSource {
+class DirConfigSource {
+ private final Set<String> checked = new HashSet<>();
private final File tempFolder;
- public final ConfigSource configSource;
+ private boolean doubleChecked;
- public DirConfigSource(File tmpDir, String testSourcePrefix) {
+ DirConfigSource(File tmpDir) {
this.tempFolder = tmpDir;
- this.configSource = new ConfigSourceSet(testSourcePrefix + new Random().nextLong());
}
- public void writeConfig(String name, String contents) {
- File file = new File(tempFolder, name + ".cfg");
- if (!file.exists()) {
- try {
- file.createNewFile();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ void writeConfig(String name, String contents) {
+ try {
+ Files.writeString(tempFolder.toPath().resolve(name + ".cfg"), contents);
+ }
+ catch (IOException e) {
+ throw new UncheckedIOException(e);
}
-
- printFile(file, contents + "\n");
}
- public String configId() {
+ String configId() {
return "dir:" + tempFolder.getPath();
}
- public ConfigSource configSource() {
- return configSource;
+ synchronized void clearCheckedConfigs() {
+ checked.clear();
+ doubleChecked = false;
}
- public void cleanup() {
- tempFolder.delete();
+ synchronized void awaitConfigChecked(long millis) throws InterruptedException {
+ long remaining, doom = System.currentTimeMillis() + millis;
+ while ( ! doubleChecked && (remaining = doom - System.currentTimeMillis()) > 0) wait(remaining);
+ Assertions.assertTrue(doubleChecked, "no config was checked more than once during " + millis + " millis");
}
- private static void printFile(File f, String content) {
- try (OutputStream out = new FileOutputStream(f)) {
- out.write(content.getBytes("UTF-8"));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ ConfigSource configSource() {
+ return new DirSource(tempFolder) {
+ @Override public FileSource getFile(String name) {
+ return new FileSource(new File(tempFolder, name)) {
+ @Override public long getLastModified() {
+ synchronized (DirConfigSource.this) {
+ if ( ! checked.add(name)) {
+ doubleChecked = true;
+ DirConfigSource.this.notifyAll();
+ }
+ return super.getLastModified();
+ }
+ }
+ };
+ }
+ };
}
}
diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/ContainerThreadFactory.java b/container-disc/src/main/java/com/yahoo/container/jdisc/ContainerThreadFactory.java
index 92969ef9e97..b087c4e80b3 100644
--- a/container-disc/src/main/java/com/yahoo/container/jdisc/ContainerThreadFactory.java
+++ b/container-disc/src/main/java/com/yahoo/container/jdisc/ContainerThreadFactory.java
@@ -3,7 +3,6 @@ package com.yahoo.container.jdisc;
import com.yahoo.container.jdisc.metric.MetricConsumerProvider;
import com.yahoo.jdisc.application.ContainerThread;
-import com.yahoo.jdisc.application.MetricConsumer;
import java.util.concurrent.ThreadFactory;
@@ -15,14 +14,7 @@ public class ContainerThreadFactory implements ThreadFactory {
private final ThreadFactory delegate;
public ContainerThreadFactory(MetricConsumerProvider metricConsumerProvider) {
- metricConsumerProvider.getClass(); // throws NullPointerException
- delegate = new ContainerThread.Factory(new com.google.inject.Provider<MetricConsumer>() {
-
- @Override
- public MetricConsumer get() {
- return metricConsumerProvider.newInstance();
- }
- });
+ delegate = new ContainerThread.Factory(metricConsumerProvider::newInstance);
}
@Override
diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricProvider.java b/container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricProvider.java
index b547b3dd897..1afe152a420 100644
--- a/container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricProvider.java
+++ b/container-disc/src/main/java/com/yahoo/container/jdisc/metric/MetricProvider.java
@@ -3,7 +3,6 @@ package com.yahoo.container.jdisc.metric;
import com.yahoo.container.di.componentgraph.Provider;
import com.yahoo.jdisc.Metric;
-import com.yahoo.jdisc.application.MetricConsumer;
/**
* An implementation of {@link Provider} component of <code>Metric</code>. Because this class depends on {@link
@@ -17,13 +16,7 @@ public final class MetricProvider implements Provider<Metric> {
private final Metric metric;
public MetricProvider(MetricConsumerProvider provider) {
- metric = new com.yahoo.jdisc.application.MetricProvider(new com.google.inject.Provider<MetricConsumer>() {
-
- @Override
- public MetricConsumer get() {
- return provider.newInstance();
- }
- }).get();
+ metric = new com.yahoo.jdisc.application.MetricProvider(provider::newInstance).get();
}
@Override
diff --git a/jdisc_core/src/main/java/com/yahoo/jdisc/application/MetricImpl.java b/jdisc_core/src/main/java/com/yahoo/jdisc/application/MetricImpl.java
index 5a6a1f96bad..994bfc0fc3f 100644
--- a/jdisc_core/src/main/java/com/yahoo/jdisc/application/MetricImpl.java
+++ b/jdisc_core/src/main/java/com/yahoo/jdisc/application/MetricImpl.java
@@ -45,11 +45,7 @@ class MetricImpl implements Metric {
}
private MetricConsumer currentConsumer() {
- Thread thread = Thread.currentThread();
- if (thread instanceof ContainerThread) {
- return ((ContainerThread)thread).consumer();
- }
- return consumer.get();
+ return Thread.currentThread() instanceof ContainerThread thread ? thread.consumer() : consumer.get();
}
private static class LocalConsumer extends ThreadLocal<MetricConsumer> {
diff --git a/messagebus/src/test/java/com/yahoo/messagebus/ConfigAgentTestCase.java b/messagebus/src/test/java/com/yahoo/messagebus/ConfigAgentTestCase.java
index ad8e8a7c94e..f9185bfe0e0 100755
--- a/messagebus/src/test/java/com/yahoo/messagebus/ConfigAgentTestCase.java
+++ b/messagebus/src/test/java/com/yahoo/messagebus/ConfigAgentTestCase.java
@@ -5,21 +5,18 @@ import com.yahoo.config.subscription.ConfigSet;
import com.yahoo.config.subscription.ConfigURI;
import com.yahoo.messagebus.routing.RoutingSpec;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.io.TempDir;
-import java.io.File;
import java.util.concurrent.TimeUnit;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Simon Thoresen Hult
*/
public class ConfigAgentTestCase {
- @TempDir
- public File tmpFolder;
-
@Test
void testRoutingConfig() throws InterruptedException {
LocalHandler handler = new LocalHandler();