use of org.apache.hadoop.ozone.om.response.file.OMFileCreateResponseWithFSO in project ozone by apache.
the class OMFileCreateRequestWithFSO method validateAndUpdateCache.
@Override
@SuppressWarnings("methodlength")
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, long trxnLogIndex, OzoneManagerDoubleBufferHelper omDoubleBufferHelper) {
CreateFileRequest createFileRequest = getOmRequest().getCreateFileRequest();
KeyArgs keyArgs = createFileRequest.getKeyArgs();
Map<String, String> auditMap = buildKeyArgsAuditMap(keyArgs);
String volumeName = keyArgs.getVolumeName();
String bucketName = keyArgs.getBucketName();
String keyName = keyArgs.getKeyName();
// if isRecursive is true, file would be created even if parent
// directories does not exist.
boolean isRecursive = createFileRequest.getIsRecursive();
if (LOG.isDebugEnabled()) {
LOG.debug("File create for : " + volumeName + "/" + bucketName + "/" + keyName + ":" + isRecursive);
}
// if isOverWrite is true, file would be over written.
boolean isOverWrite = createFileRequest.getIsOverwrite();
OMMetrics omMetrics = ozoneManager.getMetrics();
omMetrics.incNumCreateFile();
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
boolean acquiredLock = false;
OmBucketInfo omBucketInfo = null;
final List<OmKeyLocationInfo> locations = new ArrayList<>();
List<OmDirectoryInfo> missingParentInfos;
int numKeysCreated = 0;
OMClientResponse omClientResponse = null;
OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(getOmRequest());
IOException exception = null;
Result result = null;
try {
keyArgs = resolveBucketLink(ozoneManager, keyArgs, auditMap);
volumeName = keyArgs.getVolumeName();
bucketName = keyArgs.getBucketName();
if (keyName.length() == 0) {
// Check if this is the root of the filesystem.
throw new OMException("Can not write to directory: " + keyName, OMException.ResultCodes.NOT_A_FILE);
}
// check Acl
checkKeyAcls(ozoneManager, volumeName, bucketName, keyName, IAccessAuthorizer.ACLType.CREATE, OzoneObj.ResourceType.KEY);
// acquire lock
acquiredLock = omMetadataManager.getLock().acquireWriteLock(BUCKET_LOCK, volumeName, bucketName);
validateBucketAndVolume(omMetadataManager, volumeName, bucketName);
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(pathInfoFSO.getLastKnownParentId(), pathInfoFSO.getLeafNodeName());
dbFileInfo = OMFileRequest.getOmKeyInfoFromFileTable(false, omMetadataManager, dbFileKey, keyName);
}
// check if the file or directory already existed in OM
checkDirectoryResult(keyName, isOverWrite, pathInfoFSO.getDirectoryResult());
if (!isRecursive) {
checkAllParentsExist(keyArgs, pathInfoFSO);
}
// add all missing parents to dir table
missingParentInfos = OMDirectoryCreateRequestWithFSO.getAllMissingParentDirInfo(ozoneManager, keyArgs, pathInfoFSO, trxnLogIndex);
// total number of keys created.
numKeysCreated = missingParentInfos.size();
// do open key
OmBucketInfo bucketInfo = omMetadataManager.getBucketTable().get(omMetadataManager.getBucketKey(volumeName, bucketName));
OmKeyInfo omFileInfo = prepareFileInfo(omMetadataManager, keyArgs, dbFileInfo, keyArgs.getDataSize(), locations, getFileEncryptionInfo(keyArgs), ozoneManager.getPrefixManager(), bucketInfo, pathInfoFSO, trxnLogIndex, pathInfoFSO.getLeafNodeObjectId(), ozoneManager.isRatisEnabled());
long openVersion = omFileInfo.getLatestVersionLocations().getVersion();
long clientID = createFileRequest.getClientID();
String dbOpenFileName = omMetadataManager.getOpenFileName(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() * omFileInfo.getReplicationConfig().getRequiredNodes();
checkBucketQuotaInBytes(omBucketInfo, preAllocatedSpace);
checkBucketQuotaInNamespace(omBucketInfo, 1L);
// 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(), trxnLogIndex);
// Add cache entries for the prefix directories.
// Skip adding for the file key itself, until Key Commit.
OMFileRequest.addDirectoryTableCacheEntries(omMetadataManager, Optional.absent(), Optional.of(missingParentInfos), trxnLogIndex);
omBucketInfo.incrUsedBytes(preAllocatedSpace);
// Update namespace quota
omBucketInfo.incrUsedNamespace(1L);
// Prepare response. Sets user given full key name in the 'keyName'
// attribute in response object.
int clientVersion = getOmRequest().getVersion();
omResponse.setCreateFileResponse(CreateFileResponse.newBuilder().setKeyInfo(omFileInfo.getNetworkProtobuf(keyName, clientVersion, keyArgs.getLatestVersionLocation())).setID(clientID).setOpenVersion(openVersion).build()).setCmdType(Type.CreateFile);
omClientResponse = new OMFileCreateResponseWithFSO(omResponse.build(), omFileInfo, missingParentInfos, clientID, omBucketInfo.copyObject());
result = Result.SUCCESS;
} catch (IOException ex) {
result = Result.FAILURE;
exception = ex;
omMetrics.incNumCreateFileFails();
omResponse.setCmdType(Type.CreateFile);
omClientResponse = new OMFileCreateResponseWithFSO(createErrorOMResponse(omResponse, exception), getBucketLayout());
} finally {
addResponseToDoubleBuffer(trxnLogIndex, omClientResponse, omDoubleBufferHelper);
if (acquiredLock) {
omMetadataManager.getLock().releaseWriteLock(BUCKET_LOCK, volumeName, bucketName);
}
}
// Audit Log outside the lock
auditLog(ozoneManager.getAuditLogger(), buildAuditMessage(OMAction.CREATE_FILE, auditMap, exception, getOmRequest().getUserInfo()));
switch(result) {
case SUCCESS:
omMetrics.incNumKeys(numKeysCreated);
LOG.debug("File created. Volume:{}, Bucket:{}, Key:{}", volumeName, bucketName, keyName);
break;
case FAILURE:
LOG.error("File create failed. Volume:{}, Bucket:{}, Key:{}.", volumeName, bucketName, keyName, exception);
break;
default:
LOG.error("Unrecognized Result for OMFileCreateRequest: {}", createFileRequest);
}
return omClientResponse;
}
Aggregations