summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Musum <musum@verizonmedia.com>2020-12-08 13:35:44 +0100
committerGitHub <noreply@github.com>2020-12-08 13:35:44 +0100
commit1fce95eefd21a4a0686dbf8557cb540894029a1f (patch)
treef0535c9ae6ccbf13bf0ad3ce15322a964f261b90
parent10464c859ccca2596e2b841612f8ea958330e4dc (diff)
Revert "Bratseth/simplify config take 2"
-rw-r--r--config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServer.java1
-rw-r--r--config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigTester.java4
-rw-r--r--config-proxy/src/test/java/com/yahoo/vespa/config/proxy/MemoryCacheTest.java6
-rw-r--r--config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ProxyServerTest.java14
-rw-r--r--config/abi-spec.json1
-rw-r--r--config/src/apps/vespa-get-config/getconfig.cpp3
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java22
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/ConfigSubscription.java32
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java13
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java3
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/JarConfigSubscription.java2
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java2
-rw-r--r--config/src/main/java/com/yahoo/config/subscription/impl/RawConfigSubscription.java2
-rwxr-xr-xconfig/src/main/java/com/yahoo/vespa/config/RawConfig.java22
-rw-r--r--config/src/main/java/com/yahoo/vespa/config/protocol/ConfigResponse.java2
-rw-r--r--config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequest.java3
-rw-r--r--config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequestV3.java6
-rw-r--r--config/src/main/java/com/yahoo/vespa/config/protocol/JRTServerConfigRequest.java11
-rw-r--r--config/src/main/java/com/yahoo/vespa/config/protocol/JRTServerConfigRequestV3.java9
-rw-r--r--config/src/main/java/com/yahoo/vespa/config/protocol/SlimeConfigResponse.java15
-rw-r--r--config/src/main/java/com/yahoo/vespa/config/protocol/SlimeResponseData.java6
-rwxr-xr-xconfig/src/test/java/com/yahoo/config/subscription/ConfigApiTest.java4
-rw-r--r--config/src/test/java/com/yahoo/config/subscription/impl/JRTConfigRequesterTest.java6
-rw-r--r--config/src/test/java/com/yahoo/vespa/config/RawConfigTest.java26
-rw-r--r--config/src/test/java/com/yahoo/vespa/config/protocol/ConfigResponseTest.java4
-rw-r--r--config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestV3Test.java22
-rw-r--r--config/src/tests/configagent/configagent.cpp3
-rw-r--r--config/src/tests/frt/frt.cpp8
-rw-r--r--config/src/vespa/config/common/configstate.h5
-rw-r--r--config/src/vespa/config/frt/protocol.cpp1
-rw-r--r--config/src/vespa/config/frt/protocol.h1
-rw-r--r--config/src/vespa/config/frt/slimeconfigresponse.cpp1
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelController.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java5
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java1
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/rpc/ConfigResponseFactory.java8
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/rpc/GetConfigProcessor.java6
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/rpc/LZ4ConfigResponseFactory.java3
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/rpc/UncompressedConfigResponseFactory.java3
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ServerCacheTest.java6
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelRequestHandlerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationMapperTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationSetTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationTest.java4
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/application/ConfigConvergenceCheckerTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/application/FileDistributionStatusTest.java1
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/application/TenantApplicationsTest.java1
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpConfigResponseTest.java2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/metrics/DeploymentMetricsRetrieverTest.java4
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/metrics/ProtonMetricsRetrieverTest.java4
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/rpc/ConfigResponseFactoryTest.java4
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/rpc/RpcServerTest.java1
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRepositoryTest.java1
-rw-r--r--container-core/src/main/java/com/yahoo/container/core/config/HandlersConfigurerDi.java7
-rw-r--r--container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java2
-rw-r--r--container-di/src/main/java/com/yahoo/container/di/CloudSubscriberFactory.java12
-rw-r--r--container-di/src/main/java/com/yahoo/container/di/ConfigRetriever.java18
-rw-r--r--container-di/src/main/java/com/yahoo/container/di/Container.java7
-rw-r--r--container-di/src/main/java/com/yahoo/container/di/config/Subscriber.java1
-rw-r--r--container-di/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java24
-rw-r--r--container-di/src/test/java/com/yahoo/container/di/ContainerTest.java4
-rw-r--r--container-di/src/test/java/com/yahoo/container/di/ContainerTestBase.java2
-rw-r--r--container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java6
-rw-r--r--container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java2
-rw-r--r--standalone-container/src/main/java/com/yahoo/container/standalone/StandaloneSubscriberFactory.java3
65 files changed, 286 insertions, 126 deletions
diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServer.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServer.java
index fbc10c772d7..81ecd8620b9 100644
--- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServer.java
+++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServer.java
@@ -352,6 +352,7 @@ public class ConfigProxyRpcServer implements Runnable, TargetWatcher, RpcServer
request.getRequestTrace().trace(TRACELEVEL, "Config proxy returnOkResponse()");
request.addOkResponse(config.getPayload(),
config.getGeneration(),
+ config.isInternalRedeploy(),
config.applyOnRestart(),
config.getConfigMd5());
log.log(Level.FINE, () -> "Return response: " + request.getShortDescription() + ",configMd5=" + config.getConfigMd5() +
diff --git a/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigTester.java b/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigTester.java
index 33e798da15e..87a8764310a 100644
--- a/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigTester.java
+++ b/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigTester.java
@@ -44,11 +44,11 @@ public class ConfigTester {
String defMd5 = ConfigUtils.getDefMd5(defContent);
String configMd5 = ConfigUtils.getMd5(fooConfigPayload);
fooConfig = new RawConfig(configKey, defMd5, fooPayload, configMd5,
- generation, false, defContent, Optional.empty());
+ generation, false, false, defContent, Optional.empty());
String defName2 = "bar";
barConfig = new RawConfig(new ConfigKey<>(defName2, configId, namespace), defMd5, fooPayload, configMd5,
- generation, false, defContent, Optional.empty());
+ generation, false, false, defContent, Optional.empty());
}
JRTServerConfigRequest createRequest(RawConfig config) {
diff --git a/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/MemoryCacheTest.java b/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/MemoryCacheTest.java
index 485a091d9ae..c5e680f950a 100644
--- a/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/MemoryCacheTest.java
+++ b/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/MemoryCacheTest.java
@@ -63,9 +63,9 @@ public class MemoryCacheTest {
slime.setString("bar \"value2\"");
payloadDifferentMd5 = Payload.from(new ConfigPayload(slime));
- config = new RawConfig(configKey, defMd5, payload, configMd5, generation, false, defContent, Optional.empty());
- config2 = new RawConfig(configKey2, defMd52, payload2, configMd5, generation, false, defContent, Optional.empty());
- configDifferentMd5 = new RawConfig(configKey, differentDefMd5, payloadDifferentMd5, configMd5, generation, false, defContent, Optional.empty());
+ config = new RawConfig(configKey, defMd5, payload, configMd5, generation, false, false, defContent, Optional.empty());
+ config2 = new RawConfig(configKey2, defMd52, payload2, configMd5, generation, false, false, defContent, Optional.empty());
+ configDifferentMd5 = new RawConfig(configKey, differentDefMd5, payloadDifferentMd5, configMd5, generation, false, false, defContent, Optional.empty());
cacheKey = new ConfigCacheKey(configKey, config.getDefMd5());
cacheKey2 = new ConfigCacheKey(configKey2, config2.getDefMd5());
diff --git a/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ProxyServerTest.java b/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ProxyServerTest.java
index 87c1fa151f8..c858f894fc4 100644
--- a/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ProxyServerTest.java
+++ b/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ProxyServerTest.java
@@ -34,9 +34,9 @@ public class ProxyServerTest {
// errorConfig based on fooConfig
private static final ConfigKey<?> errorConfigKey = new ConfigKey<>("error", fooConfig.getConfigId(), fooConfig.getNamespace());
- static final RawConfig errorConfig = new RawConfig(errorConfigKey, fooConfig.getDefMd5(), fooConfig.getPayload(),
- fooConfig.getConfigMd5(), fooConfig.getGeneration(), false,
- ErrorCode.UNKNOWN_DEFINITION, fooConfig.getDefContent(), Optional.empty());
+ static final RawConfig errorConfig = new RawConfig(errorConfigKey, fooConfig.getDefMd5(),
+ fooConfig.getPayload(), fooConfig.getConfigMd5(),
+ fooConfig.getGeneration(), false, false, ErrorCode.UNKNOWN_DEFINITION, fooConfig.getDefContent(), Optional.empty());
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@@ -178,9 +178,9 @@ public class ProxyServerTest {
assertEquals(1, cache.size());
// Simulate an empty response
- RawConfig emptyConfig = new RawConfig(fooConfig.getKey(), fooConfig.getDefMd5(), Payload.from("{}"),
- fooConfig.getConfigMd5(), 0, false,
- 0, fooConfig.getDefContent(), Optional.empty());
+ RawConfig emptyConfig = new RawConfig(fooConfig.getKey(), fooConfig.getDefMd5(),
+ Payload.from("{}"), fooConfig.getConfigMd5(),
+ 0, false, false, 0, fooConfig.getDefContent(), Optional.empty());
source.put(fooConfig.getKey(), emptyConfig);
res = proxy.resolveConfig(tester.createRequest(fooConfig));
@@ -239,7 +239,7 @@ public class ProxyServerTest {
static RawConfig createConfigWithNextConfigGeneration(RawConfig config, int errorCode, Payload payload, long configGeneration) {
return new RawConfig(config.getKey(), config.getDefMd5(),
payload, config.getConfigMd5(),
- configGeneration, false,
+ configGeneration, false, false,
errorCode, config.getDefContent(), Optional.empty());
}
diff --git a/config/abi-spec.json b/config/abi-spec.json
index a41df9aa60d..b60f9053642 100644
--- a/config/abi-spec.json
+++ b/config/abi-spec.json
@@ -218,6 +218,7 @@
"public boolean isClosed()",
"public com.yahoo.config.subscription.ConfigHandle subscribe(com.yahoo.config.subscription.ConfigSubscriber$SingleSubscriber, java.lang.Class, java.lang.String)",
"public long getGeneration()",
+ "public boolean isInternalRedeploy()",
"protected void finalize()"
],
"fields": [
diff --git a/config/src/apps/vespa-get-config/getconfig.cpp b/config/src/apps/vespa-get-config/getconfig.cpp
index 65dc800c275..92966b934f1 100644
--- a/config/src/apps/vespa-get-config/getconfig.cpp
+++ b/config/src/apps/vespa-get-config/getconfig.cpp
@@ -220,7 +220,7 @@ GetConfig::Main()
FRTConfigRequestFactory requestFactory(protocolVersion, traceLevel, vespaVersion, config::protocol::readProtocolCompressionType());
FRTConnection connection(spec, _server->supervisor(), TimingValues());
ConfigKey key(configId, defName, defNamespace, defMD5, defSchema);
- ConfigState state(configMD5, generation, false);
+ ConfigState state(configMD5, generation, false, false);
FRTConfigRequest::UP request = requestFactory.createConfigRequest(key, &connection, state, serverTimeout * 1000);
_target->InvokeSync(request->getRequest(), clientTimeout); // seconds
@@ -244,6 +244,7 @@ GetConfig::Main()
printf("configMD5 %s\n", rState.md5.c_str());
printf("generation %" PRId64 "\n", rState.generation);
+ printf("internalRedeploy %s\n", rState.internalRedeploy == 0 ? "false" : "true");
printf("trace %s\n", response->getTrace().toString().c_str());
} else if (traceLevel > 0) {
printf("trace %s\n", response->getTrace().toString().c_str());
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 de44d0b86c4..ad131f8e0dd 100644
--- a/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java
+++ b/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java
@@ -43,6 +43,9 @@ public class ConfigSubscriber implements AutoCloseable {
/** The last complete config generation received by this */
private long generation = -1;
+ /** Whether the last generation received was due to a system-internal redeploy, not an application package change */
+ private boolean internalRedeploy = false;
+
/**
* Whether the last generation should only be applied on restart, not immediately.
* Once this is set it will not be unset, as no future generation should be applied
@@ -244,13 +247,11 @@ public class ConfigSubscriber implements AutoCloseable {
* the config should be applied at this time, false otherwise
*/
private boolean acquireSnapshot(long timeoutInMillis, boolean requireChange) {
- boolean initialConfiguration;
boolean applyOnRestartOnly;
synchronized (monitor) {
if (state == State.CLOSED) return false;
state = State.FROZEN;
applyOnRestartOnly = applyOnRestart;
- initialConfiguration = generation == -1;
}
long started = System.currentTimeMillis();
long timeLeftMillis = timeoutInMillis;
@@ -261,6 +262,7 @@ public class ConfigSubscriber implements AutoCloseable {
h.setChanged(false); // Reset this flag, if it was set, the user should have acted on it the last time this method returned true.
}
boolean reconfigDue;
+ boolean internalRedeployOnly = true;
do {
boolean allGenerationsChanged = true;
boolean allGenerationsTheSame = true;
@@ -276,14 +278,15 @@ public class ConfigSubscriber implements AutoCloseable {
if (currentGen == null) currentGen = config.getGeneration();
allGenerationsTheSame &= currentGen.equals(config.getGeneration());
allGenerationsChanged &= config.isGenerationChanged();
- anyConfigChanged |= config.isConfigChanged();
- applyOnRestartOnly |= config.applyOnRestart();
+ anyConfigChanged |= config.isConfigChanged();
+ internalRedeployOnly &= config.isInternalRedeploy();
+ applyOnRestartOnly |= requireChange && config.applyOnRestart(); // only if this is reconfig
timeLeftMillis = timeoutInMillis + started - System.currentTimeMillis();
}
- reconfigDue = ( initialConfiguration || (anyConfigChanged && !applyOnRestartOnly))
+ reconfigDue = ((anyConfigChanged && !applyOnRestartOnly) || !requireChange)
&& allGenerationsChanged && allGenerationsTheSame;
- if (applyOnRestartOnly && ! initialConfiguration) { // disable any reconfig until restart
+ if (requireChange && applyOnRestartOnly) { // if this is a reconfig, disable future reconfigs until restart
synchronized (monitor) {
applyOnRestart = applyOnRestartOnly;
}
@@ -298,6 +301,7 @@ public class ConfigSubscriber implements AutoCloseable {
// Also if appropriate update the changed flag on the handler, which clients use.
markSubsChangedSeen(currentGen);
synchronized (monitor) {
+ internalRedeploy = internalRedeployOnly;
generation = currentGen;
}
}
@@ -487,6 +491,12 @@ public class ConfigSubscriber implements AutoCloseable {
}
/**
+ * Whether the current config generation received by this was due to a system-internal redeploy,
+ * not an application package change
+ */
+ public boolean isInternalRedeploy() { synchronized (monitor) { return internalRedeploy; } }
+
+ /**
* Convenience interface for clients who only subscribe to one config. Implement this, and pass it to {@link ConfigSubscriber#subscribe(SingleSubscriber, Class, String)}.
*
* @author vegardh
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 b58817305e9..15f6395c417 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
@@ -25,7 +25,7 @@ import com.yahoo.vespa.config.protocol.DefContent;
*/
public abstract class ConfigSubscription<T extends ConfigInstance> {
- protected static final Logger log = Logger.getLogger(ConfigSubscription.class.getName());
+ protected static Logger log = Logger.getLogger(ConfigSubscription.class.getName());
protected final ConfigSubscriber subscriber;
private final AtomicReference<ConfigState<T>> config = new AtomicReference<>();
protected final ConfigKey<T> key;
@@ -39,26 +39,29 @@ public abstract class ConfigSubscription<T extends ConfigInstance> {
private final boolean generationChanged;
private final T config;
private final Long generation;
+ private final boolean internalRedeploy;
private final boolean applyOnRestart;
private ConfigState(boolean generationChanged,
Long generation,
+ boolean internalRedeploy,
boolean applyOnRestart,
boolean configChanged,
T config) {
this.generationChanged = generationChanged;
this.generation = generation;
+ this.internalRedeploy = internalRedeploy;
this.applyOnRestart = applyOnRestart;
this.configChanged = configChanged;
this.config = config;
}
private ConfigState(Long generation, T config) {
- this(false, generation, false, false, config);
+ this(false, generation, false, false, false, config);
}
private ConfigState() {
- this(false, 0L, false, false, null);
+ this(false, 0L, false, false, false, null);
}
private ConfigState<T> createUnchanged() { return new ConfigState<>(generation, config); }
@@ -66,6 +69,12 @@ public abstract class ConfigSubscription<T extends ConfigInstance> {
public boolean isGenerationChanged() { return generationChanged; }
public Long getGeneration() { return generation; }
+ /**
+ * Returns whether this config generation was caused by a system-internal redeploy,
+ * not an application package change
+ */
+ public boolean isInternalRedeploy() { return internalRedeploy; }
+
public boolean applyOnRestart() { return applyOnRestart; }
public T getConfig() { return config; }
@@ -181,29 +190,34 @@ public abstract class ConfigSubscription<T extends ConfigInstance> {
return !prev.getGeneration().equals(requiredGen) || prev.isConfigChanged();
}
- void setConfig(Long generation, boolean applyOnRestart, T config) {
- this.config.set(new ConfigState<>(true, generation, applyOnRestart, true, config));
+ void setConfig(Long generation, boolean internalRedeploy, boolean applyOnRestart, T config) {
+ this.config.set(new ConfigState<>(true, generation, internalRedeploy, applyOnRestart, true, config));
}
/** Used by {@link FileConfigSubscription} and {@link ConfigSetSubscription} */
protected void setConfigIncGen(T config) {
ConfigState<T> prev = this.config.get();
- this.config.set(new ConfigState<>(true, prev.getGeneration() + 1, prev.applyOnRestart(), true, config));
+ this.config.set(new ConfigState<>(true, prev.getGeneration() + 1, prev.isInternalRedeploy(), prev.applyOnRestart(), true, config));
}
protected void setConfigIfChanged(T config) {
ConfigState<T> prev = this.config.get();
- this.config.set(new ConfigState<>(true, prev.getGeneration(), prev.applyOnRestart(), !config.equals(prev.getConfig()), config));
+ this.config.set(new ConfigState<>(true, prev.getGeneration(), prev.isInternalRedeploy(), prev.applyOnRestart(), !config.equals(prev.getConfig()), config));
}
void setGeneration(Long generation) {
ConfigState<T> prev = config.get();
- this.config.set(new ConfigState<>(true, generation, prev.applyOnRestart(), prev.isConfigChanged(), prev.getConfig()));
+ this.config.set(new ConfigState<>(true, generation, prev.isInternalRedeploy(), prev.applyOnRestart(), prev.isConfigChanged(), prev.getConfig()));
+ }
+
+ void setInternalRedeploy(boolean internalRedeploy) {
+ ConfigState<T> prev = config.get();
+ this.config.set(new ConfigState<>(prev.isGenerationChanged(), prev.getGeneration(), internalRedeploy, prev.applyOnRestart(), prev.isConfigChanged(), prev.getConfig()));
}
void setApplyOnRestart(boolean applyOnRestart) {
ConfigState<T> prev = config.get();
- this.config.set(new ConfigState<>(prev.isGenerationChanged(), prev.getGeneration(), applyOnRestart, prev.isConfigChanged(), prev.getConfig()));
+ this.config.set(new ConfigState<>(prev.isGenerationChanged(), prev.getGeneration(), prev.isInternalRedeploy(), applyOnRestart, prev.isConfigChanged(), prev.getConfig()));
}
/**
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java
index b052c79f429..ba8fc8a5e19 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/GenericJRTConfigSubscription.java
@@ -32,7 +32,7 @@ public class GenericJRTConfigSubscription extends JRTConfigSubscription<RawConfi
@Override
protected void setNewConfig(JRTClientConfigRequest jrtReq) {
- setConfig(jrtReq.getNewGeneration(), jrtReq.responseIsApplyOnRestart(), RawConfig.createFromResponseParameters(jrtReq) );
+ setConfig(jrtReq.getNewGeneration(), jrtReq.responseIsInternalRedeploy(), jrtReq.responseIsApplyOnRestart(), RawConfig.createFromResponseParameters(jrtReq) );
log.log(FINE, () -> "in setNewConfig, config=" + this.getConfigState().getConfig());
}
@@ -50,6 +50,17 @@ public class GenericJRTConfigSubscription extends JRTConfigSubscription<RawConfi
// Override to propagate internal redeploy into the config value in addition to the config state
@Override
+ void setInternalRedeploy(boolean internalRedeploy) {
+ super.setInternalRedeploy(internalRedeploy);
+ ConfigState<RawConfig> configState = getConfigState();
+
+ if (configState.getConfig() != null) {
+ configState.getConfig().setInternalRedeploy(internalRedeploy);
+ }
+ }
+
+ // Override to propagate internal redeploy into the config value in addition to the config state
+ @Override
void setApplyOnRestart(boolean applyOnRestart) {
super.setApplyOnRestart(applyOnRestart);
ConfigState<RawConfig> configState = getConfigState();
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java
index b48e5905239..e9d5d317995 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigSubscription.java
@@ -93,6 +93,7 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc
}
log.log(FINE, () -> "Polled queue and found config " + jrtReq);
if (jrtReq.hasUpdatedGeneration()) {
+ setInternalRedeploy(jrtReq.responseIsInternalRedeploy());
setApplyOnRestart(jrtReq.responseIsApplyOnRestart());
if (jrtReq.hasUpdatedConfig()) {
setNewConfig(jrtReq);
@@ -111,7 +112,7 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc
} catch (IllegalArgumentException e) {
badConfigE = e;
}
- setConfig(jrtReq.getNewGeneration(), jrtReq.responseIsApplyOnRestart(), configInstance);
+ setConfig(jrtReq.getNewGeneration(), jrtReq.responseIsInternalRedeploy(), jrtReq.responseIsApplyOnRestart(), configInstance);
if (badConfigE != null) {
throw new IllegalArgumentException("Bad config from jrt", badConfigE);
}
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/JarConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/JarConfigSubscription.java
index 05da9a72837..9fc5d9d3300 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/JarConfigSubscription.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/JarConfigSubscription.java
@@ -63,7 +63,7 @@ public class JarConfigSubscription<T extends ConfigInstance> extends ConfigSubsc
} catch (IOException e) {
throw new ConfigurationRuntimeException(e);
}
- setConfig(0L, false, config);
+ setConfig(0L, false, false, config);
try {
jarFile.close();
} catch (IOException e) {
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java b/config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java
index 58eed7f9e78..3a284489109 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java
@@ -115,7 +115,7 @@ public class MockConnection implements ConnectionPool, com.yahoo.vespa.config.Co
JRTServerConfigRequestV3 jrtReq = JRTServerConfigRequestV3.createFromRequest(request);
Payload payload = Payload.from(ConfigPayload.empty());
long generation = 1;
- jrtReq.addOkResponse(payload, generation, false, ConfigUtils.getMd5(payload.getData()));
+ jrtReq.addOkResponse(payload, generation, false, false, ConfigUtils.getMd5(payload.getData()));
}
}
diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/RawConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/RawConfigSubscription.java
index 68ff6bb0135..1ff0a058a93 100644
--- a/config/src/main/java/com/yahoo/config/subscription/impl/RawConfigSubscription.java
+++ b/config/src/main/java/com/yahoo/config/subscription/impl/RawConfigSubscription.java
@@ -35,7 +35,7 @@ public class RawConfigSubscription<T extends ConfigInstance> extends ConfigSubsc
if (payload == null) {
payload = inputPayload;
ConfigPayload configPayload = new CfgConfigPayloadBuilder().deserialize(Arrays.asList(payload.split("\n")));
- setConfig(0L, false, configPayload.toInstance(configClass, key.getConfigId()));
+ setConfig(0L, false, false, configPayload.toInstance(configClass, key.getConfigId()));
return true;
}
try {
diff --git a/config/src/main/java/com/yahoo/vespa/config/RawConfig.java b/config/src/main/java/com/yahoo/vespa/config/RawConfig.java
index 1c28d4c5e05..cf0f1243acf 100755
--- a/config/src/main/java/com/yahoo/vespa/config/RawConfig.java
+++ b/config/src/main/java/com/yahoo/vespa/config/RawConfig.java
@@ -31,6 +31,7 @@ public class RawConfig extends ConfigInstance {
private final String configMd5;
private final Optional<VespaVersion> vespaVersion;
private long generation;
+ private boolean internalRedeploy;
private boolean applyOnRestart;
/**
@@ -40,30 +41,31 @@ public class RawConfig extends ConfigInstance {
* @param defMd5 The md5 sum of the .def-file.
*/
public RawConfig(ConfigKey<?> key, String defMd5) {
- this(key, defMd5, null, "", 0L, false, 0, Collections.emptyList(), Optional.empty());
+ this(key, defMd5, null, "", 0L, false, false, 0, Collections.emptyList(), Optional.empty());
}
public RawConfig(ConfigKey<?> key, String defMd5, Payload payload, String configMd5, long generation,
- boolean applyOnRestart, List<String> defContent,
+ boolean internalRedeploy, boolean applyOnRestart, List<String> defContent,
Optional<VespaVersion> vespaVersion) {
- this(key, defMd5, payload, configMd5, generation, applyOnRestart, 0, defContent, vespaVersion);
+ this(key, defMd5, payload, configMd5, generation, internalRedeploy, applyOnRestart, 0, defContent, vespaVersion);
}
/** Copy constructor */
public RawConfig(RawConfig rawConfig) {
this(rawConfig.key, rawConfig.defMd5, rawConfig.payload, rawConfig.configMd5,
- rawConfig.generation, rawConfig.applyOnRestart,
+ rawConfig.generation, rawConfig.internalRedeploy, rawConfig.applyOnRestart,
rawConfig.errorCode, rawConfig.defContent, rawConfig.getVespaVersion());
}
public RawConfig(ConfigKey<?> key, String defMd5, Payload payload, String configMd5, long generation,
- boolean applyOnRestart, int errorCode, List<String> defContent,
+ boolean internalRedeploy, boolean applyOnRestart, int errorCode, List<String> defContent,
Optional<VespaVersion> vespaVersion) {
this.key = key;
this.defMd5 = ConfigUtils.getDefMd5FromRequest(defMd5, defContent);
this.payload = payload;
this.configMd5 = configMd5;
this.generation = generation;
+ this.internalRedeploy = internalRedeploy;
this.applyOnRestart = applyOnRestart;
this.errorCode = errorCode;
this.defContent = defContent;
@@ -81,6 +83,7 @@ public class RawConfig extends ConfigInstance {
req.getNewPayload(),
req.getNewConfigMd5(),
req.getNewGeneration(),
+ req.responseIsInternalRedeploy(),
req.responseIsApplyOnRestart(),
0,
req.getDefContent().asList(),
@@ -98,6 +101,7 @@ public class RawConfig extends ConfigInstance {
Payload.from(new Utf8String(""), CompressionInfo.uncompressed()),
req.getRequestConfigMd5(),
req.getRequestGeneration(),
+ req.isInternalRedeploy(),
req.applyOnRestart(),
0,
req.getDefContent().asList(),
@@ -121,8 +125,16 @@ public class RawConfig extends ConfigInstance {
public void setGeneration(long generation) { this.generation = generation; }
+ public void setInternalRedeploy(boolean internalRedeploy) { this.internalRedeploy = internalRedeploy; }
+
public void setApplyOnRestart(boolean applyOnRestart) { this.applyOnRestart = applyOnRestart; }
+ /**
+ * Returns whether this config generation was created by a system internal redeploy, not an
+ * application package change.
+ */
+ public boolean isInternalRedeploy() { return internalRedeploy; }
+
public boolean applyOnRestart() { return applyOnRestart; }
public Payload getPayload() { return payload; }
diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/ConfigResponse.java b/config/src/main/java/com/yahoo/vespa/config/protocol/ConfigResponse.java
index 31e280e708c..27f4816849d 100644
--- a/config/src/main/java/com/yahoo/vespa/config/protocol/ConfigResponse.java
+++ b/config/src/main/java/com/yahoo/vespa/config/protocol/ConfigResponse.java
@@ -20,6 +20,8 @@ public interface ConfigResponse {
long getGeneration();
+ boolean isInternalRedeploy();
+
boolean applyOnRestart();
String getConfigMd5();
diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequest.java b/config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequest.java
index 8535cc23225..8f85e2353a5 100644
--- a/config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequest.java
+++ b/config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequest.java
@@ -53,6 +53,9 @@ public interface JRTClientConfigRequest extends JRTConfigRequest {
*/
long getNewGeneration();
+ /** Returns whether this config change is due to an internal change not an application package change */
+ boolean responseIsInternalRedeploy();
+
/** Returns true if this config should only be applied at the last restart, false if it should be applied immediately */
boolean responseIsApplyOnRestart();
diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequestV3.java b/config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequestV3.java
index 87e63399fc3..e04a2179602 100644
--- a/config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequestV3.java
+++ b/config/src/main/java/com/yahoo/vespa/config/protocol/JRTClientConfigRequestV3.java
@@ -180,6 +180,7 @@ public class JRTClientConfigRequestV3 implements JRTClientConfigRequest {
.append("'\n");
sb.append("response='").append(getNewConfigMd5())
.append(",").append(getNewGeneration())
+ .append(",").append(responseIsInternalRedeploy())
.append(",").append(responseIsApplyOnRestart())
.append("'\n");
return sb.toString();
@@ -290,6 +291,11 @@ public class JRTClientConfigRequestV3 implements JRTClientConfigRequest {
}
@Override
+ public boolean responseIsInternalRedeploy() {
+ return responseData.getResponseInternalRedeployment();
+ }
+
+ @Override
public boolean responseIsApplyOnRestart() {
return responseData.getResponseApplyOnRestart();
}
diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/JRTServerConfigRequest.java b/config/src/main/java/com/yahoo/vespa/config/protocol/JRTServerConfigRequest.java
index c085be5924c..dbc6a7bb98d 100644
--- a/config/src/main/java/com/yahoo/vespa/config/protocol/JRTServerConfigRequest.java
+++ b/config/src/main/java/com/yahoo/vespa/config/protocol/JRTServerConfigRequest.java
@@ -32,11 +32,14 @@ public interface JRTServerConfigRequest extends JRTConfigRequest, GetConfigReque
*
* @param payload The config payload that the client should receive.
* @param generation The config generation of the given payload.
+ * @param internalRedeployment whether this payload was generated from an internal redeployment not an
+ * application package change
* @param applyOnRestart true if this config should only be applied on the next restart,
* false if it should be applied right away
* @param configMd5 The md5sum of the given payload.
*/
- void addOkResponse(Payload payload, long generation, boolean applyOnRestart, String configMd5);
+ void addOkResponse(Payload payload, long generation, boolean internalRedeployment, boolean applyOnRestart,
+ String configMd5);
/**
* Get the current config md5 of the client config.
@@ -59,6 +62,12 @@ public interface JRTServerConfigRequest extends JRTConfigRequest, GetConfigReque
*/
boolean isDelayedResponse();
+ /**
+ * Returns whether the response config was created by a system internal redeploy, not an application
+ * package change
+ */
+ boolean isInternalRedeploy();
+
boolean applyOnRestart();
/**
diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/JRTServerConfigRequestV3.java b/config/src/main/java/com/yahoo/vespa/config/protocol/JRTServerConfigRequestV3.java
index 53a2f4019f9..0bc7c44fe9d 100644
--- a/config/src/main/java/com/yahoo/vespa/config/protocol/JRTServerConfigRequestV3.java
+++ b/config/src/main/java/com/yahoo/vespa/config/protocol/JRTServerConfigRequestV3.java
@@ -36,6 +36,7 @@ public class JRTServerConfigRequestV3 implements JRTServerConfigRequest {
protected final Request request;
private final SlimeRequestData requestData;
/** Response field */
+ private boolean internalRedeploy = false;
private boolean applyOnRestart = false;
// Response values
private boolean isDelayed = false;
@@ -67,7 +68,9 @@ public class JRTServerConfigRequestV3 implements JRTServerConfigRequest {
}
@Override
- public void addOkResponse(Payload payload, long generation, boolean applyOnRestart, String configMd5) {
+ public void addOkResponse(Payload payload, long generation, boolean internalRedeploy, boolean applyOnRestart,
+ String configMd5) {
+ this.internalRedeploy = internalRedeploy;
this.applyOnRestart = applyOnRestart;
boolean changedConfig = !configMd5.equals(getRequestConfigMd5());
boolean changedConfigAndNewGeneration = changedConfig && ConfigUtils.isGenerationNewer(generation, getRequestGeneration());
@@ -79,6 +82,7 @@ public class JRTServerConfigRequestV3 implements JRTServerConfigRequest {
addCommonReturnValues(jsonGenerator);
setResponseField(jsonGenerator, SlimeResponseData.RESPONSE_CONFIG_MD5, configMd5);
setResponseField(jsonGenerator, SlimeResponseData.RESPONSE_CONFIG_GENERATION, generation);
+ setResponseField(jsonGenerator, SlimeResponseData.RESPONSE_INTERNAL_REDEPLOY, internalRedeploy);
setResponseField(jsonGenerator, SlimeResponseData.RESPONSE_APPLY_ON_RESTART, applyOnRestart);
jsonGenerator.writeObjectFieldStart(SlimeResponseData.RESPONSE_COMPRESSION_INFO);
if (responsePayload == null) {
@@ -111,6 +115,9 @@ public class JRTServerConfigRequestV3 implements JRTServerConfigRequest {
}
@Override
+ public boolean isInternalRedeploy() { return internalRedeploy; }
+
+ @Override
public boolean applyOnRestart() { return applyOnRestart; }
public static JRTServerConfigRequestV3 createFromRequest(Request req) {
diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeConfigResponse.java b/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeConfigResponse.java
index 1fec7e17d06..8bdd336fd5c 100644
--- a/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeConfigResponse.java
+++ b/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeConfigResponse.java
@@ -17,24 +17,28 @@ public class SlimeConfigResponse implements ConfigResponse {
private final Utf8Array payload;
private final CompressionInfo compressionInfo;
private final long generation;
+ private final boolean internalRedeploy;
private final boolean applyOnRestart;
private final String configMd5;
public static SlimeConfigResponse fromConfigPayload(ConfigPayload payload, long generation,
- boolean applyOnRestart, String configMd5) {
+ boolean internalRedeploy, boolean applyOnRestart,
+ String configMd5) {
Utf8Array data = payload.toUtf8Array(true);
- return new SlimeConfigResponse(data, generation, applyOnRestart,
+ return new SlimeConfigResponse(data, generation, internalRedeploy, applyOnRestart,
configMd5,
CompressionInfo.create(CompressionType.UNCOMPRESSED, data.getByteLength()));
}
public SlimeConfigResponse(Utf8Array payload,
long generation,
+ boolean internalRedeploy,
boolean applyOnRestart,
String configMd5,
CompressionInfo compressionInfo) {
this.payload = payload;
this.generation = generation;
+ this.internalRedeploy = internalRedeploy;
this.applyOnRestart = applyOnRestart;
this.configMd5 = configMd5;
this.compressionInfo = compressionInfo;
@@ -50,6 +54,13 @@ public class SlimeConfigResponse implements ConfigResponse {
return generation;
}
+ /**
+ * Returns whether this application instance was produced by an internal redeployment,
+ * not an application package change
+ */
+ @Override
+ public boolean isInternalRedeploy() { return internalRedeploy; }
+
@Override
public boolean applyOnRestart() { return applyOnRestart; }
diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeResponseData.java b/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeResponseData.java
index cc98587456c..1c9afa550d4 100644
--- a/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeResponseData.java
+++ b/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeResponseData.java
@@ -23,6 +23,7 @@ class SlimeResponseData {
static final String RESPONSE_TRACE = "trace";
static final String RESPONSE_CONFIG_MD5 = "configMD5";
static final String RESPONSE_CONFIG_GENERATION = "generation";
+ static final String RESPONSE_INTERNAL_REDEPLOY = "internalRedeploy";
static final String RESPONSE_APPLY_ON_RESTART = "applyOnRestart";
static final String RESPONSE_COMPRESSION_INFO = "compressionInfo";
@@ -67,6 +68,11 @@ class SlimeResponseData {
return CompressionInfo.fromSlime(getResponseField(RESPONSE_COMPRESSION_INFO));
}
+ boolean getResponseInternalRedeployment() {
+ Inspector inspector = getResponseField(RESPONSE_INTERNAL_REDEPLOY);
+ return inspector.valid() && inspector.asBool();
+ }
+
boolean getResponseApplyOnRestart() {
Inspector inspector = getResponseField(RESPONSE_APPLY_ON_RESTART);
return inspector.valid() && inspector.asBool();
diff --git a/config/src/test/java/com/yahoo/config/subscription/ConfigApiTest.java b/config/src/test/java/com/yahoo/config/subscription/ConfigApiTest.java
index af2df2bcae7..c0080091db6 100755
--- a/config/src/test/java/com/yahoo/config/subscription/ConfigApiTest.java
+++ b/config/src/test/java/com/yahoo/config/subscription/ConfigApiTest.java
@@ -26,10 +26,10 @@ public class ConfigApiTest {
subscriber.nextConfig();
assertNotNull(h.getConfig());
assertEquals(AppConfig.CONFIG_DEF_NAME, ConfigInstance.getDefName(h.getConfig().getClass()));
- assertTrue(h.isChanged());
+ assertThat(h.isChanged(), is(true));
assertTrue(h.toString().startsWith("Handle changed: true\nSub:\n"));
subscriber.close();
- assertEquals(ConfigSubscriber.State.CLOSED, subscriber.state());
+ assertThat(subscriber.state(), is(ConfigSubscriber.State.CLOSED));
}
/**
diff --git a/config/src/test/java/com/yahoo/config/subscription/impl/JRTConfigRequesterTest.java b/config/src/test/java/com/yahoo/config/subscription/impl/JRTConfigRequesterTest.java
index 4211345dff7..07ff27a0154 100644
--- a/config/src/test/java/com/yahoo/config/subscription/impl/JRTConfigRequesterTest.java
+++ b/config/src/test/java/com/yahoo/config/subscription/impl/JRTConfigRequesterTest.java
@@ -184,7 +184,7 @@ public class JRTConfigRequesterTest {
ConfigSubscriber subscriber = new ConfigSubscriber();
final TimingValues timingValues = getTestTimingValues();
JRTConfigSubscription<SimpletypesConfig> sub = createSubscription(subscriber, timingValues);
- sub.setConfig(1L, false, config());
+ sub.setConfig(1L, false, false, config());
final MockConnection connection = new MockConnection(new ErrorResponseHandler());
JRTConfigRequester requester = new JRTConfigRequester(connection, timingValues);
@@ -212,7 +212,7 @@ public class JRTConfigRequesterTest {
ConfigSubscriber subscriber = new ConfigSubscriber();
final TimingValues timingValues = getTestTimingValues();
JRTConfigSubscription<SimpletypesConfig> sub = createSubscription(subscriber, timingValues);
- sub.setConfig(1L, false, config());
+ sub.setConfig(1L, false, false, config());
final MockConnection connection = new MockConnection(new ErrorResponseHandler(com.yahoo.jrt.ErrorCode.TIMEOUT));
JRTConfigRequester requester = new JRTConfigRequester(connection, timingValues);
@@ -227,7 +227,7 @@ public class JRTConfigRequesterTest {
ConfigSubscriber subscriber = new ConfigSubscriber();
final TimingValues timingValues = getTestTimingValues();
JRTConfigSubscription<SimpletypesConfig> sub = createSubscription(subscriber, timingValues);
- sub.setConfig(1L, false, config());
+ sub.setConfig(1L, false, false, config());
final MockConnection connection = new MockConnection(new ErrorResponseHandler(ErrorCode.UNKNOWN_DEFINITION));
JRTConfigRequester requester = new JRTConfigRequester(connection, timingValues);
diff --git a/config/src/test/java/com/yahoo/vespa/config/RawConfigTest.java b/config/src/test/java/com/yahoo/vespa/config/RawConfigTest.java
index e1d11f82eea..9fd0b9ba1fa 100644
--- a/config/src/test/java/com/yahoo/vespa/config/RawConfigTest.java
+++ b/config/src/test/java/com/yahoo/vespa/config/RawConfigTest.java
@@ -61,14 +61,14 @@ public class RawConfigTest {
assertThat(config.hashCode(), is(not(new RawConfig(key, "a").hashCode()))); // different def md5
// different generation
- config = new RawConfig(key, defMd5, payload, configMd5, generation, false, defContent, Optional.empty());
- RawConfig config2 = new RawConfig(key, defMd5, payload, configMd5, 2L, false, defContent, Optional.empty());
+ config = new RawConfig(key, defMd5, payload, configMd5, generation, false, false, defContent, Optional.empty());
+ RawConfig config2 = new RawConfig(key, defMd5, payload, configMd5, 2L, false, false, defContent, Optional.empty());
assertThat(config, is(not(config2)));
assertThat(config.hashCode(), is(not(config2.hashCode())));
// different config md5 and with vespa version
final VespaVersion vespaVersion = VespaVersion.fromString("5.37.38");
- RawConfig config3 = new RawConfig(key, defMd5, payload, "9999", generation, false, defContent, Optional.of(vespaVersion));
+ RawConfig config3 = new RawConfig(key, defMd5, payload, "9999", generation, false, false, defContent, Optional.of(vespaVersion));
assertThat(config, is(not(config3)));
assertThat(config.hashCode(), is(not(config3.hashCode())));
// Check that vespa version is set correctly
@@ -82,19 +82,19 @@ public class RawConfigTest {
assertNotEquals(config, key);
// errors
- RawConfig errorConfig1 = new RawConfig(key, defMd5, payload, configMd5, generation, false, 1, defContent, Optional.empty());
+ RawConfig errorConfig1 = new RawConfig(key, defMd5, payload, configMd5, generation, false, false, 1, defContent, Optional.empty());
assertThat(errorConfig1, is(errorConfig1));
assertThat(config, is(not(errorConfig1)));
assertThat(config.hashCode(), is(not(errorConfig1.hashCode())));
assertThat(errorConfig1, is(errorConfig1));
- RawConfig errorConfig2 = new RawConfig(key, defMd5, payload, configMd5, generation, false, 2, defContent, Optional.empty());
+ RawConfig errorConfig2 = new RawConfig(key, defMd5, payload, configMd5, generation, false, false, 2, defContent, Optional.empty());
assertThat(errorConfig1, is(not(errorConfig2)));
assertThat(errorConfig1.hashCode(), is(not(errorConfig2.hashCode())));
}
@Test
public void payload() {
- RawConfig config = new RawConfig(key, defMd5, payload, configMd5, generation, false, defContent, Optional.empty());
+ RawConfig config = new RawConfig(key, defMd5, payload, configMd5, generation, false, false, defContent, Optional.empty());
assertThat(config.getPayload(), is(payload));
assertThat(config.getConfigMd5(), is(configMd5));
assertThat(config.getGeneration(), is(generation));
@@ -105,19 +105,19 @@ public class RawConfigTest {
public void require_correct_defmd5() {
final String defMd5ForEmptyDefContent = "d41d8cd98f00b204e9800998ecf8427e";
- RawConfig config = new RawConfig(key, null, payload, configMd5, generation, false, defContent, Optional.empty());
+ RawConfig config = new RawConfig(key, null, payload, configMd5, generation, false, false, defContent, Optional.empty());
assertThat(config.getDefMd5(), is(defMd5));
- config = new RawConfig(key, "", payload, configMd5, generation, false, defContent, Optional.empty());
+ config = new RawConfig(key, "", payload, configMd5, generation, false, false, defContent, Optional.empty());
assertThat(config.getDefMd5(), is(defMd5));
- config = new RawConfig(key, defMd5, payload, configMd5, generation, false, defContent, Optional.empty());
+ config = new RawConfig(key, defMd5, payload, configMd5, generation, false, false, defContent, Optional.empty());
assertThat(config.getDefMd5(), is(defMd5));
- config = new RawConfig(key, null, payload, configMd5, generation, false, null, Optional.empty());
+ config = new RawConfig(key, null, payload, configMd5, generation, false, false, null, Optional.empty());
assertNull(config.getDefMd5());
- config = new RawConfig(key, null, payload, configMd5, generation, false, List.of(""), Optional.empty());
+ config = new RawConfig(key, null, payload, configMd5, generation, false,false, List.of(""), Optional.empty());
assertThat(config.getDefMd5(), is(defMd5ForEmptyDefContent));
- config = new RawConfig(key, "", payload, configMd5, generation, false, null, Optional.empty());
+ config = new RawConfig(key, "", payload, configMd5, generation, false, false, null, Optional.empty());
assertThat(config.getDefMd5(), is(""));
- config = new RawConfig(key, "", payload, configMd5, generation, false, List.of(""), Optional.empty());
+ config = new RawConfig(key, "", payload, configMd5, generation, false, false, List.of(""), Optional.empty());
assertThat(config.getDefMd5(), is(defMd5ForEmptyDefContent));
}
diff --git a/config/src/test/java/com/yahoo/vespa/config/protocol/ConfigResponseTest.java b/config/src/test/java/com/yahoo/vespa/config/protocol/ConfigResponseTest.java
index a56c7ef2daa..98eda868bbf 100644
--- a/config/src/test/java/com/yahoo/vespa/config/protocol/ConfigResponseTest.java
+++ b/config/src/test/java/com/yahoo/vespa/config/protocol/ConfigResponseTest.java
@@ -24,7 +24,7 @@ public class ConfigResponseTest {
@Test
public void require_that_slime_response_is_initialized() throws IOException {
ConfigPayload configPayload = ConfigPayload.fromInstance(new SimpletypesConfig(new SimpletypesConfig.Builder()));
- ConfigResponse response = SlimeConfigResponse.fromConfigPayload(configPayload, 3, false, "mymd5");
+ ConfigResponse response = SlimeConfigResponse.fromConfigPayload(configPayload, 3, false, false, "mymd5");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
response.serialize(baos, CompressionType.UNCOMPRESSED);
String payload = baos.toString(StandardCharsets.UTF_8);
@@ -43,7 +43,7 @@ public class ConfigResponseTest {
ConfigPayload configPayload = ConfigPayload.fromInstance(new SimpletypesConfig(new SimpletypesConfig.Builder()));
Utf8Array data = configPayload.toUtf8Array(true);
Utf8Array bytes = new Utf8Array(new LZ4PayloadCompressor().compress(data.getBytes()));
- ConfigResponse response = new SlimeConfigResponse(bytes, 3, false, "mymd5", CompressionInfo.create(CompressionType.LZ4, data.getByteLength()));
+ ConfigResponse response = new SlimeConfigResponse(bytes, 3, false, false, "mymd5", CompressionInfo.create(CompressionType.LZ4, data.getByteLength()));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
response.serialize(baos, CompressionType.UNCOMPRESSED);
String payload = baos.toString(StandardCharsets.UTF_8);
diff --git a/config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestV3Test.java b/config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestV3Test.java
index 006a6fc6a0a..6fc55e60a54 100644
--- a/config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestV3Test.java
+++ b/config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestV3Test.java
@@ -28,7 +28,6 @@ import java.util.Collections;
import java.util.Optional;
import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
@@ -74,11 +73,12 @@ public class JRTConfigRequestV3Test {
@Test
public void emptypayload() {
ConfigPayload payload = ConfigPayload.empty();
- SlimeConfigResponse response = SlimeConfigResponse.fromConfigPayload(payload, 0, false, ConfigUtils.getMd5(payload));
- serverReq.addOkResponse(serverReq.payloadFromResponse(response), response.getGeneration(), false, response.getConfigMd5());
+ SlimeConfigResponse response = SlimeConfigResponse.fromConfigPayload(payload, 0, false, false, ConfigUtils.getMd5(payload));
+ serverReq.addOkResponse(serverReq.payloadFromResponse(response), response.getGeneration(), false, false, response.getConfigMd5());
assertTrue(clientReq.validateResponse());
assertTrue(clientReq.hasUpdatedGeneration());
- assertEquals("{}", clientReq.getNewPayload().withCompression(CompressionType.UNCOMPRESSED).getData().toString());
+ assertThat(clientReq.getNewPayload().withCompression(CompressionType.UNCOMPRESSED).getData().toString(), is("{}"));
+ assertFalse(clientReq.responseIsInternalRedeploy());
}
@Test
@@ -92,9 +92,11 @@ public class JRTConfigRequestV3Test {
@Test
public void next_request_when_error_is_correct() {
- serverReq.addOkResponse(createPayload(), 999999, false, "newmd5");
+ serverReq.addOkResponse(createPayload(), 999999, false, false, "newmd5");
serverReq.addErrorResponse(ErrorCode.OUTDATED_CONFIG, "error message");
+ System.out.println(serverReq);
JRTClientConfigRequest next = clientReq.nextRequest(6);
+ System.out.println(next);
// Should use config md5 and generation from the request, not the response
// when there are errors
assertThat(next.getRequestConfigMd5(), is(clientReq.getRequestConfigMd5()));
@@ -106,7 +108,7 @@ public class JRTConfigRequestV3Test {
Payload payload = createPayload("vale");
String md5 = ConfigUtils.getMd5(payload.getData());
long generation = 4L;
- serverReq.addOkResponse(payload, generation, false, md5);
+ serverReq.addOkResponse(payload, generation, false, false, md5);
assertTrue(clientReq.validateResponse());
assertThat(clientReq.getNewPayload().withCompression(CompressionType.UNCOMPRESSED).getData().toString(), is(payload.getData().toString()));
assertThat(clientReq.getNewGeneration(), is(4L));
@@ -132,7 +134,7 @@ public class JRTConfigRequestV3Test {
@Test
public void generation_only_is_updated() {
Payload payload = createPayload();
- serverReq.addOkResponse(payload, 4L, false, ConfigUtils.getMd5(payload.getData()));
+ serverReq.addOkResponse(payload, 4L, false, false, ConfigUtils.getMd5(payload.getData()));
boolean value = clientReq.validateResponse();
assertTrue(clientReq.errorMessage(), value);
assertFalse(clientReq.hasUpdatedConfig());
@@ -142,7 +144,7 @@ public class JRTConfigRequestV3Test {
@Test
public void nothing_is_updated() {
Payload payload = createPayload();
- serverReq.addOkResponse(payload, currentGeneration, false, configMd5);
+ serverReq.addOkResponse(payload, currentGeneration, false, false, configMd5);
assertTrue(clientReq.validateResponse());
assertFalse(clientReq.hasUpdatedConfig());
assertFalse(clientReq.hasUpdatedGeneration());
@@ -153,7 +155,7 @@ public class JRTConfigRequestV3Test {
Payload payload = Payload.from(ConfigPayload.empty());
clientReq = createReq(payload);
serverReq = createReq(clientReq.getRequest());
- serverReq.addOkResponse(payload, currentGeneration, false, ConfigUtils.getMd5(payload.getData()));
+ serverReq.addOkResponse(payload, currentGeneration, false, false, ConfigUtils.getMd5(payload.getData()));
boolean val = clientReq.validateResponse();
assertTrue(clientReq.errorMessage(), val);
assertFalse(clientReq.hasUpdatedConfig());
@@ -190,7 +192,7 @@ public class JRTConfigRequestV3Test {
@Override
public void createResponse() {
JRTServerConfigRequest serverRequest = createReq(request);
- serverRequest.addOkResponse(createPayload(), currentGeneration, false, configMd5);
+ serverRequest.addOkResponse(createPayload(), currentGeneration, false, false, configMd5);
}
});
diff --git a/config/src/tests/configagent/configagent.cpp b/config/src/tests/configagent/configagent.cpp
index d6766cce822..7cc0abee0bc 100644
--- a/config/src/tests/configagent/configagent.cpp
+++ b/config/src/tests/configagent/configagent.cpp
@@ -36,7 +36,7 @@ public:
_value(value),
_fillCalled(false),
_valid(valid),
- _state(md5, timestamp, false),
+ _state(md5, timestamp, false, false),
_errorMessage(errorMsg),
_errorCode(errorC0de),
_isError(iserror)
@@ -141,6 +141,7 @@ TEST("require that agent returns correct values") {
ConfigState cs;
ASSERT_EQUAL(cs.md5, handler.getConfigState().md5);
ASSERT_EQUAL(cs.generation, handler.getConfigState().generation);
+ ASSERT_EQUAL(cs.internalRedeploy, handler.getConfigState().internalRedeploy);
ASSERT_EQUAL(cs.applyOnRestart, handler.getConfigState().applyOnRestart);
}
diff --git a/config/src/tests/frt/frt.cpp b/config/src/tests/frt/frt.cpp
index 0d70605fa62..60973aea2bf 100644
--- a/config/src/tests/frt/frt.cpp
+++ b/config/src/tests/frt/frt.cpp
@@ -276,10 +276,10 @@ TEST("require that v3 request is correctly initialized") {
traceIn.trace(2, "Hei");
FRTConfigRequestV3 v3req(&conn, key, md5, currentGeneration, hostName,
timeout, traceIn, VespaVersion::fromString("1.2.3"), CompressionType::LZ4);
- ASSERT_TRUE(v3req.verifyState(ConfigState(md5, 3, false)));
- ASSERT_FALSE(v3req.verifyState(ConfigState(md5, 2, false)));
- ASSERT_FALSE(v3req.verifyState(ConfigState("xxx", 3, false)));
- ASSERT_FALSE(v3req.verifyState(ConfigState("xxx", 2, false)));
+ ASSERT_TRUE(v3req.verifyState(ConfigState(md5, 3, false, false)));
+ ASSERT_FALSE(v3req.verifyState(ConfigState(md5, 2, false, false)));
+ ASSERT_FALSE(v3req.verifyState(ConfigState("xxx", 3, false, false)));
+ ASSERT_FALSE(v3req.verifyState(ConfigState("xxx", 2, false, false)));
ConfigDefinition origDef(MyConfig::CONFIG_DEF_SCHEMA);
diff --git a/config/src/vespa/config/common/configstate.h b/config/src/vespa/config/common/configstate.h
index 2dbea3cc30f..155c182271b 100644
--- a/config/src/vespa/config/common/configstate.h
+++ b/config/src/vespa/config/common/configstate.h
@@ -15,16 +15,19 @@ public:
ConfigState()
: md5(""),
generation(0),
+ internalRedeploy(false),
applyOnRestart(false)
{ }
- ConfigState(const vespalib::string & md5sum, int64_t gen, bool _applyOnRestart)
+ ConfigState(const vespalib::string & md5sum, int64_t gen, bool _internalRedeploy, bool _applyOnRestart)
: md5(md5sum),
generation(gen),
+ internalRedeploy(_internalRedeploy),
applyOnRestart(_applyOnRestart)
{ }
vespalib::string md5;
int64_t generation;
+ bool internalRedeploy;
bool applyOnRestart;
bool isNewerGenerationThan(const ConfigState & other) const {
diff --git a/config/src/vespa/config/frt/protocol.cpp b/config/src/vespa/config/frt/protocol.cpp
index 269c3477ba8..5019cce23c5 100644
--- a/config/src/vespa/config/frt/protocol.cpp
+++ b/config/src/vespa/config/frt/protocol.cpp
@@ -40,6 +40,7 @@ const Memory RESPONSE_CONFIG_MD5 = "configMD5";
const Memory RESPONSE_CONFIG_GENERATION = "generation";
const Memory RESPONSE_PAYLOAD = "payload";
const Memory RESPONSE_TRACE = "trace";
+const Memory RESPONSE_INTERNAL_REDEPLOY = "internalRedeploy";
const Memory RESPONSE_APPLY_ON_RESTART = "applyOnRestart";
const Inspector &
diff --git a/config/src/vespa/config/frt/protocol.h b/config/src/vespa/config/frt/protocol.h
index 0ec16952701..a7465ef979d 100644
--- a/config/src/vespa/config/frt/protocol.h
+++ b/config/src/vespa/config/frt/protocol.h
@@ -52,6 +52,7 @@ extern const vespalib::Memory RESPONSE_CONFIG_MD5;
extern const vespalib::Memory RESPONSE_CONFIG_GENERATION;
extern const vespalib::Memory RESPONSE_PAYLOAD;
extern const vespalib::Memory RESPONSE_TRACE;
+extern const vespalib::Memory RESPONSE_INTERNAL_REDEPLOY;
extern const vespalib::Memory RESPONSE_APPLY_ON_RESTART;
const vespalib::slime::Inspector & extractPayload(const vespalib::Slime & data);
diff --git a/config/src/vespa/config/frt/slimeconfigresponse.cpp b/config/src/vespa/config/frt/slimeconfigresponse.cpp
index af224008d01..f778fe574f1 100644
--- a/config/src/vespa/config/frt/slimeconfigresponse.cpp
+++ b/config/src/vespa/config/frt/slimeconfigresponse.cpp
@@ -68,6 +68,7 @@ SlimeConfigResponse::readState() const
const Slime & data(*_data);
return ConfigState(data.get()[RESPONSE_CONFIG_MD5].asString().make_string(),
data.get()[RESPONSE_CONFIG_GENERATION].asLong(),
+ data.get()[RESPONSE_INTERNAL_REDEPLOY].asBool(),
data.get()[RESPONSE_APPLY_ON_RESTART].asBool());
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelController.java b/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelController.java
index 0bddd8d0637..933a8d86230 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelController.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelController.java
@@ -46,7 +46,7 @@ public class SuperModelController {
ConfigKey<?> configKey = request.getConfigKey();
validateConfigDefinition(request.getConfigKey(), request.getDefContent());
ConfigPayload payload = model.getConfig(configKey);
- return responseFactory.createResponse(payload, generation, false);
+ return responseFactory.createResponse(payload, generation, false, false);
}
private void validateConfigDefinition(ConfigKey<?> configKey, DefContent defContent) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java
index 55ef05650af..156b4be392e 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/Application.java
@@ -44,18 +44,20 @@ public class Application implements ModelResult {
/** The config generation for this application. */
private final long applicationGeneration;
+ private final boolean internalRedeploy;
private final Version vespaVersion;
private final Model model;
private final ServerCache cache;
private final MetricUpdater metricUpdater;
private final ApplicationId app;
- public Application(Model model, ServerCache cache, long applicationGeneration,
+ public Application(Model model, ServerCache cache, long applicationGeneration, boolean internalRedeploy,
Version vespaVersion, MetricUpdater metricUpdater, ApplicationId app) {
Objects.requireNonNull(model, "The model cannot be null");
this.model = model;
this.cache = cache;
this.applicationGeneration = applicationGeneration;
+ this.internalRedeploy = internalRedeploy;
this.vespaVersion = vespaVersion;
this.metricUpdater = metricUpdater;
this.app = app;
@@ -169,6 +171,7 @@ public class Application implements ModelResult {
ConfigResponse configResponse = responseFactory.createResponse(payload,
applicationGeneration,
+ internalRedeploy,
applyOnRestart);
metricUpdater.incrementProcTime(System.currentTimeMillis() - start);
if (useCache(req)) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java
index 9e104461b33..a3a8bba567a 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java
@@ -110,6 +110,7 @@ public class ActivatedModelsBuilder extends ModelsBuilder<Application> {
return new Application(modelFactory.createModel(modelContext),
serverCache,
applicationGeneration,
+ applicationPackage.getMetaData().isInternalRedeploy(),
modelFactory.version(),
applicationMetricUpdater,
applicationId);
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/ConfigResponseFactory.java b/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/ConfigResponseFactory.java
index 8003b2a2be9..00a0e6f8f2e 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/ConfigResponseFactory.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/ConfigResponseFactory.java
@@ -27,12 +27,14 @@ public interface ConfigResponseFactory {
/**
* Creates a {@link ConfigResponse} for a given payload and generation.
*
- * @param payload the {@link ConfigPayload} to put in the response
- * @param generation the payload generation
+ * @param payload the {@link ConfigPayload} to put in the response
+ * @param generation the payload generation
+ * @param internalRedeploy whether this config generation was produced by an internal redeployment
+ * not a change to the application package
* @param applyOnRestart true if this config change should only be applied on restart,
* false if it should be applied immediately
* @return a {@link ConfigResponse} that can be sent to the client
*/
- ConfigResponse createResponse(ConfigPayload payload, long generation, boolean applyOnRestart);
+ ConfigResponse createResponse(ConfigPayload payload, long generation, boolean internalRedeploy, boolean applyOnRestart);
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/GetConfigProcessor.java b/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/GetConfigProcessor.java
index 010640b967f..5d637c0e0bd 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/GetConfigProcessor.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/GetConfigProcessor.java
@@ -125,7 +125,7 @@ class GetConfigProcessor implements Runnable {
// config == null is not an error, but indicates that the config will be returned later.
if ((config != null) && (!config.hasEqualConfig(request) || config.hasNewerGeneration(request) || forceResponse)) {
// debugLog(trace, "config response before encoding:" + config.toString());
- request.addOkResponse(request.payloadFromResponse(config), config.getGeneration(), config.applyOnRestart(), config.getConfigMd5());
+ request.addOkResponse(request.payloadFromResponse(config), config.getGeneration(), config.isInternalRedeploy(), config.applyOnRestart(), config.getConfigMd5());
if (logDebug(trace)) {
debugLog(trace, "return response: " + request.getShortDescription());
}
@@ -166,8 +166,8 @@ class GetConfigProcessor implements Runnable {
log.log(Level.FINE, () -> "Returning empty sentinel config for request from " + request.getClientHostName());
ConfigPayload emptyPayload = ConfigPayload.empty();
String configMd5 = ConfigUtils.getMd5(emptyPayload);
- ConfigResponse config = SlimeConfigResponse.fromConfigPayload(emptyPayload, 0, false, configMd5);
- request.addOkResponse(request.payloadFromResponse(config), config.getGeneration(), false, config.getConfigMd5());
+ ConfigResponse config = SlimeConfigResponse.fromConfigPayload(emptyPayload, 0, false, false, configMd5);
+ request.addOkResponse(request.payloadFromResponse(config), config.getGeneration(), false, false, config.getConfigMd5());
respond(request);
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/LZ4ConfigResponseFactory.java b/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/LZ4ConfigResponseFactory.java
index 619e6c0a2a2..a818eaeb8f5 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/LZ4ConfigResponseFactory.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/LZ4ConfigResponseFactory.java
@@ -22,12 +22,13 @@ public class LZ4ConfigResponseFactory implements ConfigResponseFactory {
@Override
public ConfigResponse createResponse(ConfigPayload payload,
long generation,
+ boolean internalRedeploy,
boolean applyOnRestart) {
Utf8Array rawPayload = payload.toUtf8Array(true);
String configMd5 = ConfigUtils.getMd5(rawPayload);
CompressionInfo info = CompressionInfo.create(CompressionType.LZ4, rawPayload.getByteLength());
Utf8Array compressed = new Utf8Array(compressor.compress(rawPayload.getBytes()));
- return new SlimeConfigResponse(compressed, generation, applyOnRestart, configMd5, info);
+ return new SlimeConfigResponse(compressed, generation, internalRedeploy, applyOnRestart, configMd5, info);
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/UncompressedConfigResponseFactory.java b/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/UncompressedConfigResponseFactory.java
index 8d852ebd8c9..e3f3f1c1395 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/UncompressedConfigResponseFactory.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/UncompressedConfigResponseFactory.java
@@ -19,11 +19,12 @@ public class UncompressedConfigResponseFactory implements ConfigResponseFactory
@Override
public ConfigResponse createResponse(ConfigPayload payload,
long generation,
+ boolean internalRedeploy,
boolean applyOnRestart) {
Utf8Array rawPayload = payload.toUtf8Array(true);
String configMd5 = ConfigUtils.getMd5(rawPayload);
CompressionInfo info = CompressionInfo.create(CompressionType.UNCOMPRESSED, rawPayload.getByteLength());
- return new SlimeConfigResponse(rawPayload, generation, applyOnRestart, configMd5, info);
+ return new SlimeConfigResponse(rawPayload, generation, internalRedeploy, applyOnRestart, configMd5, info);
}
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ServerCacheTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ServerCacheTest.java
index 35449238f78..fa69df9f628 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/ServerCacheTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ServerCacheTest.java
@@ -48,9 +48,9 @@ public class ServerCacheTest {
cache = new ServerCache(new TestConfigDefinitionRepo(), userConfigDefinitionRepo);
- cache.put(fooBarCacheKey, SlimeConfigResponse.fromConfigPayload(ConfigPayload.empty(), 2, false, configMd5), configMd5);
- cache.put(bazQuuxCacheKey, SlimeConfigResponse.fromConfigPayload(ConfigPayload.empty(), 2, false, configMd5), configMd5);
- cache.put(fooBarCacheKeyDifferentMd5, SlimeConfigResponse.fromConfigPayload(ConfigPayload.empty(), 2, false, configMd5_2), configMd5_2);
+ cache.put(fooBarCacheKey, SlimeConfigResponse.fromConfigPayload(ConfigPayload.empty(), 2, false, false, configMd5), configMd5);
+ cache.put(bazQuuxCacheKey, SlimeConfigResponse.fromConfigPayload(ConfigPayload.empty(), 2, false, false, configMd5), configMd5);
+ cache.put(fooBarCacheKeyDifferentMd5, SlimeConfigResponse.fromConfigPayload(ConfigPayload.empty(), 2, false, false, configMd5_2), configMd5_2);
}
@Test
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelRequestHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelRequestHandlerTest.java
index e33b52e5fd4..26ef180cf8d 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelRequestHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelRequestHandlerTest.java
@@ -125,7 +125,7 @@ public class SuperModelRequestHandlerTest {
private static class TestApplication extends Application {
TestApplication(VespaModel vespaModel, ServerCache cache, long appGeneration, ApplicationId app) {
- super(vespaModel, cache, appGeneration, new Version(1, 2, 3), MetricUpdater.createTestUpdater(), app);
+ super(vespaModel, cache, appGeneration, false, new Version(1, 2, 3), MetricUpdater.createTestUpdater(), app);
}
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationMapperTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationMapperTest.java
index 9ef63b768a9..3270bb5cd76 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationMapperTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationMapperTest.java
@@ -70,7 +70,7 @@ public class ApplicationMapperTest {
}
private Application createApplication(Version version) {
- return new Application(new ModelStub(), null, 0, version, MetricUpdater.createTestUpdater(), ApplicationId.defaultId());
+ return new Application(new ModelStub(), null, 0, false, version, MetricUpdater.createTestUpdater(), ApplicationId.defaultId());
}
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationSetTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationSetTest.java
index b37c5defbc3..a5ec2583595 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationSetTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationSetTest.java
@@ -58,6 +58,6 @@ public class ApplicationSetTest {
}
private Application createApplication(Version version) {
- return new Application(new ModelStub(), null, 0, version, MetricUpdater.createTestUpdater(), ApplicationId.defaultId());
+ return new Application(new ModelStub(), null, 0, false, version, MetricUpdater.createTestUpdater(), ApplicationId.defaultId());
}
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationTest.java
index acd0acc3792..1e70304ef42 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ApplicationTest.java
@@ -57,7 +57,7 @@ public class ApplicationTest {
ApplicationName.from("foobar"), InstanceName.defaultName());
ServerCache cache = new ServerCache();
Version vespaVersion = new Version(1, 2, 3);
- Application app = new Application(new ModelStub(), cache, 1337L, vespaVersion, MetricUpdater.createTestUpdater(), appId);
+ Application app = new Application(new ModelStub(), cache, 1337L, false, vespaVersion, MetricUpdater.createTestUpdater(), appId);
assertThat(app.getApplicationGeneration(), is(1337L));
assertNotNull(app.getModel());
assertThat(app.getCache(), is(cache));
@@ -76,7 +76,7 @@ public class ApplicationTest {
ServerCache cache = createCacheAndAddContent();
VespaModel model = new VespaModel(FilesApplicationPackage.fromFile(testApp));
ApplicationId applicationId = new ApplicationId.Builder().tenant("foo").applicationName("foo").build();
- handler = new Application(model, cache, 1L, new Version(1, 2, 3),
+ handler = new Application(model, cache, 1L, false, new Version(1, 2, 3),
new MetricUpdater(Metrics.createTestMetrics(), Metrics.createDimensions(applicationId)), applicationId);
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ConfigConvergenceCheckerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ConfigConvergenceCheckerTest.java
index 2fbc14dda50..8a3a3b6e0ca 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/ConfigConvergenceCheckerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/ConfigConvergenceCheckerTest.java
@@ -64,6 +64,7 @@ public class ConfigConvergenceCheckerTest {
application = new Application(mockModel,
new ServerCache(),
3,
+ false,
new Version(0, 0, 0),
MetricUpdater.createTestUpdater(), appId);
checker = new ConfigConvergenceChecker();
@@ -136,6 +137,7 @@ public class ConfigConvergenceCheckerTest {
MockModel.createContainerHost(service2.getHost(), service2.getPort()))
);
Application application = new Application(model, new ServerCache(), 4,
+ false,
new Version(0, 0, 0),
MetricUpdater.createTestUpdater(), appId);
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/FileDistributionStatusTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/FileDistributionStatusTest.java
index b650e8eb291..e425943ef59 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/FileDistributionStatusTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/FileDistributionStatusTest.java
@@ -164,6 +164,7 @@ public class FileDistributionStatusTest {
return new Application(mockModel,
new ServerCache(),
3,
+ false,
new Version(0, 0, 0),
MetricUpdater.createTestUpdater(),
appId);
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/application/TenantApplicationsTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/application/TenantApplicationsTest.java
index 947308962d4..aa3f240b12e 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/application/TenantApplicationsTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/application/TenantApplicationsTest.java
@@ -181,6 +181,7 @@ public class TenantApplicationsTest {
applications.activateApplication(ApplicationSet.from(new Application(model,
new ServerCache(),
1,
+ false,
vespaVersion,
MetricUpdater.createTestUpdater(),
applicationId)),
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpConfigResponseTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpConfigResponseTest.java
index ef0a5f6113d..336a8c623b8 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpConfigResponseTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/HttpConfigResponseTest.java
@@ -20,7 +20,7 @@ public class HttpConfigResponseTest {
public void require_that_response_is_created_from_config() throws IOException {
final long generation = 1L;
ConfigPayload payload = ConfigPayload.fromInstance(new SimpletypesConfig(new SimpletypesConfig.Builder()));
- ConfigResponse configResponse = SlimeConfigResponse.fromConfigPayload(payload, generation, false, "mymd5");
+ ConfigResponse configResponse = SlimeConfigResponse.fromConfigPayload(payload, generation, false, false, "mymd5");
HttpConfigResponse response = HttpConfigResponse.createFromConfig(configResponse);
assertThat(SessionHandlerTest.getRenderedString(response), is("{\"boolval\":false,\"doubleval\":0.0,\"enumval\":\"VAL1\",\"intval\":0,\"longval\":0,\"stringval\":\"s\"}"));
}
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/DeploymentMetricsRetrieverTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/DeploymentMetricsRetrieverTest.java
index b5cdfa8eda2..3a68e0f4c65 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/DeploymentMetricsRetrieverTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/DeploymentMetricsRetrieverTest.java
@@ -34,8 +34,8 @@ public class DeploymentMetricsRetrieverTest {
public void getMetrics() {
MockModel mockModel = new MockModel(mockHosts());
MockDeploymentMetricsRetriever mockMetricsRetriever = new MockDeploymentMetricsRetriever();
- Application application = new Application(mockModel, null, 0,
- null, null, ApplicationId.fromSerializedForm("tenant:app:instance"));
+ Application application = new Application(mockModel, null, 0, false,
+ null, null, ApplicationId.fromSerializedForm("tenant:app:instance"));
DeploymentMetricsRetriever clusterMetricsRetriever = new DeploymentMetricsRetriever(mockMetricsRetriever);
clusterMetricsRetriever.getMetrics(application);
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/ProtonMetricsRetrieverTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/ProtonMetricsRetrieverTest.java
index 7fab01faf3d..bbf9bd0bcb7 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/ProtonMetricsRetrieverTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/ProtonMetricsRetrieverTest.java
@@ -29,8 +29,8 @@ public class ProtonMetricsRetrieverTest {
public void getMetrics() {
ProtonMetricsRetrieverTest.MockModel mockModel = new MockModel(mockHosts());
ProtonMetricsRetrieverTest.MockProtonMetricsRetriever mockMetricsRetriever = new MockProtonMetricsRetriever();
- Application application = new Application(mockModel, null, 0,
- null, null, ApplicationId.fromSerializedForm("tenant:app:instance"));
+ Application application = new Application(mockModel, null, 0, false,
+ null, null, ApplicationId.fromSerializedForm("tenant:app:instance"));
ProtonMetricsRetriever clusterMetricsRetriever = new ProtonMetricsRetriever(mockMetricsRetriever);
clusterMetricsRetriever.getMetrics(application);
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/ConfigResponseFactoryTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/ConfigResponseFactoryTest.java
index 5d8b8c92472..c932627ce6a 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/ConfigResponseFactoryTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/ConfigResponseFactoryTest.java
@@ -16,7 +16,7 @@ public class ConfigResponseFactoryTest {
@Test
public void testUncompressedFactory() {
UncompressedConfigResponseFactory responseFactory = new UncompressedConfigResponseFactory();
- ConfigResponse response = responseFactory.createResponse(ConfigPayload.empty(), 3, false);
+ ConfigResponse response = responseFactory.createResponse(ConfigPayload.empty(), 3, false, false);
assertEquals(CompressionType.UNCOMPRESSED, response.getCompressionInfo().getCompressionType());
assertEquals(3L,response.getGeneration());
assertEquals(2, response.getPayload().getByteLength());
@@ -25,7 +25,7 @@ public class ConfigResponseFactoryTest {
@Test
public void testLZ4CompressedFactory() {
LZ4ConfigResponseFactory responseFactory = new LZ4ConfigResponseFactory();
- ConfigResponse response = responseFactory.createResponse(ConfigPayload.empty(), 3, false);
+ ConfigResponse response = responseFactory.createResponse(ConfigPayload.empty(), 3, false, false);
assertEquals(CompressionType.LZ4, response.getCompressionInfo().getCompressionType());
assertEquals(3L, response.getGeneration());
assertEquals(3, response.getPayload().getByteLength());
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/RpcServerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/RpcServerTest.java
index 735eae2700f..704b00c4e0b 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/RpcServerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/RpcServerTest.java
@@ -131,6 +131,7 @@ public class RpcServerTest {
Application app = new Application(new VespaModel(MockApplicationPackage.createEmpty()),
new ServerCache(),
2L,
+ false,
new Version(1, 2, 3),
MetricUpdater.createTestUpdater(),
applicationId);
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRepositoryTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRepositoryTest.java
index 4900c50f1d7..d9d6fb01086 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRepositoryTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRepositoryTest.java
@@ -92,6 +92,7 @@ public class TenantRepositoryTest {
applicationRepo.activateApplication(ApplicationSet.from(new Application(new VespaModel(MockApplicationPackage.createEmpty()),
new ServerCache(),
4L,
+ false,
new Version(1, 2, 3),
MetricUpdater.createTestUpdater(),
id)),
diff --git a/container-core/src/main/java/com/yahoo/container/core/config/HandlersConfigurerDi.java b/container-core/src/main/java/com/yahoo/container/core/config/HandlersConfigurerDi.java
index ac632f5acce..af163e88fee 100644
--- a/container-core/src/main/java/com/yahoo/container/core/config/HandlersConfigurerDi.java
+++ b/container-core/src/main/java/com/yahoo/container/core/config/HandlersConfigurerDi.java
@@ -74,7 +74,7 @@ public class HandlersConfigurerDi {
this.vespaContainer = vespaContainer;
container = new Container(subscriberFactory, configId, deconstructor, osgiWrapper);
- getNewComponentGraph(discInjector);
+ getNewComponentGraph(discInjector, false);
}
private static class ContainerAndDiOsgi extends OsgiImpl implements OsgiWrapper {
@@ -128,9 +128,10 @@ public class HandlersConfigurerDi {
/**
* Wait for new config to arrive and produce the new graph
*/
- public void getNewComponentGraph(Injector discInjector) {
+ public void getNewComponentGraph(Injector discInjector, boolean restartOnRedeploy) {
currentGraph = container.getNewComponentGraph(currentGraph,
- createFallbackInjector(vespaContainer, discInjector));
+ createFallbackInjector(vespaContainer, discInjector),
+ restartOnRedeploy);
}
private Injector createFallbackInjector(com.yahoo.container.Container vespaContainer, Injector discInjector) {
diff --git a/container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java b/container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java
index 42e54d3a78f..d98a865e1fb 100644
--- a/container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java
+++ b/container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java
@@ -117,7 +117,7 @@ public class HandlersConfigurerTestWrapper {
public void reloadConfig() {
configurer.reloadConfig(++lastGeneration);
- configurer.getNewComponentGraph(guiceInjector());
+ configurer.getNewComponentGraph(guiceInjector(), false);
}
public void shutdown() {
diff --git a/container-di/src/main/java/com/yahoo/container/di/CloudSubscriberFactory.java b/container-di/src/main/java/com/yahoo/container/di/CloudSubscriberFactory.java
index 75a660789e2..1133363be8e 100644
--- a/container-di/src/main/java/com/yahoo/container/di/CloudSubscriberFactory.java
+++ b/container-di/src/main/java/com/yahoo/container/di/CloudSubscriberFactory.java
@@ -30,9 +30,8 @@ public class CloudSubscriberFactory implements SubscriberFactory {
private static final Logger log = Logger.getLogger(CloudSubscriberFactory.class.getName());
private final ConfigSource configSource;
- private final Map<CloudSubscriber, Integer> activeSubscribers = new WeakHashMap<>();
-
private Optional<Long> testGeneration = Optional.empty();
+ private Map<CloudSubscriber, Integer> activeSubscribers = new WeakHashMap<>();
public CloudSubscriberFactory(ConfigSource configSource) {
this.configSource = configSource;
@@ -71,6 +70,9 @@ public class CloudSubscriberFactory implements SubscriberFactory {
// if waitNextGeneration has not yet been called, -1 should be returned
private long generation = -1L;
+ // True if this reconfiguration was caused by a system-internal redeploy, not an external application change
+ private boolean internalRedeploy = false;
+
private CloudSubscriber(Set<ConfigKey<ConfigInstance>> keys, ConfigSource configSource) {
this.subscriber = new ConfigSubscriber(configSource);
keys.forEach(k -> handles.put(k, subscriber.subscribe(k.getConfigClass(), k.getConfigId())));
@@ -86,6 +88,11 @@ public class CloudSubscriberFactory implements SubscriberFactory {
return generation;
}
+ @Override
+ public boolean internalRedeploy() {
+ return internalRedeploy;
+ }
+
//mapValues returns a view,, so we need to force evaluation of it here to prevent deferred evaluation.
@Override
public Map<ConfigKey<ConfigInstance>, ConfigInstance> config() {
@@ -121,6 +128,7 @@ public class CloudSubscriberFactory implements SubscriberFactory {
}
generation = subscriber.getGeneration();
+ internalRedeploy = subscriber.isInternalRedeploy();
return generation;
}
diff --git a/container-di/src/main/java/com/yahoo/container/di/ConfigRetriever.java b/container-di/src/main/java/com/yahoo/container/di/ConfigRetriever.java
index 44e38648230..f892fe410a8 100644
--- a/container-di/src/main/java/com/yahoo/container/di/ConfigRetriever.java
+++ b/container-di/src/main/java/com/yahoo/container/di/ConfigRetriever.java
@@ -46,10 +46,11 @@ public final class ConfigRetriever {
}
public ConfigSnapshot getConfigs(Set<ConfigKey<? extends ConfigInstance>> componentConfigKeys,
- long leastGeneration) {
+ long leastGeneration,
+ boolean restartOnRedeploy) {
// Loop until we get config.
while (true) {
- Optional<ConfigSnapshot> maybeSnapshot = getConfigsOnce(componentConfigKeys, leastGeneration);
+ Optional<ConfigSnapshot> maybeSnapshot = getConfigsOnce(componentConfigKeys, leastGeneration, restartOnRedeploy);
if (maybeSnapshot.isPresent()) {
var configSnapshot = maybeSnapshot.get();
resetComponentSubscriberIfBootstrap(configSnapshot);
@@ -58,8 +59,13 @@ public final class ConfigRetriever {
}
}
+ ConfigSnapshot getConfigs(Set<ConfigKey<? extends ConfigInstance>> componentConfigKeys, long leastGeneration) {
+ return getConfigs(componentConfigKeys, leastGeneration, false);
+ }
+
Optional<ConfigSnapshot> getConfigsOnce(Set<ConfigKey<? extends ConfigInstance>> componentConfigKeys,
- long leastGeneration) {
+ long leastGeneration,
+ boolean restartOnRedeploy) {
if (!Sets.intersection(componentConfigKeys, bootstrapKeys).isEmpty()) {
throw new IllegalArgumentException(
"Component config keys [" + componentConfigKeys + "] overlaps with bootstrap config keys [" + bootstrapKeys + "]");
@@ -70,16 +76,18 @@ public final class ConfigRetriever {
allKeys.addAll(bootstrapKeys);
setupComponentSubscriber(allKeys);
- return getConfigsOptional(leastGeneration);
+ return getConfigsOptional(leastGeneration, restartOnRedeploy);
}
- private Optional<ConfigSnapshot> getConfigsOptional(long leastGeneration) {
+ private Optional<ConfigSnapshot> getConfigsOptional(long leastGeneration, boolean restartOnRedeploy) {
long newestComponentGeneration = componentSubscriber.waitNextGeneration();
log.log(FINE, "getConfigsOptional: new component generation: " + newestComponentGeneration);
// leastGeneration is only used to ensure newer generation when the previous generation was invalidated due to an exception
if (newestComponentGeneration < leastGeneration) {
return Optional.empty();
+ } else if (restartOnRedeploy && !componentSubscriber.internalRedeploy()) { // Don't reconfig - wait for restart
+ return Optional.empty();
} else if (bootstrapSubscriber.generation() < newestComponentGeneration) {
long newestBootstrapGeneration = bootstrapSubscriber.waitNextGeneration();
log.log(FINE, "getConfigsOptional: new bootstrap generation: " + bootstrapSubscriber.generation());
diff --git a/container-di/src/main/java/com/yahoo/container/di/Container.java b/container-di/src/main/java/com/yahoo/container/di/Container.java
index 7855cd6b2f1..7fc2f2e55bc 100644
--- a/container-di/src/main/java/com/yahoo/container/di/Container.java
+++ b/container-di/src/main/java/com/yahoo/container/di/Container.java
@@ -72,10 +72,10 @@ public class Container {
});
}
- public ComponentGraph getNewComponentGraph(ComponentGraph oldGraph, Injector fallbackInjector) {
+ public ComponentGraph getNewComponentGraph(ComponentGraph oldGraph, Injector fallbackInjector, boolean restartOnRedeploy) {
try {
Collection<Bundle> obsoleteBundles = new HashSet<>();
- ComponentGraph newGraph = getConfigAndCreateGraph(oldGraph, fallbackInjector, obsoleteBundles);
+ ComponentGraph newGraph = getConfigAndCreateGraph(oldGraph, fallbackInjector, restartOnRedeploy, obsoleteBundles);
newGraph.reuseNodes(oldGraph);
constructComponents(newGraph);
deconstructObsoleteComponents(oldGraph, newGraph, obsoleteBundles);
@@ -88,11 +88,12 @@ public class Container {
private ComponentGraph getConfigAndCreateGraph(ComponentGraph graph,
Injector fallbackInjector,
+ boolean restartOnRedeploy,
Collection<Bundle> obsoleteBundles) // NOTE: Return value
{
ConfigSnapshot snapshot;
while (true) {
- snapshot = configurer.getConfigs(graph.configKeys(), leastGeneration);
+ snapshot = configurer.getConfigs(graph.configKeys(), leastGeneration, restartOnRedeploy);
log.log(FINE, String.format("createNewGraph:\n" + "graph.configKeys = %s\n" + "graph.generation = %s\n" + "snapshot = %s\n",
graph.configKeys(), graph.generation(), snapshot));
diff --git a/container-di/src/main/java/com/yahoo/container/di/config/Subscriber.java b/container-di/src/main/java/com/yahoo/container/di/config/Subscriber.java
index 9fd30f888b9..0feab7779ad 100644
--- a/container-di/src/main/java/com/yahoo/container/di/config/Subscriber.java
+++ b/container-di/src/main/java/com/yahoo/container/di/config/Subscriber.java
@@ -14,6 +14,7 @@ public interface Subscriber {
long waitNextGeneration();
long generation();
+ boolean internalRedeploy();
boolean configChanged();
Map<ConfigKey<ConfigInstance>, ConfigInstance> config();
diff --git a/container-di/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java b/container-di/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java
index 4751b9b74b7..e6b0309981a 100644
--- a/container-di/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java
+++ b/container-di/src/test/java/com/yahoo/container/di/ConfigRetrieverTest.java
@@ -51,7 +51,7 @@ public class ConfigRetrieverTest {
public void require_that_bootstrap_configs_come_first() {
writeConfigs();
ConfigRetriever retriever = createConfigRetriever();
- ConfigSnapshot bootstrapConfigs = retriever.getConfigs(Collections.emptySet(), 0);
+ ConfigSnapshot bootstrapConfigs = retriever.getConfigs(Collections.emptySet(), 0, false);
assertThat(bootstrapConfigs, Matchers.instanceOf(BootstrapConfigs.class));
}
@@ -61,7 +61,7 @@ public class ConfigRetrieverTest {
public void require_that_components_comes_after_bootstrap() {
writeConfigs();
ConfigRetriever retriever = createConfigRetriever();
- ConfigSnapshot bootstrapConfigs = retriever.getConfigs(Collections.emptySet(), 0);
+ ConfigSnapshot bootstrapConfigs = retriever.getConfigs(Collections.emptySet(), 0, false);
ConfigKey<? extends ConfigInstance> testConfigKey = new ConfigKey<>(TestConfig.class, dirConfigSource.configId());
ConfigSnapshot componentsConfigs = retriever.getConfigs(Collections.singleton(testConfigKey), 0);
@@ -73,6 +73,22 @@ public class ConfigRetrieverTest {
}
}
+ @Test
+ @SuppressWarnings("unused")
+ public void require_no_reconfig_when_restart_on_redeploy() {
+ // TODO
+ writeConfigs();
+ ConfigRetriever retriever = createConfigRetriever();
+ ConfigSnapshot bootstrapConfigs = retriever.getConfigs(Collections.emptySet(), 0, false);
+
+ ConfigKey<? extends ConfigInstance> testConfigKey = new ConfigKey<>(TestConfig.class, dirConfigSource.configId());
+ Optional<ConfigSnapshot> componentsConfigs = retriever.getConfigsOnce(Collections.singleton(testConfigKey), 0, true);
+
+ if (componentsConfigs.isPresent()) {
+ fail("Expected no configs");
+ }
+ }
+
@Rule
public ExpectedException expectedException = ExpectedException.none();
@@ -84,8 +100,8 @@ public class ConfigRetrieverTest {
writeConfigs();
ConfigRetriever retriever = createConfigRetriever();
ConfigKey<? extends ConfigInstance> testConfigKey = new ConfigKey<>(TestConfig.class, dirConfigSource.configId());
- ConfigSnapshot bootstrapConfigs = retriever.getConfigs(Collections.emptySet(), 0);
- ConfigSnapshot componentsConfigs = retriever.getConfigs(Collections.singleton(testConfigKey), 0);
+ ConfigSnapshot bootstrapConfigs = retriever.getConfigs(Collections.emptySet(), 0, false);
+ ConfigSnapshot componentsConfigs = retriever.getConfigs(Collections.singleton(testConfigKey), 0, false);
Set<ConfigKey<? extends ConfigInstance>> keys = new HashSet<>();
keys.add(testConfigKey);
keys.add(new ConfigKey<>(TestConfig.class, ""));
diff --git a/container-di/src/test/java/com/yahoo/container/di/ContainerTest.java b/container-di/src/test/java/com/yahoo/container/di/ContainerTest.java
index 37d84df2612..d39e8a36aed 100644
--- a/container-di/src/test/java/com/yahoo/container/di/ContainerTest.java
+++ b/container-di/src/test/java/com/yahoo/container/di/ContainerTest.java
@@ -402,11 +402,11 @@ public class ContainerTest extends ContainerTestBase {
}
ComponentGraph getNewComponentGraph(Container container, ComponentGraph oldGraph) {
- return container.getNewComponentGraph(oldGraph, Guice.createInjector());
+ return container.getNewComponentGraph(oldGraph, Guice.createInjector(), false);
}
ComponentGraph getNewComponentGraph(Container container) {
- return container.getNewComponentGraph(new ComponentGraph(), Guice.createInjector());
+ return container.getNewComponentGraph(new ComponentGraph(), Guice.createInjector(), false);
}
private ComponentTakingConfig createComponentTakingConfig(ComponentGraph componentGraph) {
diff --git a/container-di/src/test/java/com/yahoo/container/di/ContainerTestBase.java b/container-di/src/test/java/com/yahoo/container/di/ContainerTestBase.java
index 815865536f0..f1f3c4a2ae4 100644
--- a/container-di/src/test/java/com/yahoo/container/di/ContainerTestBase.java
+++ b/container-di/src/test/java/com/yahoo/container/di/ContainerTestBase.java
@@ -70,7 +70,7 @@ public class ContainerTestBase {
throw new UnsupportedOperationException("getBundle not supported.");
}
});
- componentGraph = container.getNewComponentGraph(componentGraph, Guice.createInjector());
+ componentGraph = container.getNewComponentGraph(componentGraph, Guice.createInjector(), false);
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java b/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java
index f32d7dfbb02..3158c06b0b1 100644
--- a/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java
+++ b/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java
@@ -261,12 +261,16 @@ public final class ConfiguredApplication implements Application {
private void startReconfigurerThread() {
reconfigurerThread = new Thread(() -> {
+ boolean restartOnDeploy = false;
while ( ! Thread.interrupted()) {
try {
ContainerBuilder builder = createBuilderWithGuiceBindings();
+ // Restart on deploy is sticky: Once it is set no future generation should be applied until restart
+ restartOnDeploy = restartOnDeploy || qrConfig.restartOnDeploy();
+
// Block until new config arrives, and it should be applied
- configurer.getNewComponentGraph(builder.guiceModules().activate());
+ configurer.getNewComponentGraph(builder.guiceModules().activate(), restartOnDeploy);
initializeAndActivateContainer(builder);
} catch (ConfigInterruptedException e) {
break;
diff --git a/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java b/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java
index 57c5e768cfb..a58aabfce17 100644
--- a/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java
+++ b/container-search-and-docproc/src/main/java/com/yahoo/container/handler/observability/ApplicationStatusHandler.java
@@ -86,7 +86,7 @@ public class ApplicationStatusHandler extends AbstractRequestHandler {
@Override
protected com.yahoo.jdisc.Response newResponse() {
com.yahoo.jdisc.Response response = new com.yahoo.jdisc.Response(com.yahoo.jdisc.Response.Status.OK);
- response.headers().add("Content-Type", List.of("application/json"));
+ response.headers().add("Content-Type", Arrays.asList(new String[]{"application/json"}));
return response;
}
}.connect(handler));
diff --git a/standalone-container/src/main/java/com/yahoo/container/standalone/StandaloneSubscriberFactory.java b/standalone-container/src/main/java/com/yahoo/container/standalone/StandaloneSubscriberFactory.java
index 7b23f190daa..d65b41c11c7 100644
--- a/standalone-container/src/main/java/com/yahoo/container/standalone/StandaloneSubscriberFactory.java
+++ b/standalone-container/src/main/java/com/yahoo/container/standalone/StandaloneSubscriberFactory.java
@@ -36,6 +36,9 @@ public class StandaloneSubscriberFactory implements SubscriberFactory {
}
@Override
+ public boolean internalRedeploy() { return false; }
+
+ @Override
public boolean configChanged() {
return generation == 0;
}