diff options
Diffstat (limited to 'config')
23 files changed, 244 insertions, 136 deletions
diff --git a/config/src/main/java/com/yahoo/config/subscription/ConfigInstanceUtil.java b/config/src/main/java/com/yahoo/config/subscription/ConfigInstanceUtil.java index 18d13aac12c..cce3ce0a0c5 100644 --- a/config/src/main/java/com/yahoo/config/subscription/ConfigInstanceUtil.java +++ b/config/src/main/java/com/yahoo/config/subscription/ConfigInstanceUtil.java @@ -14,7 +14,6 @@ import com.yahoo.vespa.config.*; /** * @author gjoranv - * @since 5.1.6 */ public class ConfigInstanceUtil { @@ -34,8 +33,8 @@ public class ConfigInstanceUtil { setter.invoke(destination, source); setter.setAccessible(false); } catch (Exception e) { - throw new ConfigurationRuntimeException("Could not set values on config builder." - + destination.getClass().getName(), e); + throw new ConfigurationRuntimeException("Could not set values on config builder." + + destination.getClass().getName(), e); } } 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 b0af69d2dbf..9e3a08eaf2c 100644 --- a/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java +++ b/config/src/main/java/com/yahoo/config/subscription/ConfigSubscriber.java @@ -31,8 +31,13 @@ public class ConfigSubscriber { private State state = State.OPEN; protected List<ConfigHandle<? extends ConfigInstance>> subscriptionHandles = new ArrayList<>(); private final ConfigSource source; + + /** 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; + /** * Reuse requesters for equal source sets, limit number if many subscriptions. */ @@ -219,7 +224,7 @@ public class ConfigSubscriber { * @param timeoutInMillis timeout to wait in milliseconds * @param requireChange if set, at least one config have to change * @return true, if a new config generation has been found for all configs (additionally requires - * that at lest one of them has changed if <code>requireChange</code> is true), false otherwise + * that at lest one of them has changed if <code>requireChange</code> is true), false otherwise */ private boolean acquireSnapshot(long timeoutInMillis, boolean requireChange) { if (state == State.CLOSED) return false; @@ -234,20 +239,22 @@ public class ConfigSubscriber { 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 { // Keep on polling the subscriptions until we have a new generation across the board, or it times out for (ConfigHandle<? extends ConfigInstance> h : subscriptionHandles) { ConfigSubscription<? extends ConfigInstance> subscription = h.subscription(); - if (!subscription.nextConfig(timeLeftMillis)) { + if ( ! subscription.nextConfig(timeLeftMillis)) { // This subscriber has no new state and we know it has exhausted all time return false; } throwIfExceptionSet(subscription); ConfigSubscription.ConfigState<? extends ConfigInstance> config = subscription.getConfigState(); if (currentGen == null) currentGen = config.getGeneration(); - if (!currentGen.equals(config.getGeneration())) allGenerationsTheSame = false; + if ( ! currentGen.equals(config.getGeneration())) allGenerationsTheSame = false; allGenerationsChanged = allGenerationsChanged && config.isGenerationChanged(); if (config.isConfigChanged()) anyConfigChanged = true; + internalRedeployOnly = internalRedeployOnly && config.isInternalRedeploy(); timeLeftMillis = timeLeftMillis - (System.currentTimeMillis() - started); } reconfigDue = (anyConfigChanged || !requireChange) && allGenerationsChanged && allGenerationsTheSame; @@ -259,6 +266,7 @@ public class ConfigSubscriber { // This indicates the clients will possibly reconfigure their services, so "reset" changed-logic in subscriptions. // Also if appropriate update the changed flag on the handler, which clients use. markSubsChangedSeen(currentGen); + internalRedeploy = internalRedeployOnly; generation = currentGen; } return reconfigDue; @@ -422,6 +430,12 @@ public class ConfigSubscriber { } /** + * Whether the current config generation received by this was due to a system-internal redeploy, + * not an application package change + */ + public boolean isInternalRedeploy() { 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 02c455bf1c3..76241c560e4 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 @@ -23,9 +23,9 @@ import com.yahoo.vespa.config.protocol.DefContent; * Represents one active subscription to one config * * @author vegardh - * @since 5.1 */ public abstract class ConfigSubscription<T extends ConfigInstance> { + protected static Logger log = Logger.getLogger(ConfigSubscription.class.getName()); protected final ConfigSubscriber subscriber; private final AtomicReference<ConfigState<T>> config = new AtomicReference<>(); @@ -35,34 +35,49 @@ public abstract class ConfigSubscription<T extends ConfigInstance> { private State state = State.OPEN; public static class ConfigState<T extends ConfigInstance> { + private final boolean configChanged; private final boolean generationChanged; private final T config; private final Long generation; - private ConfigState(boolean generationChanged, Long generation, boolean configChanged, T config) { - this.configChanged = configChanged; - this.config = config; + private final boolean internalRedeploy; + + private ConfigState(boolean generationChanged, Long generation, boolean internalRedeploy, boolean configChanged, T config) { this.generationChanged = generationChanged; this.generation = generation; + this.internalRedeploy = internalRedeploy; + this.configChanged = configChanged; + this.config = config; } + private ConfigState(Long generation, T config) { - this(false, generation,false, config); + this(false, generation, false, false, config); } + private ConfigState() { - this(false, 0L, false, null); + this(false, 0L, false, false, null); } + private ConfigState<T> createUnchanged() { return new ConfigState<T>(generation, config); } public boolean isConfigChanged() { return configChanged; } 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 T getConfig() { return config; } + } + /** * If non-null: The user has set this generation explicitly. nextConfig should take this into account. * Access to these variables _must_ be synchronized, as nextConfig and reload() is likely to be run from * independent threads. */ - private final AtomicReference<Long> reloadedGeneration = new AtomicReference<>(); enum State { @@ -168,30 +183,28 @@ public abstract class ConfigSubscription<T extends ConfigInstance> { } void setConfig(Long generation, T config) { - this.config.set(new ConfigState<>(true, generation, true, config)); + this.config.set(new ConfigState<>(true, generation, false, true, config)); } // Only used by {@link FileConfigSubscription} protected void setConfigIncGen(T config) { ConfigState<T> prev = this.config.get(); - setConfig(prev.getGeneration() + 1, config); + this.config.set(new ConfigState<>(true, prev.getGeneration() + 1, prev.isInternalRedeploy(), true, config)); } - // Only used by {@link FileConfigSubscription} and {@link ConfigSetSubscription} - protected void setConfigIfChangedIncGen(T config) { - ConfigState<T> prev = this.config.get(); - this.config.set(new ConfigState<>(true, prev.getGeneration() + 1, - !config.equals(prev.getConfig()), config)); - } protected void setConfigIfChanged(T config) { ConfigState<T> prev = this.config.get(); - this.config.set(new ConfigState<>(true, prev.getGeneration(), - !config.equals(prev.getConfig()), config)); + this.config.set(new ConfigState<>(true, prev.getGeneration(), prev.isInternalRedeploy(), !config.equals(prev.getConfig()), config)); } void setGeneration(Long generation) { - ConfigState<T> c = config.get(); - this.config.set(new ConfigState<>(true, generation, c.isConfigChanged(), c.getConfig())); + ConfigState<T> prev = config.get(); + this.config.set(new ConfigState<>(true, generation, prev.isInternalRedeploy(), prev.isConfigChanged(), prev.getConfig())); + } + + void setInternalRedeploy(boolean internalRedeploy) { + ConfigState<T> prev = config.get(); + this.config.set(new ConfigState<>(prev.isGenerationChanged(), prev.getGeneration(), prev.isConfigChanged(), internalRedeploy, prev.getConfig())); } /** diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java b/config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java index 8c3f87d0702..bcee06cd667 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/FileConfigSubscription.java @@ -17,9 +17,8 @@ import com.yahoo.log.LogLevel; /** * Subscription used when config id is file:... - * @author vegardh - * @since 5.1 * + * @author vegardh */ public class FileConfigSubscription<T extends ConfigInstance> extends ConfigSubscription<T> { 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 3eea87ab5ba..9ef7b602228 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 @@ -22,13 +22,14 @@ import com.yahoo.vespa.config.protocol.Payload; * A JRT config subscription uses one {@link JRTConfigRequester} to fetch config using Vespa RPC from a config source, typically proxy or server * * @author vegardh - * @since 5.1 */ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubscription<T> { + private JRTConfigRequester requester; private TimingValues timingValues; + // Last time we got an OK JRT callback for this - private long lastOK=0; + private long lastOK = 0; /** * The queue containing either nothing or the one (newest) request that has got callback from JRT, @@ -67,8 +68,11 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc } /** - * Polls the callback queue and <em>maybe</em> sets the following (caller must check): generation, generation changed, config, config changed - * Important: it never <em>resets</em> those flags, we must persist that state until the {@link ConfigSubscriber} clears it + * Polls the callback queue and <em>maybe</em> sets the following (caller must check): + * generation, generation changed, config, config changed + * Important: it never <em>resets</em> those flags, we must persist that state until the + * {@link ConfigSubscriber} clears it + * * @param timeoutMillis timeout when polling (returns after at most this time) * @return true if it got anything off the queue and <em>maybe</em> changed any state, false if timed out taking from queue */ @@ -85,6 +89,7 @@ public class JRTConfigSubscription<T extends ConfigInstance> extends ConfigSubsc return false; } if (jrtReq.hasUpdatedGeneration()) { + setInternalRedeploy(jrtReq.isInternalRedeploy()); if (jrtReq.hasUpdatedConfig()) { setNewConfig(jrtReq); } else { 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 4870d69bb23..1b2daba32a4 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 @@ -22,10 +22,9 @@ import com.yahoo.vespa.config.ConfigPayload; * * @author vegardh * @author gjoranv - * @since 5.1 - * */ public class JarConfigSubscription<T extends ConfigInstance> extends ConfigSubscription<T> { + private final String jarName; private final String path; private ZipEntry zipEntry = null; 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 cb623437dba..9ad8f5c6ba2 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 @@ -111,12 +111,14 @@ public class MockConnection implements ConnectionPool, com.yahoo.vespa.config.Co } static class OKResponseHandler extends AbstractResponseHandler { + protected void createResponse() { JRTServerConfigRequestV3 jrtReq = JRTServerConfigRequestV3.createFromRequest(request); Payload payload = Payload.from(ConfigPayload.empty()); long generation = 1; - jrtReq.addOkResponse(payload, generation, ConfigUtils.getMd5(payload.getData())); + jrtReq.addOkResponse(payload, generation, false, ConfigUtils.getMd5(payload.getData())); } + } public interface ResponseHandler extends Runnable { @@ -131,6 +133,7 @@ public class MockConnection implements ConnectionPool, com.yahoo.vespa.config.Co } public abstract static class AbstractResponseHandler implements ResponseHandler { + private RequestWaiter requestWaiter; protected Request request; 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 0d3f04361aa..60811dd38d1 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 @@ -16,10 +16,9 @@ import com.yahoo.vespa.config.ConfigPayload; * Config is the actual text given after the config id, with newlines * * @author vegardh - * @since 5.1 - * */ public class RawConfigSubscription<T extends ConfigInstance> extends ConfigSubscription<T> { + final String inputPayload; String payload; 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 75c5161103e..3aaff1a6b57 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; /** * Constructor for an empty config (not yet resolved). @@ -38,27 +39,29 @@ 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, 0, Collections.emptyList(), Optional.empty()); + this(key, defMd5, null, "", 0L, false, 0, Collections.emptyList(), Optional.empty()); } public RawConfig(ConfigKey<?> key, String defMd5, Payload payload, String configMd5, long generation, - List<String> defContent, Optional<VespaVersion> vespaVersion) { - this(key, defMd5, payload, configMd5, generation, 0, defContent, vespaVersion); + boolean internalRedeploy, List<String> defContent, Optional<VespaVersion> vespaVersion) { + this(key, defMd5, payload, configMd5, generation, internalRedeploy, 0, defContent, vespaVersion); } /** Copy constructor */ public RawConfig(RawConfig rawConfig) { this(rawConfig.key, rawConfig.defMd5, rawConfig.payload, rawConfig.configMd5, - rawConfig.generation, rawConfig.errorCode, rawConfig.defContent, rawConfig.getVespaVersion()); + rawConfig.generation, rawConfig.internalRedeploy, rawConfig.errorCode, + rawConfig.defContent, rawConfig.getVespaVersion()); } public RawConfig(ConfigKey<?> key, String defMd5, Payload payload, String configMd5, long generation, - int errorCode, List<String> defContent, Optional<VespaVersion> vespaVersion) { + boolean internalRedeploy, 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.errorCode = errorCode; this.defContent = defContent; this.vespaVersion = vespaVersion; @@ -69,8 +72,15 @@ public class RawConfig extends ConfigInstance { * @param req a {@link JRTClientConfigRequest} */ public static RawConfig createFromResponseParameters(JRTClientConfigRequest req) { - return new RawConfig(req.getConfigKey(), req.getConfigKey().getMd5(), req.getNewPayload(), req.getNewConfigMd5(), - req.getNewGeneration(), 0, req.getDefContent().asList(), req.getVespaVersion()); + return new RawConfig(req.getConfigKey(), + req.getConfigKey().getMd5(), + req.getNewPayload(), + req.getNewConfigMd5(), + req.getNewGeneration(), + req.isInternalRedeploy(), + 0, + req.getDefContent().asList(), + req.getVespaVersion()); } /** @@ -78,58 +88,47 @@ public class RawConfig extends ConfigInstance { * @param req a {@link JRTClientConfigRequest} */ public static RawConfig createFromServerRequest(JRTServerConfigRequest req) { - return new RawConfig(req.getConfigKey(), req.getConfigKey().getMd5() , Payload.from(new Utf8String(""), CompressionInfo.uncompressed()), req.getRequestConfigMd5(), - req.getRequestGeneration(), 0, req.getDefContent().asList(), req.getVespaVersion()); + return new RawConfig(req.getConfigKey(), + req.getConfigKey().getMd5() , + Payload.from(new Utf8String(""), CompressionInfo.uncompressed()), + req.getRequestConfigMd5(), + req.getRequestGeneration(), + req.isInternalRedeploy(), + 0, + req.getDefContent().asList(), + req.getVespaVersion()); } - public ConfigKey<?> getKey() { - return key; - } + public ConfigKey<?> getKey() { return key; } - public String getName() { - return key.getName(); - } + public String getName() { return key.getName(); } - public String getNamespace() { - return key.getNamespace(); - } + public String getNamespace() { return key.getNamespace(); } - public String getConfigId() { - return key.getConfigId(); - } + public String getConfigId() { return key.getConfigId(); } - public String getConfigMd5() { - return configMd5; - } + public String getConfigMd5() { return configMd5; } - public String getDefMd5() { - return defMd5; - } + public String getDefMd5() { return defMd5; } - public long getGeneration() { - return generation; - } + public long getGeneration() { return generation; } - public void setGeneration(long generation) { - this.generation = generation; - } + public void setGeneration(long generation) { this.generation = generation; } - public Payload getPayload() { - return payload; - } + /** + * Returns whether this config generation was created by a system internal redeploy, not an + * application package change. + */ + public boolean isInternalRedeploy() { return internalRedeploy; } - public int errorCode() { - return errorCode; - } + public Payload getPayload() { return payload; } - public String getDefNamespace() { - return key.getNamespace(); - } + public int errorCode() { return errorCode; } - public Optional<VespaVersion> getVespaVersion() { - return vespaVersion; - } + public String getDefNamespace() { return key.getNamespace(); } + + public Optional<VespaVersion> getVespaVersion() { return vespaVersion; } /** * Returns true if this config is equal to the config (same payload md5) in the given request. 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 5666417a50a..c07be8337fe 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 @@ -13,8 +13,7 @@ import java.util.List; * of this must be thread safe, because a response may be cached and, the methods below should be callable * from multiple request handler threads. * - * @author lulf - * @since 5.1.14 + * @author Ulf Lilleengen */ public interface ConfigResponse { @@ -24,6 +23,8 @@ public interface ConfigResponse { long getGeneration(); + boolean isInternalRedeploy(); + String getConfigMd5(); void serialize(OutputStream os, CompressionType uncompressed) throws IOException; 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 8e554dc45d8..97ba08a1c09 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 @@ -4,12 +4,13 @@ package com.yahoo.vespa.config.protocol; /** * Interface for config requests used by clients. * - * @author lulf - * @since 5.3 + * @author Ulf Lilleengen */ public interface JRTClientConfigRequest extends JRTConfigRequest { + /** * Validate config response given by the server. If none is given, or an error occurred, this should return false. + * * @return true if valid response, false if not. */ boolean validateResponse(); @@ -17,19 +18,22 @@ public interface JRTClientConfigRequest extends JRTConfigRequest { /** * Test whether ot not the returned config has an updated generation. This should return false if no response have * been given. + * * @return true if generation is updated, false if not. */ boolean hasUpdatedGeneration(); /** * Return the payload in the response given by the server. The payload will be empty if no response was given. + * * @return the config payload. */ Payload getNewPayload(); /** - * Create a new {@link JRTClientConfigRequest} based on this request based on the same request parameters, but having - * the timeout changed. + * Create a new {@link JRTClientConfigRequest} based on this request based on the same request parameters, + * but having the timeout changed. + * * @param timeout server timeout of the new request. * @return a new {@link JRTClientConfigRequest} instance. */ @@ -37,44 +41,57 @@ public interface JRTClientConfigRequest extends JRTConfigRequest { /** * Test whether or not the returned request is an error. + * * @return true if error, false if not. */ boolean isError(); /** * Get the generation of the newly provided config. If none has been given, 0 should be returned. + * * @return the new generation. */ long getNewGeneration(); + /** Returns whether this config changes is due to an internal change not an application package change */ + boolean isInternalRedeploy(); + /** * Get the config md5 of the config returned by the server. Return an empty string if no response has been returned. + * * @return a config md5. */ String getNewConfigMd5(); /** - * Test whether or not the payload is contained in this response or not. Should return false for error responses as well. + * Test whether or not the payload is contained in this response or not. + * Should return false for error responses as well. + * * @return true if empty, false if not. */ boolean containsPayload(); /** - * Test whether or not the response contains an updated config or not. False if no response has been returned. + * Test whether or not the response contains an updated config or not. + * False if no response has been returned. + * * @return true if config is updated, false if not. */ boolean hasUpdatedConfig(); /** - * Get the {@link Trace} given in the response by the server. The {@link Trace} can be used to add further tracing - * and later printed to provide useful debug info. + * Get the {@link Trace} given in the response by the server. + * The {@link Trace} can be used to add further tracing and later printed to provide useful debug info. + * * @return a {@link Trace}. */ Trace getResponseTrace(); /** * Get config definition content. + * * @return def as lines. */ DefContent getDefContent(); + } 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 3d7c0dc1e80..1c842a4d1b0 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 @@ -19,8 +19,7 @@ import java.util.Optional; * * See {@link JRTServerConfigRequestV3} for protocol details. * - * @author lulf - * @since 5.19 + * @author Ulf Lilleengen */ public class JRTClientConfigRequestV3 extends SlimeClientConfigRequest { @@ -71,7 +70,10 @@ public class JRTClientConfigRequestV3 extends SlimeClientConfigRequest { requestData.getVespaVersion()); } - public static <T extends ConfigInstance> JRTClientConfigRequest createFromSub(JRTConfigSubscription<T> sub, Trace trace, CompressionType compressionType, Optional<VespaVersion> vespaVersion) { + public static <T extends ConfigInstance> JRTClientConfigRequest createFromSub(JRTConfigSubscription<T> sub, + Trace trace, + CompressionType compressionType, + Optional<VespaVersion> vespaVersion) { String hostname = ConfigUtils.getCanonicalHostName(); ConfigKey<T> key = sub.getKey(); ConfigSubscription.ConfigState<T> configState = sub.getConfigState(); @@ -88,7 +90,11 @@ public class JRTClientConfigRequestV3 extends SlimeClientConfigRequest { } - public static JRTClientConfigRequest createFromRaw(RawConfig config, long serverTimeout, Trace trace, CompressionType compressionType, Optional<VespaVersion> vespaVersion) { + public static JRTClientConfigRequest createFromRaw(RawConfig config, + long serverTimeout, + Trace trace, + CompressionType compressionType, + Optional<VespaVersion> vespaVersion) { String hostname = ConfigUtils.getCanonicalHostName(); return createWithParams(config.getKey(), DefContent.fromList(config.getDefContent()), 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 54607ec4502..763f672a513 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 @@ -6,13 +6,14 @@ import com.yahoo.vespa.config.GetConfigRequest; /** * Interface for config requests at the server end point. * - * @author lulf - * @since 5.3 + * @author Ulf Lilleengen */ public interface JRTServerConfigRequest extends JRTConfigRequest, GetConfigRequest { + /** * Notify this request that its delayed due to no new config being available at this point. The value * provided in this function should be returned when calling {@link #isDelayedResponse()}. + * * @param delayedResponse true if response is delayed, false if not. */ void setDelayedResponse(boolean delayedResponse); @@ -20,6 +21,7 @@ public interface JRTServerConfigRequest extends JRTConfigRequest, GetConfigReque /** * Signal error when handling this request. The error should be reflected in the request state and propagated * back to the client. + * * @param errorCode error code, as described in {@link com.yahoo.vespa.config.ErrorCode}. * @param message message to display for this error, typically printed by client. */ @@ -27,33 +29,46 @@ public interface JRTServerConfigRequest extends JRTConfigRequest, GetConfigReque /** * Signal that the request was handled and provide return values typically needed by a client. + * * @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 configMd5 The md5sum of the given payload. */ - void addOkResponse(Payload payload, long generation, String configMd5); + void addOkResponse(Payload payload, long generation, boolean internalRedeployment, String configMd5); /** * Get the current config md5 of the client config. + * * @return a config md5. */ String getRequestConfigMd5(); /** * Get the current config generation of the client config. + * * @return the current config generation. */ long getRequestGeneration(); /** * Check whether or not this request is delayed. + * * @return true if delayed, false if not. */ boolean isDelayedResponse(); /** + * Returns whether the response config was created by a system internal redeploy, not an application + * package change + */ + boolean isInternalRedeploy(); + + /** * Get the request trace for this request. The trace can be used to trace config execution to provide useful * debug info in production environments. + * * @return a {@link Trace} instance. */ Trace getRequestTrace(); @@ -65,4 +80,5 @@ public interface JRTServerConfigRequest extends JRTConfigRequest, GetConfigReque * @return A {@link Payload} that satisfies this request format. */ Payload payloadFromResponse(ConfigResponse response); + } 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 b0096444820..f70ebf39a28 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 @@ -20,17 +20,21 @@ import java.io.IOException; * The implementation of addOkResponse is optimized for doing as little copying of payload data as possible, ensuring * that we get a lower memory footprint. * - * @author lulf - * @since 5.19 + * @author Ulf Lilleengen */ +// TODO: Merge with parent public class JRTServerConfigRequestV3 extends SlimeServerConfigRequest { + /** Response field */ + private boolean internalRedeploy = false; + protected JRTServerConfigRequestV3(Request request) { super(request); } @Override - public void addOkResponse(Payload payload, long generation, String configMd5) { + public void addOkResponse(Payload payload, long generation, boolean internalRedeploy, String configMd5) { + this.internalRedeploy = internalRedeploy; boolean changedConfig = !configMd5.equals(getRequestConfigMd5()); boolean changedConfigAndNewGeneration = changedConfig && ConfigUtils.isGenerationNewer(generation, getRequestGeneration()); Payload responsePayload = payload.withCompression(getCompressionType()); @@ -41,6 +45,7 @@ public class JRTServerConfigRequestV3 extends SlimeServerConfigRequest { addCommonReturnValues(jsonGenerator); setResponseField(jsonGenerator, SlimeResponseData.RESPONSE_CONFIG_MD5, configMd5); setResponseField(jsonGenerator, SlimeResponseData.RESPONSE_CONFIG_GENERATION, generation); + setResponseField(jsonGenerator, SlimeResponseData.RESPONSE_INTERNAL_REDEPLOY, internalRedeploy); jsonGenerator.writeObjectFieldStart(SlimeResponseData.RESPONSE_COMPRESSION_INFO); if (responsePayload == null) { throw new RuntimeException("Payload is null for ' " + this + ", not able to create response"); @@ -73,7 +78,11 @@ public class JRTServerConfigRequestV3 extends SlimeServerConfigRequest { return 3; } + @Override + public boolean isInternalRedeploy() { return internalRedeploy; } + public static JRTServerConfigRequestV3 createFromRequest(Request req) { return new JRTServerConfigRequestV3(req); } + } diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeClientConfigRequest.java b/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeClientConfigRequest.java index 19323fb1a85..055f48bbcf3 100644 --- a/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeClientConfigRequest.java +++ b/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeClientConfigRequest.java @@ -16,8 +16,7 @@ import java.util.logging.Logger; * Base class for new generation of config requests based on {@link Slime}. Allows for some customization of * payload encoding and decoding, as well as adding extra request/response fields. * - * @author lulf - * @since 5.18 + * @author Ulf Lilleengen */ public abstract class SlimeClientConfigRequest implements JRTClientConfigRequest { @@ -82,6 +81,7 @@ public abstract class SlimeClientConfigRequest implements JRTClientConfigRequest .append(",").append(getVespaVersion()).append("'\n"); sb.append("response='").append(getNewConfigMd5()) .append(",").append(getNewGeneration()) + .append(",").append(isInternalRedeploy()) .append("'\n"); return sb.toString(); } @@ -203,6 +203,11 @@ public abstract class SlimeClientConfigRequest implements JRTClientConfigRequest } @Override + public boolean isInternalRedeploy() { + return responseData.getResponseInternalRedeployment(); + } + + @Override public long getRequestGeneration() { return requestData.getRequestGeneration(); } 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 e7aae3251d0..9e05b5b2d86 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 @@ -15,8 +15,7 @@ import java.util.List; /** * Class for serializing config responses based on {@link com.yahoo.slime.Slime} implementing the {@link ConfigResponse} interface. * - * @author lulf - * @since 5.1 + * @author Ulf Lilleengen */ public class SlimeConfigResponse implements ConfigResponse { @@ -24,17 +23,26 @@ public class SlimeConfigResponse implements ConfigResponse { private final CompressionInfo compressionInfo; private final InnerCNode targetDef; private final long generation; + private final boolean internalRedeployment; private final String configMd5; public static SlimeConfigResponse fromConfigPayload(ConfigPayload payload, InnerCNode targetDef, long generation, String configMd5) { Utf8Array data = payload.toUtf8Array(true); - return new SlimeConfigResponse(data, targetDef, generation, configMd5, CompressionInfo.create(CompressionType.UNCOMPRESSED, data.getByteLength())); + return new SlimeConfigResponse(data, targetDef, generation, false, + configMd5, + CompressionInfo.create(CompressionType.UNCOMPRESSED, data.getByteLength())); } - public SlimeConfigResponse(Utf8Array payload, InnerCNode targetDef, long generation, String configMd5, CompressionInfo compressionInfo) { + public SlimeConfigResponse(Utf8Array payload, + InnerCNode targetDef, + long generation, + boolean internalRedeployment, + String configMd5, + CompressionInfo compressionInfo) { this.payload = payload; this.targetDef = targetDef; this.generation = generation; + this.internalRedeployment = internalRedeployment; this.configMd5 = configMd5; this.compressionInfo = compressionInfo; } @@ -62,6 +70,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 internalRedeployment; } + @Override public String getConfigMd5() { return configMd5; 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 04f6df7a45b..6add29074d1 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 @@ -11,10 +11,10 @@ import com.yahoo.text.Utf8; * Contains response data for a slime response and methods for decoding the response data that * are common to all {@link Slime} based config requests. * - * @author lulf - * @since 5.18 + * @author Ulf Lilleengen */ class SlimeResponseData { + static final String RESPONSE_VERSION = "version"; static final String RESPONSE_DEF_NAME = "defName"; static final String RESPONSE_DEF_NAMESPACE = "defNamespace"; @@ -24,6 +24,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_COMPRESSION_INFO = "compressionInfo"; private final Request request; @@ -66,4 +67,10 @@ class SlimeResponseData { CompressionInfo getCompressionInfo() { return CompressionInfo.fromSlime(getResponseField(RESPONSE_COMPRESSION_INFO)); } + + boolean getResponseInternalRedeployment() { + Inspector inspector = getResponseField(RESPONSE_INTERNAL_REDEPLOY); + return inspector.valid() ? inspector.asBool() : false; + } + } diff --git a/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeServerConfigRequest.java b/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeServerConfigRequest.java index 662eacc4eea..41bf38ef1dc 100644 --- a/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeServerConfigRequest.java +++ b/config/src/main/java/com/yahoo/vespa/config/protocol/SlimeServerConfigRequest.java @@ -19,8 +19,7 @@ import java.util.logging.Logger; * payload encoding and decoding, as well as adding extra request/response fields. Used by both V2 and V3 * config protocol. * - * @author lulf - * @since 5.18 + * @author Ulf Lilleengen */ abstract class SlimeServerConfigRequest implements JRTServerConfigRequest { @@ -164,6 +163,10 @@ abstract class SlimeServerConfigRequest implements JRTServerConfigRequest { jsonGenerator.writeNumberField(fieldName, value); } + protected static void setResponseField(JsonGenerator jsonGenerator, String fieldName, boolean value) throws IOException { + jsonGenerator.writeBooleanField(fieldName, value); + } + @Override public long getRequestGeneration() { return requestData.getRequestGeneration(); diff --git a/config/src/test/java/com/yahoo/config/subscription/ConfigSetSubscriptionTest.java b/config/src/test/java/com/yahoo/config/subscription/ConfigSetSubscriptionTest.java index 8acab56d838..d17a2ff61f4 100644 --- a/config/src/test/java/com/yahoo/config/subscription/ConfigSetSubscriptionTest.java +++ b/config/src/test/java/com/yahoo/config/subscription/ConfigSetSubscriptionTest.java @@ -85,7 +85,7 @@ public class ConfigSetSubscriptionTest { assertEquals(hA1.getConfig().times(), 89); assertEquals(hS.getConfig().stringVal(), "StringVal"); - //Reconfigure all configs, generation should change + // Reconfigure all configs, generation should change a0builder.message("A new message, 0").times(880); a1builder.message("A new message, 1").times(890); barBuilder.stringVal("new StringVal"); 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 33560ff666d..b19da2c1689 100644 --- a/config/src/test/java/com/yahoo/vespa/config/RawConfigTest.java +++ b/config/src/test/java/com/yahoo/vespa/config/RawConfigTest.java @@ -60,14 +60,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, defContent, Optional.empty()); - RawConfig config2 = new RawConfig(key, defMd5, payload, configMd5, 2L, defContent, Optional.empty()); + 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()); 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, defContent, Optional.of(vespaVersion)); + RawConfig config3 = new RawConfig(key, defMd5, payload, "9999", generation, false, defContent, Optional.of(vespaVersion)); assertThat(config, is(not(config3))); assertThat(config.hashCode(), is(not(config3.hashCode()))); // Check that vespa version is set correctly @@ -81,19 +81,19 @@ public class RawConfigTest { assertFalse(config.equals(key)); // errors - RawConfig errorConfig1 = new RawConfig(key, defMd5, payload, configMd5, generation, 1, defContent, Optional.empty()); + RawConfig errorConfig1 = new RawConfig(key, defMd5, payload, configMd5, generation, 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, 2, defContent, Optional.empty()); + RawConfig errorConfig2 = new RawConfig(key, defMd5, payload, configMd5, generation, 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, defContent, Optional.empty()); + RawConfig config = new RawConfig(key, defMd5, payload, configMd5, generation, false, defContent, Optional.empty()); assertThat(config.getPayload(), is(payload)); assertThat(config.getConfigMd5(), is(configMd5)); assertThat(config.getGeneration(), is(generation)); @@ -104,19 +104,19 @@ public class RawConfigTest { public void require_correct_defmd5() { final String defMd5ForEmptyDefContent = "d41d8cd98f00b204e9800998ecf8427e"; - RawConfig config = new RawConfig(key, null, payload, configMd5, generation, defContent, Optional.empty()); + RawConfig config = new RawConfig(key, null, payload, configMd5, generation, false, defContent, Optional.empty()); assertThat(config.getDefMd5(), is(defMd5)); - config = new RawConfig(key, "", payload, configMd5, generation, defContent, Optional.empty()); + config = new RawConfig(key, "", payload, configMd5, generation, false, defContent, Optional.empty()); assertThat(config.getDefMd5(), is(defMd5)); - config = new RawConfig(key, defMd5, payload, configMd5, generation, defContent, Optional.empty()); + config = new RawConfig(key, defMd5, payload, configMd5, generation, false, defContent, Optional.empty()); assertThat(config.getDefMd5(), is(defMd5)); - config = new RawConfig(key, null, payload, configMd5, generation, null, Optional.empty()); + config = new RawConfig(key, null, payload, configMd5, generation, false, null, Optional.empty()); assertNull(config.getDefMd5()); - config = new RawConfig(key, null, payload, configMd5, generation, Arrays.asList(""), Optional.empty()); + config = new RawConfig(key, null, payload, configMd5, generation, false, Arrays.asList(""), Optional.empty()); assertThat(config.getDefMd5(), is(defMd5ForEmptyDefContent)); - config = new RawConfig(key, "", payload, configMd5, generation, null, Optional.empty()); + config = new RawConfig(key, "", payload, configMd5, generation, false, null, Optional.empty()); assertThat(config.getDefMd5(), is("")); - config = new RawConfig(key, "", payload, configMd5, generation, Arrays.asList(""), Optional.empty()); + config = new RawConfig(key, "", payload, configMd5, generation, false, Arrays.asList(""), 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 9a7b216d6b0..7daac671b34 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 @@ -20,8 +20,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; /** - * @author lulf - * @since 5.1 + * @author Ulf Lilleengen */ public class ConfigResponseTest { @@ -45,13 +44,12 @@ public class ConfigResponseTest { @Test public void require_that_slime_response_decompresses_on_serialize() throws IOException { - ConfigPayload configPayload = ConfigPayload.fromInstance(new SimpletypesConfig(new SimpletypesConfig.Builder())); DefParser dParser = new DefParser(SimpletypesConfig.getDefName(), new StringReader(StringUtilities.implode(SimpletypesConfig.CONFIG_DEF_SCHEMA, "\n"))); InnerCNode targetDef = dParser.getTree(); Utf8Array data = configPayload.toUtf8Array(true); Utf8Array bytes = new Utf8Array(new LZ4PayloadCompressor().compress(data.getBytes())); - ConfigResponse response = new SlimeConfigResponse(bytes, targetDef, 3, "mymd5", CompressionInfo.create(CompressionType.LZ4, data.getByteLength())); + ConfigResponse response = new SlimeConfigResponse(bytes, targetDef, 3, false, "mymd5", CompressionInfo.create(CompressionType.LZ4, data.getByteLength())); List<String> payload = response.getLegacyPayload(); assertNotNull(payload); assertThat(payload.size(), is(6)); @@ -63,4 +61,5 @@ public class ConfigResponseTest { response.serialize(baos, CompressionType.UNCOMPRESSED); assertThat(baos.toString(), is("{\"boolval\":false,\"doubleval\":0.0,\"enumval\":\"VAL1\",\"intval\":0,\"longval\":0,\"stringval\":\"s\"}")); } + } diff --git a/config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestBase.java b/config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestBase.java index 1f5274b832b..cdaaf2061f4 100644 --- a/config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestBase.java +++ b/config/src/test/java/com/yahoo/vespa/config/protocol/JRTConfigRequestBase.java @@ -125,7 +125,7 @@ public abstract class JRTConfigRequestBase { @Test public void next_request_when_error_is_correct() { - serverReq.addOkResponse(createPayload(), 999999, "newmd5"); + serverReq.addOkResponse(createPayload(), 999999, false, "newmd5"); serverReq.addErrorResponse(ErrorCode.OUTDATED_CONFIG, "error message"); System.out.println(serverReq); JRTClientConfigRequest next = clientReq.nextRequest(6); @@ -141,7 +141,7 @@ public abstract class JRTConfigRequestBase { Payload payload = createPayload("vale"); String md5 = ConfigUtils.getMd5(payload.getData()); long generation = 4L; - serverReq.addOkResponse(payload, generation, md5); + serverReq.addOkResponse(payload, generation, false, md5); assertTrue(clientReq.validateResponse()); assertThat(clientReq.getNewPayload().withCompression(CompressionType.UNCOMPRESSED).getData().toString(), is(payload.getData().toString())); assertThat(clientReq.getNewGeneration(), is(4L)); @@ -168,7 +168,7 @@ public abstract class JRTConfigRequestBase { @Test public void generation_only_is_updated() { Payload payload = createPayload(); - serverReq.addOkResponse(payload, 4L, ConfigUtils.getMd5(payload.getData())); + serverReq.addOkResponse(payload, 4L, false, ConfigUtils.getMd5(payload.getData())); boolean value = clientReq.validateResponse(); assertTrue(clientReq.errorMessage(), value); assertFalse(clientReq.hasUpdatedConfig()); @@ -188,7 +188,7 @@ public abstract class JRTConfigRequestBase { @Test public void nothing_is_updated() { Payload payload = createPayload(); - serverReq.addOkResponse(payload, currentGeneration, configMd5); + serverReq.addOkResponse(payload, currentGeneration, false, configMd5); assertTrue(clientReq.validateResponse()); assertFalse(clientReq.hasUpdatedConfig()); assertFalse(clientReq.hasUpdatedGeneration()); @@ -199,7 +199,7 @@ public abstract class JRTConfigRequestBase { Payload payload = Payload.from(ConfigPayload.empty()); clientReq = createReq(payload); serverReq = createReq(clientReq.getRequest()); - serverReq.addOkResponse(payload, currentGeneration, ConfigUtils.getMd5(payload.getData())); + serverReq.addOkResponse(payload, currentGeneration, false, ConfigUtils.getMd5(payload.getData())); boolean val = clientReq.validateResponse(); assertTrue(clientReq.errorMessage(), val); assertFalse(clientReq.hasUpdatedConfig()); @@ -238,7 +238,7 @@ public abstract class JRTConfigRequestBase { @Override protected void createResponse() { JRTServerConfigRequest serverRequest = createReq(request); - serverRequest.addOkResponse(createPayload(), currentGeneration, configMd5); + serverRequest.addOkResponse(createPayload(), currentGeneration, false, configMd5); } }); 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 ccb68da5f85..896ee116301 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 @@ -71,7 +71,7 @@ public class JRTConfigRequestV3Test extends JRTConfigRequestBase { public void emptypayload() { ConfigPayload payload = ConfigPayload.empty(); SlimeConfigResponse response = SlimeConfigResponse.fromConfigPayload(payload, null, 0, ConfigUtils.getMd5(payload)); - serverReq.addOkResponse(serverReq.payloadFromResponse(response), response.getGeneration(), response.getConfigMd5()); + serverReq.addOkResponse(serverReq.payloadFromResponse(response), response.getGeneration(), false, response.getConfigMd5()); assertTrue(clientReq.validateResponse()); assertTrue(clientReq.hasUpdatedGeneration()); assertThat(clientReq.getNewPayload().withCompression(CompressionType.UNCOMPRESSED).getData().toString(), is("{}")); |