use of com.microsoft.azure.cosmosdb.RequestOptions in project ambry by linkedin.
the class CosmosDataAccessor method updateMetadata.
/**
* Update the blob metadata document in the CosmosDB collection.
* @param blobId the {@link BlobId} for which metadata is replaced.
* @param updateFields Map of field names and new values to update.
* @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> updateMetadata(BlobId blobId, Map<String, String> updateFields) throws DocumentClientException {
// Read the existing record
String docLink = getDocumentLink(blobId.getID());
RequestOptions options = getRequestOptions(blobId.getPartition().toPathString());
ResourceResponse<Document> readResponse = executeCosmosAction(() -> asyncDocumentClient.readDocument(docLink, options).toBlocking().single(), azureMetrics.documentReadTime);
Document doc = readResponse.getResource();
// Update only if value has changed
Map<String, String> fieldsToUpdate = updateFields.entrySet().stream().filter(map -> !String.valueOf(updateFields.get(map.getKey())).equals(doc.get(map.getKey()))).collect(Collectors.toMap(Map.Entry::getKey, map -> String.valueOf(map.getValue())));
if (fieldsToUpdate.size() == 0) {
logger.debug("No change in value for {} in blob {}", updateFields.keySet(), blobId.getID());
return null;
}
// For testing conflict handling
if (updateCallback != null) {
try {
updateCallback.call();
} catch (Exception ex) {
logger.error("Error in update callback", ex);
}
}
// Perform the update
fieldsToUpdate.forEach((key, value) -> doc.set(key, value));
// 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;
}
}
use of com.microsoft.azure.cosmosdb.RequestOptions in project ambry by linkedin.
the class CosmosDataAccessor method getRequestOptions.
private RequestOptions getRequestOptions(String partitionPath) {
RequestOptions options = new RequestOptions();
options.setPartitionKey(new PartitionKey(partitionPath));
return options;
}
use of com.microsoft.azure.cosmosdb.RequestOptions in project ambry by linkedin.
the class CosmosDataAccessor method testConnectivity.
/**
* Test connectivity to Azure CosmosDB
*/
void testConnectivity() {
ResourceResponse<DocumentCollection> response = asyncDocumentClient.readCollection(cosmosCollectionLink, new RequestOptions()).toBlocking().single();
if (response.getResource() == null) {
throw new IllegalStateException("CosmosDB collection not found: " + cosmosCollectionLink);
}
logger.info("CosmosDB connection test succeeded.");
if (purgeBatchSize > 1) {
// Check for existence of BulkDelete stored procedure.
// Source: https://github.com/Azure/azure-cosmosdb-js-server/blob/master/samples/stored-procedures/bulkDelete.js
String sprocLink = cosmosCollectionLink + BULK_DELETE_SPROC;
try {
ResourceResponse<StoredProcedure> spResponse = asyncDocumentClient.readStoredProcedure(sprocLink, null).toBlocking().single();
if (spResponse.getResource() == null) {
logger.error("Did not find stored procedure {}, falling back to individual record deletions", sprocLink);
} else {
logger.info("Found stored procedure {}, will use it with batch size {}.", sprocLink, purgeBatchSize);
bulkDeleteEnabled = true;
}
} catch (Exception ex) {
logger.error("Did not find stored procedure {}, falling back to individual record deletions", sprocLink, ex);
}
} else {
logger.info("Cosmos purge batch size = 1 ==> disabling bulk deletes.");
bulkDeleteEnabled = false;
}
}
use of com.microsoft.azure.cosmosdb.RequestOptions in project ambry by linkedin.
the class CloudTestUtil method cleanupPartition.
/**
* Cleanup the specified partition in azure by deleting all the blobs of the partition.
* @param azureCloudConfig Properties containing the credentials needed for connection to azure.
* @param partitionId partition to be deleted.
*/
static void cleanupPartition(AzureCloudConfig azureCloudConfig, PartitionId partitionId) {
ConnectionPolicy connectionPolicy = new ConnectionPolicy();
AsyncDocumentClient asyncDocumentClient = new AsyncDocumentClient.Builder().withServiceEndpoint(azureCloudConfig.cosmosEndpoint).withMasterKeyOrResourceToken(azureCloudConfig.cosmosKey).withConnectionPolicy(connectionPolicy).withConsistencyLevel(ConsistencyLevel.Session).build();
SqlQuerySpec sqlQuerySpec = new SqlQuerySpec("select * from c where c.partitionId=\"" + partitionId.toPathString() + "\"");
FeedOptions feedOptions = new FeedOptions();
feedOptions.setPartitionKey(new PartitionKey(partitionId.toPathString()));
Iterator<FeedResponse<Document>> iterator = asyncDocumentClient.queryDocuments(azureCloudConfig.cosmosCollectionLink, sqlQuerySpec, feedOptions).toBlocking().getIterator();
RequestOptions requestOptions = new RequestOptions();
requestOptions.setPartitionKey(new PartitionKey(partitionId.toPathString()));
while (iterator.hasNext()) {
FeedResponse<Document> response = iterator.next();
response.getResults().forEach(document -> asyncDocumentClient.deleteDocument(azureCloudConfig.cosmosCollectionLink + "/docs/" + document.getId(), requestOptions).toBlocking().single());
}
}
Aggregations