public OMClientResponse validateAndUpdateCache()

in hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyCreateRequestWithFSO.java [66:235]


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

    OzoneManagerProtocolProtos.CreateKeyRequest createKeyRequest =
            getOmRequest().getCreateKeyRequest();

    OzoneManagerProtocolProtos.KeyArgs keyArgs = createKeyRequest.getKeyArgs();
    Map<String, String> auditMap = buildKeyArgsAuditMap(keyArgs);

    String volumeName = keyArgs.getVolumeName();
    String bucketName = keyArgs.getBucketName();
    String keyName = keyArgs.getKeyName();

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

    OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
    OmBucketInfo omBucketInfo = null;
    final List<OmKeyLocationInfo> locations = new ArrayList<>();

    boolean acquireLock = false;
    OMClientResponse omClientResponse = null;
    OzoneManagerProtocolProtos.OMResponse.Builder omResponse =
            OmResponseUtil.getOMResponseBuilder(getOmRequest());
    Exception exception = null;
    Result result;
    List<OmDirectoryInfo> missingParentInfos;
    int numKeysCreated = 0;
    try {
      mergeOmLockDetails(omMetadataManager.getLock()
          .acquireWriteLock(BUCKET_LOCK, volumeName, bucketName));
      acquireLock = getOmLockDetails().isLockAcquired();
      validateBucketAndVolume(omMetadataManager, volumeName, bucketName);

      final long volumeId = omMetadataManager.getVolumeTable()
              .get(omMetadataManager.getVolumeKey(volumeName)).getObjectID();
      final long bucketId = omMetadataManager.getBucketTable()
              .get(omMetadataManager.getBucketKey(volumeName, bucketName))
              .getObjectID();

      OmKeyInfo dbFileInfo = null;

      OMFileRequest.OMPathInfoWithFSO pathInfoFSO =
              OMFileRequest.verifyDirectoryKeysInPath(omMetadataManager,
                      volumeName, bucketName, keyName, Paths.get(keyName));

      if (pathInfoFSO.getDirectoryResult()
              == OMFileRequest.OMDirectoryResult.FILE_EXISTS) {
        String dbFileKey = omMetadataManager.getOzonePathKey(volumeId, bucketId,
                pathInfoFSO.getLastKnownParentId(),
                pathInfoFSO.getLeafNodeName());
        dbFileInfo = OMFileRequest.getOmKeyInfoFromFileTable(false,
                omMetadataManager, dbFileKey, keyName);
      }
      validateAtomicRewrite(dbFileInfo, keyArgs);

      // Check if a file or directory exists with same key name.
      if (pathInfoFSO.getDirectoryResult() == DIRECTORY_EXISTS) {
        throw new OMException("Cannot write to "
            + "directory. createIntermediateDirs behavior is enabled and "
            + "hence / has special interpretation: " + keyName, NOT_A_FILE);
      } else if (pathInfoFSO.getDirectoryResult()
          == FILE_EXISTS_IN_GIVENPATH) {
        throw new OMException("Can not create file: " + keyName
            + " as there is already file in the given path", NOT_A_FILE);
      }

      // do open key
      OmBucketInfo bucketInfo = omMetadataManager.getBucketTable().get(
              omMetadataManager.getBucketKey(volumeName, bucketName));

      // add all missing parents to dir table
      missingParentInfos = getAllMissingParentDirInfo(
          ozoneManager, keyArgs, bucketInfo, pathInfoFSO, trxnLogIndex);

      // total number of keys created.
      numKeysCreated = missingParentInfos.size();

      final ReplicationConfig repConfig = OzoneConfigUtil
          .resolveReplicationConfigPreference(keyArgs.getType(),
              keyArgs.getFactor(), keyArgs.getEcReplicationConfig(),
              bucketInfo.getDefaultReplicationConfig(),
              ozoneManager);

      OmKeyInfo omFileInfo = prepareFileInfo(omMetadataManager, keyArgs,
              dbFileInfo, keyArgs.getDataSize(), locations,
              getFileEncryptionInfo(keyArgs), ozoneManager.getPrefixManager(),
              bucketInfo, pathInfoFSO, trxnLogIndex,
              pathInfoFSO.getLeafNodeObjectId(),
              repConfig, ozoneManager.getConfiguration());

      validateEncryptionKeyInfo(bucketInfo, keyArgs);

      long openVersion = omFileInfo.getLatestVersionLocations().getVersion();
      long clientID = createKeyRequest.getClientID();
      String dbOpenFileName = omMetadataManager
          .getOpenFileName(volumeId, bucketId,
                  pathInfoFSO.getLastKnownParentId(),
                  pathInfoFSO.getLeafNodeName(), clientID);

      // Append new blocks
      List<OmKeyLocationInfo> newLocationList = keyArgs.getKeyLocationsList()
              .stream().map(OmKeyLocationInfo::getFromProtobuf)
              .collect(Collectors.toList());
      omFileInfo.appendNewBlocks(newLocationList, false);

      omBucketInfo = getBucketInfo(omMetadataManager, volumeName, bucketName);
      // check bucket and volume quota
      long preAllocatedSpace =
          newLocationList.size() * ozoneManager.getScmBlockSize() * repConfig
              .getRequiredNodes();
      checkBucketQuotaInBytes(omMetadataManager, omBucketInfo,
          preAllocatedSpace);
      checkBucketQuotaInNamespace(omBucketInfo, numKeysCreated + 1L);
      omBucketInfo.incrUsedNamespace(numKeysCreated);

      // Add to cache entry can be done outside of lock for this openKey.
      // Even if bucket gets deleted, when commitKey we shall identify if
      // bucket gets deleted.
      OMFileRequest.addOpenFileTableCacheEntry(omMetadataManager,
              dbOpenFileName, omFileInfo, pathInfoFSO.getLeafNodeName(), keyName,
              trxnLogIndex);

      // Add cache entries for the prefix directories.
      // Skip adding for the file key itself, until Key Commit.
      OMFileRequest.addDirectoryTableCacheEntries(omMetadataManager,
              volumeId, bucketId, trxnLogIndex,
              missingParentInfos, null);

      // Prepare response. Sets user given full key name in the 'keyName'
      // attribute in response object.
      int clientVersion = getOmRequest().getVersion();
      omResponse.setCreateKeyResponse(CreateKeyResponse.newBuilder()
              .setKeyInfo(omFileInfo.getNetworkProtobuf(keyName, clientVersion,
                  keyArgs.getLatestVersionLocation()))
              .setID(clientID)
              .setOpenVersion(openVersion).build())
              .setCmdType(Type.CreateKey);
      omClientResponse = new OMKeyCreateResponseWithFSO(omResponse.build(),
              omFileInfo, missingParentInfos, clientID,
              omBucketInfo.copyObject(), volumeId);

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

    // Audit Log outside the lock
    markForAudit(ozoneManager.getAuditLogger(), buildAuditMessage(
            OMAction.ALLOCATE_KEY, auditMap, exception,
            getOmRequest().getUserInfo()));

    logResult(createKeyRequest, omMetrics, exception, result,
            numKeysCreated);

    return omClientResponse;
  }