private boolean preUndeleteValidation(CloudBlobMetadata metadata, StoreKey key, Map<String, Object> updateFields)
      throws StoreException {
    validateAccountAndContainer(Collections.singletonMap(key.getID(), metadata), Collections.singletonList(key));
    short requestedLifeVersion = (short) updateFields.get(FIELD_LIFE_VERSION);
    if (isVcr) {
      // This is an undelete request from vcr. Apply undelete only if incoming life version is more recent. 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.getLifeVersion() < requestedLifeVersion;
    }
    if (metadata.isExpired()) {
      throw new StoreException("Id " + key + " already expired in cloud ", StoreErrorCodes.TTLExpired);
    } else if (metadata.isUndeleted()) {
      throw new StoreException("Id " + key + " is already undeleted in cloud", StoreErrorCodes.IDUndeleted);
    } else if (!metadata.isDeleted()) {
      throw new StoreException("Id " + key + " is not deleted yet in cloud ", StoreErrorCodes.IDNotDeleted);
    } else if (metadata.getDeletionTime() + TimeUnit.MINUTES.toMillis(storeConfig.storeDeletedMessageRetentionMinutes)
        < System.currentTimeMillis()) {
      throw new StoreException("Id " + key + " already permanently deleted in cloud ",
          StoreErrorCodes.IDDeletedPermanently);
    }
    // Update life version to appropriate value for frontend requests.
    updateFields.put(FIELD_LIFE_VERSION, metadata.getLifeVersion() + 1);
    return true;
  }
Validates existing metadata in cloud destination against requested undelete.
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 local cloud destination life version is more recent. true if validation successful.
@throws StoreException if validation fails.
ambry-cloud/src/main/java/com/github/ambry/cloud/CloudBlobStore.java