diff --git a/lib/api/objectDelete.js b/lib/api/objectDelete.js index d2045821bd..b8ec7fb168 100644 --- a/lib/api/objectDelete.js +++ b/lib/api/objectDelete.js @@ -51,6 +51,13 @@ function objectDeleteInternal(authInfo, request, log, isExpiration, cb) { const reqVersionId = decodedVidResult; const hasGovernanceBypass = hasGovernanceBypassHeader(request.headers); + // Reassign a specific apiMethod, as monitoring can rely on the + // type of cloudserver instance to determine it comes from Backbeat routes. + // This is also needed for quota evaluation, where "routeBackbeat" cannot + // be used for different operations, such as putObject + // eslint-disable-next-line no-param-reassign + request.apiMethod = reqVersionId ? 'objectDeleteVersion' : 'deleteObject'; + const valParams = { authInfo, bucketName, diff --git a/tests/unit/api/apiUtils/quotas/quotaUtils.js b/tests/unit/api/apiUtils/quotas/quotaUtils.js index cdb4352ab9..81a286d96a 100644 --- a/tests/unit/api/apiUtils/quotas/quotaUtils.js +++ b/tests/unit/api/apiUtils/quotas/quotaUtils.js @@ -114,6 +114,32 @@ describe('validateQuotas (buckets)', () => { }); }); + it('should not return QuotaExceeded if quotas are exceeded but operation is creating a delete marker', done => { + const result1 = { + bytesTotal: 150, + }; + const result2 = { + bytesTotal: 120, + }; + QuotaService._getLatestMetricsCallback.yields(null, result1); + QuotaService._getLatestMetricsCallback.onCall(1).yields(null, result2); + + validateQuotas(request, mockBucket, {}, ['objectDelete'], 'objectDelete', 0, false, mockLog, err => { + assert.ifError(err); + assert.strictEqual(QuotaService._getLatestMetricsCallback.calledOnce, true); + assert.strictEqual(QuotaService._getLatestMetricsCallback.calledWith( + 'bucket', + 'bucketName_1640995200000', + null, + { + action: 'objectDelete', + inflight: 0, + } + ), true); + done(); + }); + }); + it('should not return QuotaExceeded if the quotas are exceeded but operation is a delete', done => { const result1 = { bytesTotal: 150, @@ -140,6 +166,32 @@ describe('validateQuotas (buckets)', () => { }); }); + it('should not return QuotaExceeded if the quotas are exceeded but operation is a delete with version', done => { + const result1 = { + bytesTotal: 150, + }; + const result2 = { + bytesTotal: 120, + }; + QuotaService._getLatestMetricsCallback.yields(null, result1); + QuotaService._getLatestMetricsCallback.onCall(1).yields(null, result2); + + validateQuotas(request, mockBucket, {}, ['objectDelete'], 'objectDeleteVersion', -50, false, mockLog, err => { + assert.ifError(err); + assert.strictEqual(QuotaService._getLatestMetricsCallback.calledOnce, true); + assert.strictEqual(QuotaService._getLatestMetricsCallback.calledWith( + 'bucket', + 'bucketName_1640995200000', + null, + { + action: 'objectDelete', + inflight: -50, + } + ), true); + done(); + }); + }); + it('should decrease the inflights by deleting data, and go below 0 to unblock operations', done => { const result1 = { bytesTotal: 150,