private async Task DeleteSystemDocumentsByIdAsync <T>(string id, string partitionKey, string eTag, CancellationToken cancellationToken) { EnsureArg.IsNotNull(id, KnownDocumentProperties.Id); EnsureArg.IsNotNullOrEmpty(partitionKey, nameof(partitionKey)); try { StoredProcedureResponse <IList <string> > response; string typeName = typeof(T).Name; _logger.LogDebug($"Obliterating {id} for type {typeName}"); switch (typeName) { case "IdentityProvider": response = await _retryExceptionPolicyFactory.CreateRetryPolicy().ExecuteAsync( async() => await _hardDeleteIdentityProvider.Execute( _documentClient.Value, _collectionUri, id, eTag), cancellationToken); break; case "Role": response = await _retryExceptionPolicyFactory.CreateRetryPolicy().ExecuteAsync( async() => await _hardDeleteRole.Execute( _documentClient.Value, _collectionUri, id, eTag), cancellationToken); break; default: throw new InvalidControlPlaneTypeForDeleteException(typeName); } _logger.LogDebug($"Hard-deleted {response.Response.Count} documents, which consumed {response.RequestCharge} RUs. The list of hard-deleted documents: {string.Join(", ", response.Response)}."); } catch (DocumentClientException dce) { if (dce.StatusCode == HttpStatusCode.TooManyRequests) { throw new RequestRateExceededException(dce.RetryAfter); } _logger.LogError(dce, "Unhandled Document Client Exception"); throw; } }
public async Task <ExportJobOutcome> UpdateExportJobAsync(ExportJobRecord jobRecord, WeakETag eTag, CancellationToken cancellationToken) { EnsureArg.IsNotNull(jobRecord, nameof(jobRecord)); var cosmosExportJob = new CosmosExportJobRecordWrapper(jobRecord); var requestOptions = new RequestOptions() { PartitionKey = new PartitionKey(CosmosDbExportConstants.ExportJobPartitionKey), }; // Create access condition so that record is replaced only if eTag matches. if (eTag != null) { requestOptions.AccessCondition = new AccessCondition() { Type = AccessConditionType.IfMatch, Condition = eTag.VersionId, }; } try { ResourceResponse <Document> replaceResult = await _retryExceptionPolicyFactory.CreateRetryPolicy().ExecuteAsync( () => _documentClientScope.Value.ReplaceDocumentAsync( UriFactory.CreateDocumentUri(DatabaseId, CollectionId, jobRecord.Id), cosmosExportJob, requestOptions, cancellationToken)); var latestETag = replaceResult.Resource.ETag; return(new ExportJobOutcome(jobRecord, WeakETag.FromVersionId(latestETag))); } catch (DocumentClientException dce) { if (dce.StatusCode == HttpStatusCode.TooManyRequests) { throw new RequestRateExceededException(dce.RetryAfter); } else if (dce.StatusCode == HttpStatusCode.PreconditionFailed) { throw new JobConflictException(); } else if (dce.StatusCode == HttpStatusCode.NotFound) { throw new JobNotFoundException(string.Format(Core.Resources.JobNotFound, jobRecord.Id)); } _logger.LogError(dce, "Failed to update an export job."); throw; } }
public async Task <ExportJobOutcome> UpdateExportJobAsync(ExportJobRecord jobRecord, WeakETag eTag, CancellationToken cancellationToken) { EnsureArg.IsNotNull(jobRecord, nameof(jobRecord)); var cosmosExportJob = new CosmosExportJobRecordWrapper(jobRecord); var requestOptions = new ItemRequestOptions(); // Create access condition so that record is replaced only if eTag matches. if (eTag != null) { requestOptions.IfMatchEtag = eTag.VersionId; } try { var replaceResult = await _retryExceptionPolicyFactory.CreateRetryPolicy().ExecuteAsync( () => _containerScope.Value.ReplaceItemAsync( cosmosExportJob, jobRecord.Id, new PartitionKey(CosmosDbExportConstants.ExportJobPartitionKey), cancellationToken: cancellationToken, requestOptions: requestOptions)); var latestETag = replaceResult.Resource.ETag; return(new ExportJobOutcome(jobRecord, WeakETag.FromVersionId(latestETag))); } catch (CosmosException dce) { if (dce.IsRequestRateExceeded()) { throw; } else if (dce.StatusCode == HttpStatusCode.PreconditionFailed) { throw new JobConflictException(); } else if (dce.StatusCode == HttpStatusCode.NotFound) { throw new JobNotFoundException(string.Format(Core.Resources.JobNotFound, jobRecord.Id)); } _logger.LogError(dce, "Failed to update an export job."); throw; } }
public async Task <IReadOnlyCollection <ExportJobOutcome> > AcquireExportJobsAsync( ushort maximumNumberOfConcurrentJobsAllowed, TimeSpan jobHeartbeatTimeoutThreshold, CancellationToken cancellationToken) { try { StoredProcedureResponse <IReadOnlyCollection <CosmosExportJobRecordWrapper> > response = await _retryExceptionPolicyFactory.CreateRetryPolicy().ExecuteAsync( async ct => await _acquireExportJobs.ExecuteAsync( _documentClientScope.Value, CollectionUri, maximumNumberOfConcurrentJobsAllowed, (ushort)jobHeartbeatTimeoutThreshold.TotalSeconds, ct), cancellationToken); return(response.Response.Select(wrapper => new ExportJobOutcome(wrapper.JobRecord, WeakETag.FromVersionId(wrapper.ETag))).ToList()); } catch (DocumentClientException dce) { if (dce.GetSubStatusCode() == HttpStatusCode.RequestEntityTooLarge) { throw new RequestRateExceededException(null); } _logger.LogError(dce, "Failed to acquire export jobs."); throw; } }