Search in sources :

Example 1 with RequestOptions

use of com.microsoft.azure.cosmosdb.RequestOptions in project ambry by linkedin.

the class AzureContainerCompactorIntegrationTest method cleanup.

/**
 * Cleanup entries in the cosmos db container deletion table.
 * @throws DocumentClientException in case of any exception.
 */
private void cleanup() throws DocumentClientException {
    ConnectionPolicy connectionPolicy = new ConnectionPolicy();
    connectionPolicy.setRequestTimeoutInMillis(cloudConfig.cloudQueryRequestTimeout);
    // Note: retry decisions are made at CloudBlobStore level.  Configure Cosmos with no retries.
    RetryOptions noRetries = new RetryOptions();
    noRetries.setMaxRetryAttemptsOnThrottledRequests(0);
    connectionPolicy.setRetryOptions(noRetries);
    if (azureCloudConfig.cosmosDirectHttps) {
        logger.info("Using CosmosDB DirectHttps connection mode");
        connectionPolicy.setConnectionMode(ConnectionMode.Direct);
    }
    AsyncDocumentClient asyncDocumentClient = new AsyncDocumentClient.Builder().withServiceEndpoint(azureCloudConfig.cosmosEndpoint).withMasterKeyOrResourceToken(azureCloudConfig.cosmosKey).withConnectionPolicy(connectionPolicy).withConsistencyLevel(ConsistencyLevel.Session).build();
    Set<CosmosContainerDeletionEntry> entries = cloudDestination.getCosmosDataAccessor().getDeprecatedContainers(100);
    AtomicBoolean error = new AtomicBoolean(false);
    while (!entries.isEmpty() && !error.get()) {
        entries.stream().forEach(entry -> {
            try {
                RequestOptions requestOptions = new RequestOptions();
                requestOptions.setPartitionKey(new PartitionKey(entry.getId()));
                cloudRequestAgent.doWithRetries(() -> CosmosDataAccessor.executeCosmosAction(() -> asyncDocumentClient.deleteDocument(azureCloudConfig.cosmosDeletedContainerCollectionLink + "/docs/" + entry.getId(), requestOptions).toBlocking().single(), null), "Test Cleanup", entry.getId());
            } catch (CloudStorageException ex) {
                logger.warn("Failed to delete container deprecation entry {}. Unable to cleanup", entry);
                error.set(true);
            }
        });
        entries = cloudDestination.getCosmosDataAccessor().getDeprecatedContainers(100);
    }
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RequestOptions(com.microsoft.azure.cosmosdb.RequestOptions) CloudStorageException(com.github.ambry.cloud.CloudStorageException) RetryOptions(com.microsoft.azure.cosmosdb.RetryOptions) PartitionKey(com.microsoft.azure.cosmosdb.PartitionKey) ConnectionPolicy(com.microsoft.azure.cosmosdb.ConnectionPolicy) AsyncDocumentClient(com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient)

Example 2 with RequestOptions

use of com.microsoft.azure.cosmosdb.RequestOptions in project ambry by linkedin.

the class CosmosDataAccessor method updateContainerDeletionEntry.

/**
 * Update the container deletion entry document in the CosmosDB collection.
 * @param containerId the container id for which document is replaced.
 * @param accountId the account id for which document is replaced.
 * @param updateFields {@link BiConsumer} object to use as callback to update the required fields.
 * @return the {@link ResourceResponse} returned by the operation, if successful.
 * Returns {@Null} if the field already has the specified value.
 * @throws DocumentClientException if the record was not found or if the operation failed.
 */
ResourceResponse<Document> updateContainerDeletionEntry(short containerId, short accountId, BiConsumer<Document, AtomicBoolean> updateFields) throws DocumentClientException {
    // Read the existing record
    String id = CosmosContainerDeletionEntry.generateContainerDeletionEntryId(accountId, containerId);
    String docLink = getContainerDeletionEntryDocumentLink(id);
    RequestOptions options = getRequestOptions(id);
    ResourceResponse<Document> readResponse = executeCosmosAction(() -> asyncDocumentClient.readDocument(docLink, options).toBlocking().single(), azureMetrics.continerDeletionEntryReadTime);
    Document doc = readResponse.getResource();
    AtomicBoolean fieldsChanged = new AtomicBoolean(false);
    updateFields.accept(doc, fieldsChanged);
    if (!fieldsChanged.get()) {
        logger.debug("No change in value for container deletion entry {}", doc.toJson());
        return null;
    }
    // For testing conflict handling
    if (updateCallback != null) {
        try {
            updateCallback.call();
        } catch (Exception ex) {
            logger.error("Error in update callback", ex);
        }
    }
    // Set condition to ensure we don't clobber a concurrent update
    AccessCondition accessCondition = new AccessCondition();
    accessCondition.setCondition(doc.getETag());
    options.setAccessCondition(accessCondition);
    try {
        return executeCosmosAction(() -> asyncDocumentClient.replaceDocument(doc, options).toBlocking().single(), azureMetrics.documentUpdateTime);
    } catch (DocumentClientException e) {
        if (e.getStatusCode() == HttpConstants.StatusCodes.PRECONDITION_FAILED) {
            azureMetrics.blobUpdateConflictCount.inc();
        }
        throw e;
    }
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RequestOptions(com.microsoft.azure.cosmosdb.RequestOptions) AccessCondition(com.microsoft.azure.cosmosdb.AccessCondition) Document(com.microsoft.azure.cosmosdb.Document) DocumentClientException(com.microsoft.azure.cosmosdb.DocumentClientException) CloudStorageException(com.github.ambry.cloud.CloudStorageException) DocumentClientException(com.microsoft.azure.cosmosdb.DocumentClientException)

Example 3 with RequestOptions

use of com.microsoft.azure.cosmosdb.RequestOptions in project ambry by linkedin.

the class CosmosDataAccessor method deleteMetadata.

/**
 * Delete the blob metadata document in the CosmosDB collection, if it exists.
 * @param blobMetadata the blob metadata document to delete.
 * @return {@code true} if the record was deleted, {@code false} if it was not found.
 * @throws DocumentClientException if the operation failed.
 */
boolean deleteMetadata(CloudBlobMetadata blobMetadata) throws DocumentClientException {
    String docLink = getDocumentLink(blobMetadata.getId());
    RequestOptions options = getRequestOptions(blobMetadata.getPartitionId());
    try {
        // Note: not timing here since bulk deletions are timed.
        executeCosmosAction(() -> asyncDocumentClient.deleteDocument(docLink, options).toBlocking().single(), null);
        return true;
    } catch (DocumentClientException dex) {
        if (dex.getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) {
            // Can happen on retry
            logger.debug("Could not find metadata for blob {} to delete", blobMetadata.getId());
            return false;
        } else {
            throw dex;
        }
    }
}
Also used : RequestOptions(com.microsoft.azure.cosmosdb.RequestOptions) DocumentClientException(com.microsoft.azure.cosmosdb.DocumentClientException)

Example 4 with RequestOptions

use of com.microsoft.azure.cosmosdb.RequestOptions in project ambry by linkedin.

the class CosmosDataAccessor method getMetadataOrNull.

/**
 * Get the metadata record for a single blob.
 * @param blobId the blob to read.
 * @return the {@link CloudBlobMetadata} for the blob if it is found, otherwise null.
 * @throws DocumentClientException on any other error.
 */
CloudBlobMetadata getMetadataOrNull(BlobId blobId) throws DocumentClientException {
    String docLink = getDocumentLink(blobId.getID());
    RequestOptions options = getRequestOptions(blobId.getPartition().toPathString());
    try {
        ResourceResponse<Document> readResponse = executeCosmosAction(() -> asyncDocumentClient.readDocument(docLink, options).toBlocking().single(), azureMetrics.documentReadTime);
        return createMetadataFromDocument(readResponse.getResource());
    } catch (DocumentClientException dex) {
        if (dex.getStatusCode() == HttpConstants.StatusCodes.NOTFOUND) {
            return null;
        } else {
            throw dex;
        }
    }
}
Also used : RequestOptions(com.microsoft.azure.cosmosdb.RequestOptions) Document(com.microsoft.azure.cosmosdb.Document) DocumentClientException(com.microsoft.azure.cosmosdb.DocumentClientException)

Example 5 with RequestOptions

use of com.microsoft.azure.cosmosdb.RequestOptions in project ambry by linkedin.

the class CosmosDataAccessor method bulkDeleteMetadata.

/**
 * Delete the blob metadata documents from CosmosDB using the BulkDelete stored procedure.
 * @param blobMetadataList the list of blob metadata documents to delete.
 * @return the number of documents deleted.
 * @throws DocumentClientException if the operation failed.
 */
private int bulkDeleteMetadata(List<CloudBlobMetadata> blobMetadataList) throws DocumentClientException {
    String partitionPath = blobMetadataList.get(0).getPartitionId();
    RequestOptions options = getRequestOptions(partitionPath);
    // stored proc link provided in config.  Test for it at startup and use if available.
    String quotedBlobIds = blobMetadataList.stream().map(metadata -> '"' + metadata.getId() + '"').collect(Collectors.joining(","));
    String query = String.format(BULK_DELETE_QUERY, quotedBlobIds);
    String sprocLink = cosmosCollectionLink + BULK_DELETE_SPROC;
    boolean more = true;
    int deleteCount = 0;
    double requestCharge = 0;
    try {
        while (more) {
            StoredProcedureResponse response = asyncDocumentClient.executeStoredProcedure(sprocLink, options, new String[] { query }).toBlocking().single();
            requestCharge += response.getRequestCharge();
            Document responseDoc = response.getResponseAsDocument();
            more = responseDoc.getBoolean(PROPERTY_CONTINUATION);
            deleteCount += responseDoc.getInt(PROPERTY_DELETED);
        }
        if (requestCharge >= requestChargeThreshold) {
            logger.info("Bulk delete partition {} request charge {} for {} records", partitionPath, requestCharge, deleteCount);
        }
        return deleteCount;
    } catch (RuntimeException rex) {
        if (rex.getCause() instanceof DocumentClientException) {
            throw (DocumentClientException) rex.getCause();
        } else {
            throw rex;
        }
    }
}
Also used : HttpURLConnection(java.net.HttpURLConnection) SqlParameterCollection(com.microsoft.azure.cosmosdb.SqlParameterCollection) ConnectionMode(com.microsoft.azure.cosmosdb.ConnectionMode) DocumentClientException(com.microsoft.azure.cosmosdb.DocumentClientException) Date(java.util.Date) LoggerFactory(org.slf4j.LoggerFactory) VcrMetrics(com.github.ambry.cloud.VcrMetrics) ConsistencyLevel(com.microsoft.azure.cosmosdb.ConsistencyLevel) FeedResponse(com.microsoft.azure.cosmosdb.FeedResponse) JSONObject(org.json.JSONObject) Map(java.util.Map) SecretClient(com.azure.security.keyvault.secrets.SecretClient) Container(com.github.ambry.account.Container) StoredProcedureResponse(com.microsoft.azure.cosmosdb.StoredProcedureResponse) Set(java.util.Set) Utils(com.github.ambry.utils.Utils) Collectors(java.util.stream.Collectors) PartitionKey(com.microsoft.azure.cosmosdb.PartitionKey) List(java.util.List) CloudRequestAgent(com.github.ambry.cloud.CloudRequestAgent) SqlQuerySpec(com.microsoft.azure.cosmosdb.SqlQuerySpec) Document(com.microsoft.azure.cosmosdb.Document) Timer(com.codahale.metrics.Timer) BlobId(com.github.ambry.commons.BlobId) ResourceResponse(com.microsoft.azure.cosmosdb.ResourceResponse) RequestOptions(com.microsoft.azure.cosmosdb.RequestOptions) DocumentCollection(com.microsoft.azure.cosmosdb.DocumentCollection) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Callable(java.util.concurrent.Callable) ArrayList(java.util.ArrayList) CloudConfig(com.github.ambry.config.CloudConfig) HashSet(java.util.HashSet) BiConsumer(java.util.function.BiConsumer) CloudStorageException(com.github.ambry.cloud.CloudStorageException) Properties(java.util.Properties) Logger(org.slf4j.Logger) AsyncDocumentClient(com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient) Iterator(java.util.Iterator) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ChangeFeedOptions(com.microsoft.azure.cosmosdb.ChangeFeedOptions) AccessCondition(com.microsoft.azure.cosmosdb.AccessCondition) ConnectionPolicy(com.microsoft.azure.cosmosdb.ConnectionPolicy) SecretClientBuilder(com.azure.security.keyvault.secrets.SecretClientBuilder) HttpConstants(com.microsoft.azure.cosmosdb.internal.HttpConstants) RetryOptions(com.microsoft.azure.cosmosdb.RetryOptions) FeedOptions(com.microsoft.azure.cosmosdb.FeedOptions) StoredProcedure(com.microsoft.azure.cosmosdb.StoredProcedure) SqlParameter(com.microsoft.azure.cosmosdb.SqlParameter) CloudBlobMetadata(com.github.ambry.cloud.CloudBlobMetadata) BlockingObservable(rx.observables.BlockingObservable) RequestOptions(com.microsoft.azure.cosmosdb.RequestOptions) StoredProcedureResponse(com.microsoft.azure.cosmosdb.StoredProcedureResponse) Document(com.microsoft.azure.cosmosdb.Document) DocumentClientException(com.microsoft.azure.cosmosdb.DocumentClientException)

Aggregations

RequestOptions (com.microsoft.azure.cosmosdb.RequestOptions)9 DocumentClientException (com.microsoft.azure.cosmosdb.DocumentClientException)6 CloudStorageException (com.github.ambry.cloud.CloudStorageException)5 Document (com.microsoft.azure.cosmosdb.Document)5 PartitionKey (com.microsoft.azure.cosmosdb.PartitionKey)5 ConnectionPolicy (com.microsoft.azure.cosmosdb.ConnectionPolicy)4 AsyncDocumentClient (com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient)4 AccessCondition (com.microsoft.azure.cosmosdb.AccessCondition)3 DocumentCollection (com.microsoft.azure.cosmosdb.DocumentCollection)3 FeedOptions (com.microsoft.azure.cosmosdb.FeedOptions)3 FeedResponse (com.microsoft.azure.cosmosdb.FeedResponse)3 RetryOptions (com.microsoft.azure.cosmosdb.RetryOptions)3 SqlQuerySpec (com.microsoft.azure.cosmosdb.SqlQuerySpec)3 StoredProcedure (com.microsoft.azure.cosmosdb.StoredProcedure)3 SecretClient (com.azure.security.keyvault.secrets.SecretClient)2 SecretClientBuilder (com.azure.security.keyvault.secrets.SecretClientBuilder)2 Timer (com.codahale.metrics.Timer)2 Container (com.github.ambry.account.Container)2 CloudBlobMetadata (com.github.ambry.cloud.CloudBlobMetadata)2 CloudRequestAgent (com.github.ambry.cloud.CloudRequestAgent)2