public OMClientResponse validateAndUpdateCache()

in hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMDirectoriesPurgeRequestWithFSO.java [64:205]


  public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, ExecutionContext context) {
    OzoneManagerProtocolProtos.PurgeDirectoriesRequest purgeDirsRequest =
        getOmRequest().getPurgeDirectoriesRequest();
    String fromSnapshot = purgeDirsRequest.hasSnapshotTableKey() ?
        purgeDirsRequest.getSnapshotTableKey() : null;

    List<OzoneManagerProtocolProtos.PurgePathRequest> purgeRequests =
            purgeDirsRequest.getDeletedPathList();
    Set<Pair<String, String>> lockSet = new HashSet<>();
    Map<Pair<String, String>, OmBucketInfo> volBucketInfoMap = new HashMap<>();
    OmMetadataManagerImpl omMetadataManager = (OmMetadataManagerImpl) ozoneManager.getMetadataManager();
    Map<String, OmKeyInfo> openKeyInfoMap = new HashMap<>();
    OMMetrics omMetrics = ozoneManager.getMetrics();
    DeletingServiceMetrics deletingServiceMetrics = ozoneManager.getDeletionMetrics();
    OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(
        getOmRequest());
    final SnapshotInfo fromSnapshotInfo;
    try {
      fromSnapshotInfo = fromSnapshot != null ? SnapshotUtils.getSnapshotInfo(ozoneManager,
          fromSnapshot) : null;
      // Checking if this request is an old request or new one.
      if (purgeDirsRequest.hasExpectedPreviousSnapshotID()) {
        // Validating previous snapshot since while purging deletes, a snapshot create request could make this purge
        // directory request invalid on AOS since the deletedDirectory would be in the newly created snapshot. Adding
        // subdirectories could lead to not being able to reclaim sub-files and subdirectories since the
        // file/directory would be present in the newly created snapshot.
        // Validating previous snapshot can ensure the chain hasn't changed.
        UUID expectedPreviousSnapshotId = purgeDirsRequest.getExpectedPreviousSnapshotID().hasUuid()
            ? fromProtobuf(purgeDirsRequest.getExpectedPreviousSnapshotID().getUuid()) : null;
        validatePreviousSnapshotId(fromSnapshotInfo, omMetadataManager.getSnapshotChainManager(),
            expectedPreviousSnapshotId);
      }
    } catch (IOException e) {
      LOG.error("Error occurred while performing OMDirectoriesPurge. ", e);
      return new OMDirectoriesPurgeResponseWithFSO(createErrorOMResponse(omResponse, e));
    }
    try {
      int numSubDirMoved = 0, numSubFilesMoved = 0, numDirsDeleted = 0;
      for (OzoneManagerProtocolProtos.PurgePathRequest path : purgeRequests) {
        for (OzoneManagerProtocolProtos.KeyInfo key :
            path.getMarkDeletedSubDirsList()) {
          OmKeyInfo keyInfo = OmKeyInfo.getFromProtobuf(key);
          String volumeName = keyInfo.getVolumeName();
          String bucketName = keyInfo.getBucketName();
          Pair<String, String> volBucketPair = Pair.of(volumeName, bucketName);
          if (!lockSet.contains(volBucketPair)) {
            omMetadataManager.getLock().acquireWriteLock(BUCKET_LOCK,
                volumeName, bucketName);
            lockSet.add(volBucketPair);
          }
          omMetrics.decNumKeys();
          numSubDirMoved++;
          OmBucketInfo omBucketInfo = getBucketInfo(omMetadataManager,
              volumeName, bucketName);
          // bucketInfo can be null in case of delete volume or bucket
          // or key does not belong to bucket as bucket is recreated
          if (null != omBucketInfo
              && omBucketInfo.getObjectID() == path.getBucketId()) {
            omBucketInfo.incrUsedNamespace(-1L);
            String ozoneDbKey = omMetadataManager.getOzonePathKey(path.getVolumeId(),
                path.getBucketId(), keyInfo.getParentObjectID(), keyInfo.getFileName());
            omMetadataManager.getDirectoryTable().addCacheEntry(new CacheKey<>(ozoneDbKey),
                CacheValue.get(context.getIndex()));
            volBucketInfoMap.putIfAbsent(volBucketPair, omBucketInfo);
          }
        }

        for (OzoneManagerProtocolProtos.KeyInfo key :
            path.getDeletedSubFilesList()) {
          OmKeyInfo keyInfo = OmKeyInfo.getFromProtobuf(key);
          String volumeName = keyInfo.getVolumeName();
          String bucketName = keyInfo.getBucketName();
          Pair<String, String> volBucketPair = Pair.of(volumeName, bucketName);
          if (!lockSet.contains(volBucketPair)) {
            omMetadataManager.getLock().acquireWriteLock(BUCKET_LOCK,
                volumeName, bucketName);
            lockSet.add(volBucketPair);
          }

          // If omKeyInfo has hsync metadata, delete its corresponding open key as well
          String dbOpenKey;
          String hsyncClientId = keyInfo.getMetadata().get(OzoneConsts.HSYNC_CLIENT_ID);
          if (hsyncClientId != null) {
            long parentId = keyInfo.getParentObjectID();
            dbOpenKey = omMetadataManager.getOpenFileName(path.getVolumeId(), path.getBucketId(),
                parentId, keyInfo.getFileName(), hsyncClientId);
            OmKeyInfo openKeyInfo = omMetadataManager.getOpenKeyTable(getBucketLayout()).get(dbOpenKey);
            if (openKeyInfo != null) {
              openKeyInfo.getMetadata().put(DELETED_HSYNC_KEY, "true");
              openKeyInfoMap.put(dbOpenKey, openKeyInfo);
            }
          }

          omMetrics.decNumKeys();
          numSubFilesMoved++;
          OmBucketInfo omBucketInfo = getBucketInfo(omMetadataManager,
              volumeName, bucketName);
          // bucketInfo can be null in case of delete volume or bucket
          // or key does not belong to bucket as bucket is recreated
          if (null != omBucketInfo
              && omBucketInfo.getObjectID() == path.getBucketId()) {
            omBucketInfo.incrUsedBytes(-sumBlockLengths(keyInfo));
            omBucketInfo.incrUsedNamespace(-1L);
            String ozoneDbKey = omMetadataManager.getOzonePathKey(path.getVolumeId(),
                path.getBucketId(), keyInfo.getParentObjectID(), keyInfo.getFileName());
            omMetadataManager.getFileTable().addCacheEntry(new CacheKey<>(ozoneDbKey),
                CacheValue.get(context.getIndex()));
            volBucketInfoMap.putIfAbsent(volBucketPair, omBucketInfo);
          }
        }
        if (path.hasDeletedDir()) {
          numDirsDeleted++;
        }
      }
      deletingServiceMetrics.incrNumSubDirectoriesMoved(numSubDirMoved);
      deletingServiceMetrics.incrNumSubFilesMoved(numSubFilesMoved);
      deletingServiceMetrics.incrNumDirPurged(numDirsDeleted);

      if (fromSnapshotInfo != null) {
        fromSnapshotInfo.setLastTransactionInfo(TransactionInfo.valueOf(context.getTermIndex()).toByteString());
        omMetadataManager.getSnapshotInfoTable().addCacheEntry(new CacheKey<>(fromSnapshotInfo.getTableKey()),
            CacheValue.get(context.getIndex(), fromSnapshotInfo));
      }
    } catch (IOException ex) {
      // Case of IOException for fromProtobuf will not happen
      // as this is created and send within OM
      // only case of upgrade where compatibility is broken can have
      throw new IllegalStateException(ex);
    } finally {
      lockSet.stream().forEach(e -> omMetadataManager.getLock()
          .releaseWriteLock(BUCKET_LOCK, e.getKey(),
              e.getValue()));
      for (Map.Entry<Pair<String, String>, OmBucketInfo> entry :
          volBucketInfoMap.entrySet()) {
        entry.setValue(entry.getValue().copyObject());
      }
    }

    return new OMDirectoriesPurgeResponseWithFSO(
        omResponse.build(), purgeRequests,
        getBucketLayout(), volBucketInfoMap, fromSnapshotInfo, openKeyInfoMap);
  }