diff options
3 files changed, 22 insertions, 18 deletions
diff --git a/config/src/main/java/com/yahoo/vespa/config/PayloadChecksums.java b/config/src/main/java/com/yahoo/vespa/config/PayloadChecksums.java index be935043dc0..7de2de017ee 100644 --- a/config/src/main/java/com/yahoo/vespa/config/PayloadChecksums.java +++ b/config/src/main/java/com/yahoo/vespa/config/PayloadChecksums.java @@ -70,6 +70,12 @@ public class PayloadChecksums { public boolean isEmpty() { return this.equals(empty()); } + public boolean matches(PayloadChecksums other) { + if (getForType(XXHASH64) != null) return getForType(XXHASH64).equals(other.getForType(XXHASH64)); + if (getForType(MD5) != null) return getForType(MD5).equals(other.getForType(MD5)); + return true; + } + @Override public String toString() { return checksums.values().stream() 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 771068aa67a..c7326ea37f1 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 @@ -26,18 +26,6 @@ public interface ConfigResponse { void serialize(OutputStream os, CompressionType uncompressed) throws IOException; - default boolean hasEqualConfig(JRTServerConfigRequest request) { - PayloadChecksums payloadChecksums = getPayloadChecksums(); - PayloadChecksum xxhash64 = payloadChecksums.getForType(PayloadChecksum.Type.XXHASH64); - PayloadChecksum md5 = payloadChecksums.getForType(PayloadChecksum.Type.MD5); - if (xxhash64 != null) - return xxhash64.equals(request.getRequestConfigChecksums().getForType(PayloadChecksum.Type.XXHASH64)); - if (md5 != null) - return md5.equals(request.getRequestConfigChecksums().getForType(PayloadChecksum.Type.MD5)); - - return true; - } - default boolean hasNewerGeneration(JRTServerConfigRequest request) { return (getGeneration() > request.getRequestGeneration()); } 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 1946a9bf76c..c31015b533a 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 @@ -5,7 +5,10 @@ import com.yahoo.cloud.config.SentinelConfig; import com.yahoo.collections.Pair; import com.yahoo.component.Version; import com.yahoo.config.provision.TenantName; +import com.yahoo.container.di.config.ApplicationBundlesConfig; import com.yahoo.net.HostName; +import com.yahoo.vespa.config.PayloadChecksum; +import com.yahoo.vespa.config.PayloadChecksum.Type; import com.yahoo.vespa.config.PayloadChecksums; import com.yahoo.jrt.Request; import com.yahoo.vespa.config.ConfigPayload; @@ -34,6 +37,9 @@ class GetConfigProcessor implements Runnable { private static final Logger log = Logger.getLogger(GetConfigProcessor.class.getName()); private static final String localHostName = HostName.getLocalhost(); + private static final PayloadChecksums emptyApplicationBundlesConfigChecksums = + PayloadChecksums.fromPayload(Payload.from(ConfigPayload.fromInstance(new ApplicationBundlesConfig.Builder().build()))); + private final JRTServerConfigRequest request; /* True only when this request has expired its server timeout and we need to respond to the client */ @@ -108,11 +114,6 @@ class GetConfigProcessor implements Runnable { return null; } - if ( ! context.requestHandler().compatibleWith(vespaVersion, context.applicationId())) { - handleError(request, ErrorCode.INCOMPATIBLE_VESPA_VERSION, "Version " + printableVespaVersion(vespaVersion) + " is binary incompatible with the latest deployed version"); - return null; - } - this.logPre = TenantRepository.logPre(context.applicationId()); ConfigResponse config; try { @@ -130,7 +131,16 @@ 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)) { + if ((config != null) && ( ! config.getPayloadChecksums().matches(request.getRequestConfigChecksums()) + || config.hasNewerGeneration(request) + || forceResponse)) { + if ( ApplicationBundlesConfig.class.equals(request.getConfigKey().getConfigClass()) // If it's a Java container ... + && ! context.requestHandler().compatibleWith(vespaVersion, context.applicationId()) // ... with a runtime version incompatible with the deploying version ... + && ! emptyApplicationBundlesConfigChecksums.matches(config.getPayloadChecksums())) { // ... and there actually are incompatible user bundles, then return no config: + handleError(request, ErrorCode.INCOMPATIBLE_VESPA_VERSION, "Version " + printableVespaVersion(vespaVersion) + " is binary incompatible with the latest deployed version"); + return null; + } + // debugLog(trace, "config response before encoding:" + config.toString()); request.addOkResponse(request.payloadFromResponse(config), config.getGeneration(), config.applyOnRestart(), config.getPayloadChecksums()); if (logDebug(trace)) { |