in hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/tenant/OMTenantCreateRequest.java [208:383]
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, ExecutionContext context) {
final long transactionLogIndex = context.getIndex();
final OMMultiTenantManager multiTenantManager =
ozoneManager.getMultiTenantManager();
final OMMetrics omMetrics = ozoneManager.getMetrics();
omMetrics.incNumTenantCreates();
omMetrics.incNumVolumeCreates();
OMClientResponse omClientResponse = null;
final OMResponse.Builder omResponse =
OmResponseUtil.getOMResponseBuilder(getOmRequest());
OmVolumeArgs omVolumeArgs = null;
boolean acquiredVolumeLock = false;
boolean acquiredUserLock = false;
final String owner = getOmRequest().getUserInfo().getUserName();
Map<String, String> auditMap = new HashMap<>();
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
final CreateTenantRequest request = getOmRequest().getCreateTenantRequest();
final String tenantId = request.getTenantId();
final String userRoleName = request.getUserRoleName();
final String adminRoleName = request.getAdminRoleName();
final boolean forceCreationWhenVolumeExists =
request.getForceCreationWhenVolumeExists();
final VolumeInfo volumeInfo =
getOmRequest().getCreateVolumeRequest().getVolumeInfo();
final String volumeName = volumeInfo.getVolume();
Preconditions.checkNotNull(volumeName);
Preconditions.checkState(request.getVolumeName().equals(volumeName),
"CreateTenantRequest's volumeName value should match VolumeInfo's");
final String dbVolumeKey = omMetadataManager.getVolumeKey(volumeName);
Exception exception = null;
try {
// Check ACL: requires volume CREATE permission.
if (ozoneManager.getAclsEnabled()) {
checkAcls(ozoneManager, OzoneObj.ResourceType.VOLUME,
OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.CREATE,
tenantId, null, null);
}
mergeOmLockDetails(omMetadataManager.getLock().acquireWriteLock(
VOLUME_LOCK, volumeName));
acquiredVolumeLock = getOmLockDetails().isLockAcquired();
boolean skipVolumeCreation = false;
// Check volume existence
if (omMetadataManager.getVolumeTable().isExist(dbVolumeKey)) {
LOG.debug("volume: '{}' already exists", volumeName);
if (forceCreationWhenVolumeExists) {
LOG.warn("forceCreationWhenVolumeExists = true. Resuming "
+ "tenant creation despite volume '{}' existence", volumeName);
skipVolumeCreation = true;
} else {
// forceCreationWhenVolumeExists is false, throw
throw new OMException("Volume already exists", VOLUME_ALREADY_EXISTS);
}
}
mergeOmLockDetails(omMetadataManager.getLock().acquireWriteLock(
USER_LOCK, owner));
acquiredUserLock = getOmLockDetails().isLockAcquired();
PersistedUserVolumeInfo volumeList = null;
if (!skipVolumeCreation) {
// Create volume. TODO: dedup OMVolumeCreateRequest
omVolumeArgs = OmVolumeArgs.getFromProtobuf(volumeInfo);
omVolumeArgs.setQuotaInBytes(OzoneConsts.QUOTA_RESET);
omVolumeArgs.setQuotaInNamespace(OzoneConsts.QUOTA_RESET);
omVolumeArgs.setObjectID(
ozoneManager.getObjectIdFromTxId(transactionLogIndex));
omVolumeArgs.setUpdateID(transactionLogIndex);
omVolumeArgs.incRefCount();
// Remove this check when vol ref count is also used by other features
Preconditions.checkState(omVolumeArgs.getRefCount() == 1L,
"refCount should have been set to 1");
final String dbUserKey = omMetadataManager.getUserKey(owner);
volumeList = omMetadataManager.getUserTable().get(dbUserKey);
volumeList = addVolumeToOwnerList(volumeList, volumeName, owner,
ozoneManager.getMaxUserVolumeCount(), transactionLogIndex);
createVolume(omMetadataManager, omVolumeArgs, volumeList, dbVolumeKey,
dbUserKey, transactionLogIndex);
LOG.debug("volume: '{}' successfully created", dbVolumeKey);
} else {
LOG.info("Skipped volume '{}' creation. "
+ "Will only increment volume refCount", volumeName);
omVolumeArgs = getVolumeInfo(omMetadataManager, volumeName);
omVolumeArgs.incRefCount();
// Remove this check when vol ref count is also used by other features
Preconditions.checkState(omVolumeArgs.getRefCount() == 1L,
"refCount should have been set to 1");
omMetadataManager.getVolumeTable().addCacheEntry(
new CacheKey<>(omMetadataManager.getVolumeKey(volumeName)),
CacheValue.get(transactionLogIndex, omVolumeArgs));
}
// Audit
auditMap = omVolumeArgs.toAuditMap();
// Check tenant existence in tenantStateTable
if (omMetadataManager.getTenantStateTable().isExist(tenantId)) {
LOG.debug("tenant: '{}' already exists", tenantId);
throw new OMException("Tenant already exists", TENANT_ALREADY_EXISTS);
}
// Create tenant
// Add to tenantStateTable. Redundant assignment for clarity
final String bucketNamespaceName = volumeName;
// Populate policy ID list
final String bucketNamespacePolicyName =
OMMultiTenantManager.getDefaultBucketNamespacePolicyName(tenantId);
final String bucketPolicyName =
OMMultiTenantManager.getDefaultBucketPolicyName(tenantId);
final OmDBTenantState omDBTenantState = new OmDBTenantState(
tenantId, bucketNamespaceName, userRoleName, adminRoleName,
bucketNamespacePolicyName, bucketPolicyName);
omMetadataManager.getTenantStateTable().addCacheEntry(
new CacheKey<>(tenantId),
CacheValue.get(transactionLogIndex, omDBTenantState));
// Update tenant cache
multiTenantManager.getCacheOp().createTenant(
tenantId, userRoleName, adminRoleName);
omResponse.setCreateTenantResponse(
CreateTenantResponse.newBuilder()
.build());
omClientResponse = new OMTenantCreateResponse(omResponse.build(),
omVolumeArgs, volumeList, omDBTenantState);
} catch (IOException | InvalidPathException ex) {
exception = ex;
omClientResponse = new OMTenantCreateResponse(
createErrorOMResponse(omResponse, exception));
} finally {
if (acquiredUserLock) {
mergeOmLockDetails(
omMetadataManager.getLock().releaseWriteLock(USER_LOCK, owner));
}
if (acquiredVolumeLock) {
mergeOmLockDetails(
omMetadataManager.getLock().releaseWriteLock(VOLUME_LOCK,
volumeName));
}
// Release authorizer write lock
multiTenantManager.getAuthorizerLock().unlockWriteInOMRequest();
if (omClientResponse != null) {
omClientResponse.setOmLockDetails(getOmLockDetails());
}
}
// Perform audit logging
auditMap.put(OzoneConsts.TENANT, tenantId);
// Note auditMap contains volume creation info
markForAudit(ozoneManager.getAuditLogger(),
buildAuditMessage(OMAction.CREATE_TENANT, auditMap, exception,
getOmRequest().getUserInfo()));
if (exception == null) {
LOG.info("Created tenant '{}' and volume '{}'", tenantId, volumeName);
omMetrics.incNumTenants();
omMetrics.incNumVolumes();
} else {
LOG.error("Failed to create tenant '{}'", tenantId, exception);
omMetrics.incNumTenantCreateFails();
}
return omClientResponse;
}