use of org.apache.hadoop.ozone.om.response.bucket.OMBucketDeleteResponse in project ozone by apache.
the class TestOzoneManagerDoubleBufferWithOMResponse method doMixTransactions.
/**
* This method add's a mix of createBucket/DeleteBucket responses to double
* buffer. Total number of responses added is specified by bucketCount.
*/
private void doMixTransactions(String volumeName, int bucketCount, Queue<OMBucketDeleteResponse> deleteBucketQueue, Queue<OMBucketCreateResponse> bucketQueue) {
for (int i = 0; i < bucketCount; i++) {
String bucketName = UUID.randomUUID().toString();
long transactionID = trxId.incrementAndGet();
OMBucketCreateResponse omBucketCreateResponse = createBucket(volumeName, bucketName, transactionID);
// For every 2 transactions have a deleted bucket.
if (i % 2 == 0) {
OMBucketDeleteResponse omBucketDeleteResponse = (OMBucketDeleteResponse) deleteBucket(volumeName, bucketName, trxId.incrementAndGet());
deleteBucketQueue.add(omBucketDeleteResponse);
} else {
bucketQueue.add(omBucketCreateResponse);
}
}
}
use of org.apache.hadoop.ozone.om.response.bucket.OMBucketDeleteResponse in project ozone by apache.
the class TestOzoneManagerDoubleBufferWithOMResponse method testDoubleBufferWithMixOfTransactions.
/**
* This test first creates a volume, and then does a mix of transactions
* like create/delete buckets and add them to double buffer. Then it
* verifies OM DB entries are matching with actual responses added to
* double buffer or not.
*/
@Test
public void testDoubleBufferWithMixOfTransactions() throws Exception {
// This test checks count, data in table is correct or not.
Queue<OMBucketCreateResponse> bucketQueue = new ConcurrentLinkedQueue<>();
Queue<OMBucketDeleteResponse> deleteBucketQueue = new ConcurrentLinkedQueue<>();
String volumeName = UUID.randomUUID().toString();
OMVolumeCreateResponse omVolumeCreateResponse = (OMVolumeCreateResponse) createVolume(volumeName, trxId.incrementAndGet());
int bucketCount = 10;
doMixTransactions(volumeName, bucketCount, deleteBucketQueue, bucketQueue);
// As for every 2 transactions of create bucket we add deleted bucket.
final int deleteCount = 5;
// We are doing +1 for volume transaction.
GenericTestUtils.waitFor(() -> doubleBuffer.getFlushedTransactionCount() == (bucketCount + deleteCount + 1), 100, 120000);
Assert.assertEquals(1, omMetadataManager.countRowsInTable(omMetadataManager.getVolumeTable()));
Assert.assertEquals(5, omMetadataManager.countRowsInTable(omMetadataManager.getBucketTable()));
// Now after this in our DB we should have 5 buckets and one volume
checkVolume(volumeName, omVolumeCreateResponse);
checkCreateBuckets(bucketQueue);
checkDeletedBuckets(deleteBucketQueue);
// Check lastAppliedIndex is updated correctly or not.
GenericTestUtils.waitFor(() -> bucketCount + deleteCount + 1 == lastAppliedIndex, 100, 30000);
TransactionInfo transactionInfo = omMetadataManager.getTransactionInfoTable().get(TRANSACTION_INFO_KEY);
assertNotNull(transactionInfo);
Assert.assertEquals(lastAppliedIndex, transactionInfo.getTransactionIndex());
Assert.assertEquals(term, transactionInfo.getTerm());
}
use of org.apache.hadoop.ozone.om.response.bucket.OMBucketDeleteResponse in project ozone by apache.
the class OMBucketDeleteRequest method validateAndUpdateCache.
@Override
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, long transactionLogIndex, OzoneManagerDoubleBufferHelper ozoneManagerDoubleBufferHelper) {
OMMetrics omMetrics = ozoneManager.getMetrics();
omMetrics.incNumBucketDeletes();
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
OMRequest omRequest = getOmRequest();
DeleteBucketRequest deleteBucketRequest = omRequest.getDeleteBucketRequest();
String volumeName = deleteBucketRequest.getVolumeName();
String bucketName = deleteBucketRequest.getBucketName();
// Generate end user response
OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(getOmRequest());
AuditLogger auditLogger = ozoneManager.getAuditLogger();
Map<String, String> auditMap = buildVolumeAuditMap(volumeName);
auditMap.put(OzoneConsts.BUCKET, bucketName);
OzoneManagerProtocolProtos.UserInfo userInfo = getOmRequest().getUserInfo();
IOException exception = null;
boolean acquiredBucketLock = false, acquiredVolumeLock = false;
boolean success = true;
OMClientResponse omClientResponse = null;
try {
// check Acl
if (ozoneManager.getAclsEnabled()) {
checkAcls(ozoneManager, OzoneObj.ResourceType.BUCKET, OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.DELETE, volumeName, bucketName, null);
}
// acquire lock
acquiredVolumeLock = omMetadataManager.getLock().acquireReadLock(VOLUME_LOCK, volumeName);
acquiredBucketLock = omMetadataManager.getLock().acquireWriteLock(BUCKET_LOCK, volumeName, bucketName);
// No need to check volume exists here, as bucket cannot be created
// with out volume creation. Check if bucket exists
String bucketKey = omMetadataManager.getBucketKey(volumeName, bucketName);
OmBucketInfo omBucketInfo = omMetadataManager.getBucketTable().get(bucketKey);
if (omBucketInfo == null) {
LOG.debug("bucket: {} not found ", bucketName);
throw new OMException("Bucket not exists", BUCKET_NOT_FOUND);
}
// Check if bucket is empty
if (!omMetadataManager.isBucketEmpty(volumeName, bucketName)) {
LOG.debug("bucket: {} is not empty ", bucketName);
throw new OMException("Bucket is not empty", OMException.ResultCodes.BUCKET_NOT_EMPTY);
}
if (omBucketInfo.getBucketLayout().isFileSystemOptimized()) {
omMetrics.incNumFSOBucketDeletes();
}
omMetrics.decNumBuckets();
// Update table cache.
omMetadataManager.getBucketTable().addCacheEntry(new CacheKey<>(bucketKey), new CacheValue<>(Optional.absent(), transactionLogIndex));
omResponse.setDeleteBucketResponse(DeleteBucketResponse.newBuilder().build());
// update used namespace for volume
String volumeKey = omMetadataManager.getVolumeKey(volumeName);
OmVolumeArgs omVolumeArgs = omMetadataManager.getVolumeTable().getReadCopy(volumeKey);
if (omVolumeArgs == null) {
throw new OMException("Volume " + volumeName + " is not found", OMException.ResultCodes.VOLUME_NOT_FOUND);
}
omVolumeArgs.incrUsedNamespace(-1L);
// Update table cache.
omMetadataManager.getVolumeTable().addCacheEntry(new CacheKey<>(volumeKey), new CacheValue<>(Optional.of(omVolumeArgs), transactionLogIndex));
// Add to double buffer.
omClientResponse = new OMBucketDeleteResponse(omResponse.build(), volumeName, bucketName, omVolumeArgs.copyObject());
} catch (IOException ex) {
success = false;
exception = ex;
omClientResponse = new OMBucketDeleteResponse(createErrorOMResponse(omResponse, exception));
} finally {
addResponseToDoubleBuffer(transactionLogIndex, omClientResponse, ozoneManagerDoubleBufferHelper);
if (acquiredBucketLock) {
omMetadataManager.getLock().releaseWriteLock(BUCKET_LOCK, volumeName, bucketName);
}
if (acquiredVolumeLock) {
omMetadataManager.getLock().releaseReadLock(VOLUME_LOCK, volumeName);
}
}
// Performing audit logging outside of the lock.
auditLog(auditLogger, buildAuditMessage(OMAction.DELETE_BUCKET, auditMap, exception, userInfo));
// return response.
if (success) {
LOG.debug("Deleted bucket:{} in volume:{}", bucketName, volumeName);
return omClientResponse;
} else {
omMetrics.incNumBucketDeleteFails();
LOG.error("Delete bucket failed for bucket:{} in volume:{}", bucketName, volumeName, exception);
return omClientResponse;
}
}
use of org.apache.hadoop.ozone.om.response.bucket.OMBucketDeleteResponse in project ozone by apache.
the class TestOzoneManagerDoubleBufferWithOMResponse method testDoubleBufferWithMixOfTransactionsParallel.
/**
* This test first creates a volume, and then does a mix of transactions
* like create/delete buckets in parallel and add to double buffer. Then it
* verifies OM DB entries are matching with actual responses added to
* double buffer or not.
*/
@Test
public void testDoubleBufferWithMixOfTransactionsParallel() throws Exception {
// This test checks count, data in table is correct or not.
Queue<OMBucketCreateResponse> bucketQueue = new ConcurrentLinkedQueue<>();
Queue<OMBucketDeleteResponse> deleteBucketQueue = new ConcurrentLinkedQueue<>();
String volumeName1 = UUID.randomUUID().toString();
OMVolumeCreateResponse omVolumeCreateResponse1 = (OMVolumeCreateResponse) createVolume(volumeName1, trxId.incrementAndGet());
String volumeName2 = UUID.randomUUID().toString();
OMVolumeCreateResponse omVolumeCreateResponse2 = (OMVolumeCreateResponse) createVolume(volumeName2, trxId.incrementAndGet());
int bucketsPerVolume = 10;
Daemon daemon1 = new Daemon(() -> doMixTransactions(volumeName1, bucketsPerVolume, deleteBucketQueue, bucketQueue));
Daemon daemon2 = new Daemon(() -> doMixTransactions(volumeName2, bucketsPerVolume, deleteBucketQueue, bucketQueue));
daemon1.start();
daemon2.start();
int bucketCount = 2 * bucketsPerVolume;
// As for every 2 transactions of create bucket we add deleted bucket.
final int deleteCount = 10;
// We are doing +1 for volume transaction.
GenericTestUtils.waitFor(() -> doubleBuffer.getFlushedTransactionCount() == (bucketCount + deleteCount + 2), 100, 120000);
Assert.assertEquals(2, omMetadataManager.countRowsInTable(omMetadataManager.getVolumeTable()));
Assert.assertEquals(10, omMetadataManager.countRowsInTable(omMetadataManager.getBucketTable()));
// Now after this in our DB we should have 5 buckets and one volume
checkVolume(volumeName1, omVolumeCreateResponse1);
checkVolume(volumeName2, omVolumeCreateResponse2);
checkCreateBuckets(bucketQueue);
checkDeletedBuckets(deleteBucketQueue);
// Not checking lastAppliedIndex here, because 2 daemon threads are
// running in parallel, so lastAppliedIndex cannot be always
// total transaction count. So, just checking here whether it is less
// than total transaction count.
Assert.assertTrue(lastAppliedIndex <= bucketCount + deleteCount + 2);
}
Aggregations