private boolean preTtlUpdateValidation(CloudBlobMetadata metadata, StoreKey key, Map<String, Object> updateFields)
      throws StoreException {
    validateAccountAndContainer(Collections.singletonMap(key.getID(), metadata), Collections.singletonList(key));
    long now = System.currentTimeMillis();
    if (isVcr) {
      // For vcr don't update ttl if already updated. Don't throw any exception because replication relies on
      // findMissingKeys which in turn is dependent on {@link CloudDestination} implementation and can have some inconsistencies.
      return metadata.getExpirationTime() != Utils.Infinite_Time;
    }
    if (metadata.isDeleted()) {
      throw new StoreException("Cannot update TTL of " + key.getID() + " since it is already deleted in the index.",
          StoreErrorCodes.IDDeleted);
    } else if (metadata.getExpirationTime() != Utils.Infinite_Time
        && metadata.getExpirationTime() < now + ttlUpdateBufferTimeMs) {
      throw new StoreException(
          "TTL of " + key.getID() + " cannot be updated because it is too close to expiry. Minimum Op time (ms): " + now
              + ". ExpiresAtMs: " + metadata.getExpirationTime(), StoreErrorCodes.UpdateNotAllowed);
    }
    return true;
  }
Validates existing metadata in cloud destination against requested update for ttl.
Note that this method also has an unclean side effect of updating the {@code updateFields}.
@param metadata existing {@link CloudBlobMetadata} in cloud.
@param key {@link StoreKey} being updated.
@param updateFields {@link Map} of fields and values being updated.
@return false only for vcr if ttl is already applied on blob. true in all other cases if validation is successful.
@throws StoreException if validation fails.
ambry-cloud/src/main/java/com/github/ambry/cloud/CloudBlobStore.java