public OMClientResponse validateAndUpdateCache()

in hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyRenameRequestWithFSO.java [74:236]


  public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, ExecutionContext context) {
    final long trxnLogIndex = context.getIndex();

    RenameKeyRequest renameKeyRequest = getOmRequest().getRenameKeyRequest();
    KeyArgs keyArgs = renameKeyRequest.getKeyArgs();
    Map<String, String> auditMap = buildAuditMap(keyArgs, renameKeyRequest);

    String volumeName = keyArgs.getVolumeName();
    String bucketName = keyArgs.getBucketName();
    String fromKeyName = keyArgs.getKeyName();
    String toKeyName = renameKeyRequest.getToKeyName();

    OMMetrics omMetrics = ozoneManager.getMetrics();
    omMetrics.incNumKeyRenames();

    AuditLogger auditLogger = ozoneManager.getAuditLogger();

    OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(
            getOmRequest());

    OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
    boolean acquiredLock = false;
    OMClientResponse omClientResponse = null;
    Exception exception = null;
    OmKeyInfo fromKeyValue;
    Result result;
    try {
      if (fromKeyName.isEmpty()) {
        throw new OMException("Source key name is empty",
                OMException.ResultCodes.INVALID_KEY_NAME);
      }

      mergeOmLockDetails(omMetadataManager.getLock()
          .acquireWriteLock(BUCKET_LOCK, volumeName, bucketName));
      acquiredLock = getOmLockDetails().isLockAcquired();

      // Validate bucket and volume exists or not.
      validateBucketAndVolume(omMetadataManager, volumeName, bucketName);

      // Check if fromKey exists
      OzoneFileStatus fromKeyFileStatus = OMFileRequest.getOMKeyInfoIfExists(
          omMetadataManager, volumeName, bucketName, fromKeyName, 0,
          ozoneManager.getDefaultReplicationConfig());

      // case-1) fromKeyName should exist, otw throws exception
      if (fromKeyFileStatus == null) {
        // TODO: Add support for renaming open key
        throw new OMException("Key not found " + fromKeyName, KEY_NOT_FOUND);
      }

      if (fromKeyFileStatus.getKeyInfo().isHsync()) {
        throw new OMException("Open file cannot be renamed since it is " +
            "hsync'ed: volumeName=" + volumeName + ", bucketName=" +
            bucketName + ", key=" + fromKeyName, RENAME_OPEN_FILE);
      }

      // source existed
      fromKeyValue = fromKeyFileStatus.getKeyInfo();
      boolean isRenameDirectory = fromKeyFileStatus.isDirectory();

      // case-2) Cannot rename a directory to its own subdirectory
      OMFileRequest.verifyToDirIsASubDirOfFromDirectory(fromKeyName,
              toKeyName, fromKeyFileStatus.isDirectory());

      OzoneFileStatus toKeyFileStatus = OMFileRequest.getOMKeyInfoIfExists(
          omMetadataManager, volumeName, bucketName, toKeyName, 0,
          ozoneManager.getDefaultReplicationConfig());

      // Check if toKey exists.
      if (toKeyFileStatus != null) {
        // Destination exists and following are different cases:
        OmKeyInfo toKeyValue = toKeyFileStatus.getKeyInfo();

        if (fromKeyValue.getKeyName().equals(toKeyValue.getKeyName())) {
          // case-3) If src == destin then check source and destin of same type
          // (a) If dst is a file then return true.
          // (b) Otherwise throws exception.
          // TODO: Discuss do we need to throw exception for file as well.
          if (toKeyFileStatus.isFile()) {
            result = Result.SUCCESS;
          } else {
            throw new OMException("Key already exists " + toKeyName,
                    OMException.ResultCodes.KEY_ALREADY_EXISTS);
          }
        } else if (toKeyFileStatus.isDirectory()) {
          // case-4) If dst is a directory then rename source as sub-path of it
          // For example: rename /source to /dst will lead to /dst/source
          String fromFileName = OzoneFSUtils.getFileName(fromKeyName);
          String newToKeyName = OzoneFSUtils.appendFileNameToKeyPath(toKeyName,
                  fromFileName);
          OzoneFileStatus newToOzoneFileStatus =
              OMFileRequest.getOMKeyInfoIfExists(omMetadataManager,
                  volumeName, bucketName, newToKeyName, 0,
                  ozoneManager.getDefaultReplicationConfig());

          if (newToOzoneFileStatus != null) {
            // case-5) If new destin '/dst/source' exists then throws exception
            throw new OMException(String.format(
                    "Failed to rename %s to %s, file already exists or not " +
                            "empty!", fromKeyName, newToKeyName),
                    OMException.ResultCodes.KEY_ALREADY_EXISTS);
          }

          omClientResponse = renameKey(toKeyValue, newToKeyName, fromKeyValue,
              fromKeyName, isRenameDirectory, keyArgs.getModificationTime(),
              ozoneManager, omResponse, trxnLogIndex);
          result = Result.SUCCESS;
        } else {
          // case-6) If destination is a file type and if exists then throws
          // key already exists exception.
          throw new OMException("Failed to rename, key already exists "
                  + toKeyName, OMException.ResultCodes.KEY_ALREADY_EXISTS);
        }
      } else {
        // Destination doesn't exist and the cases are:
        // case-7) Check whether dst parent dir exists or not. If parent
        // doesn't exist then throw exception, otw the source can be renamed to
        // destination path.
        OmKeyInfo toKeyParent = OMFileRequest.getKeyParentDir(volumeName,
                bucketName, toKeyName, ozoneManager, omMetadataManager);

        omClientResponse = renameKey(toKeyParent, toKeyName, fromKeyValue,
            fromKeyName, isRenameDirectory, keyArgs.getModificationTime(),
            ozoneManager, omResponse, trxnLogIndex);

        result = Result.SUCCESS;
      }
    } catch (IOException | InvalidPathException ex) {
      result = Result.FAILURE;
      exception = ex;
      omClientResponse = new OMKeyRenameResponseWithFSO(createErrorOMResponse(
              omResponse, exception), getBucketLayout());
    } finally {
      if (acquiredLock) {
        mergeOmLockDetails(omMetadataManager.getLock()
            .releaseWriteLock(BUCKET_LOCK, volumeName, bucketName));
      }
      if (omClientResponse != null) {
        omClientResponse.setOmLockDetails(getOmLockDetails());
      }
    }

    markForAudit(auditLogger, buildAuditMessage(OMAction.RENAME_KEY, auditMap,
            exception, getOmRequest().getUserInfo()));

    switch (result) {
    case SUCCESS:
      LOG.debug("Rename Key is successfully completed for volume:{} bucket:{}" +
                      " fromKey:{} toKey:{}. ", volumeName, bucketName,
              fromKeyName, toKeyName);
      break;
    case FAILURE:
      ozoneManager.getMetrics().incNumKeyRenameFails();
      LOG.error("Rename key failed for volume:{} bucket:{} fromKey:{} " +
                      "toKey:{}. Exception: {}.", volumeName, bucketName,
              fromKeyName, toKeyName, exception.getMessage());
      break;
    default:
      LOG.error("Unrecognized Result for OMKeyRenameRequest: {}",
              renameKeyRequest);
    }
    return omClientResponse;
  }