use of com.microsoft.azure.cosmosdb.ResourceResponse in project ambry by linkedin.
the class AzureCloudDestinationTest method setup.
@Before
public void setup() throws Exception {
long partition = 666;
PartitionId partitionId = new MockPartitionId(partition, MockClusterMap.DEFAULT_PARTITION_CLASS);
blobId = new BlobId(BLOB_ID_V6, BlobIdType.NATIVE, dataCenterId, accountId, containerId, partitionId, false, BlobDataType.DATACHUNK);
CloudBlobMetadata blobMetadata = new CloudBlobMetadata(blobId, 0, Utils.Infinite_Time, blobSize, CloudBlobMetadata.EncryptionOrigin.NONE);
mockServiceClient = mock(BlobServiceClient.class);
mockBlobBatchClient = mock(BlobBatchClient.class);
mockBlockBlobClient = AzureBlobDataAccessorTest.setupMockBlobClient(mockServiceClient);
mockBlobExistence(false);
mockumentClient = mock(AsyncDocumentClient.class);
Observable<ResourceResponse<Document>> mockResponse = getMockedObservableForSingleResource(blobMetadata);
when(mockumentClient.readDocument(anyString(), any(RequestOptions.class))).thenReturn(mockResponse);
when(mockumentClient.upsertDocument(anyString(), any(Object.class), any(RequestOptions.class), anyBoolean())).thenReturn(mockResponse);
when(mockumentClient.replaceDocument(any(Document.class), any(RequestOptions.class))).thenReturn(mockResponse);
when(mockumentClient.deleteDocument(anyString(), any(RequestOptions.class))).thenReturn(mockResponse);
configProps.setProperty(AzureCloudConfig.AZURE_STORAGE_CONNECTION_STRING, storageConnection);
configProps.setProperty(AzureCloudConfig.COSMOS_ENDPOINT, "http://ambry.beyond-the-cosmos.com:443");
configProps.setProperty(AzureCloudConfig.COSMOS_COLLECTION_LINK, "ambry/metadata");
configProps.setProperty(AzureCloudConfig.COSMOS_DELETED_CONTAINER_COLLECTION_LINK, "ambry/deletedContainer");
configProps.setProperty(AzureCloudConfig.COSMOS_KEY, "cosmos-key");
configProps.setProperty("clustermap.cluster.name", "main");
configProps.setProperty("clustermap.datacenter.name", "uswest");
configProps.setProperty("clustermap.host.name", "localhost");
configProps.setProperty(AzureCloudConfig.AZURE_STORAGE_AUTHORITY, "https://login.microsoftonline.com/test-account/");
configProps.setProperty(AzureCloudConfig.AZURE_STORAGE_CLIENTID, "client-id");
configProps.setProperty(AzureCloudConfig.AZURE_STORAGE_SECRET, "client-secret");
configProps.setProperty(AzureCloudConfig.AZURE_STORAGE_ENDPOINT, "https://azure_storage.blob.core.windows.net");
configProps.setProperty(AzureCloudConfig.AZURE_STORAGE_CLIENT_CLASS, "com.github.ambry.cloud.azure.ConnectionStringBasedStorageClient");
vcrMetrics = new VcrMetrics(new MetricRegistry());
azureMetrics = new AzureMetrics(new MetricRegistry());
clusterMap = mock(ClusterMap.class);
azureDest = new AzureCloudDestination(mockServiceClient, mockBlobBatchClient, mockumentClient, "foo", "bar", clusterName, azureMetrics, defaultAzureReplicationFeedType, clusterMap, false, configProps);
}
use of com.microsoft.azure.cosmosdb.ResourceResponse in project ambry by linkedin.
the class AzureTestUtils method getMockedObservableForSingleResource.
/**
* Utility to mock the call chain to get mocked {@link Observable} for single resource from {@link AsyncDocumentClient}.
* @param metadata the {@link CloudBlobMetadata} to return as a document.
* @return {@link Observable< ResourceResponse <Document>>} object.
*/
static Observable<ResourceResponse<Document>> getMockedObservableForSingleResource(CloudBlobMetadata metadata) throws IOException {
Observable<ResourceResponse<Document>> mockResponse = mock(Observable.class);
BlockingObservable<ResourceResponse<Document>> mockBlockingObservable = mock(BlockingObservable.class);
when(mockResponse.toBlocking()).thenReturn(mockBlockingObservable);
ResourceResponse<Document> mockResourceResponse = mock(ResourceResponse.class);
when(mockBlockingObservable.single()).thenReturn(mockResourceResponse);
Document metadataDoc = createDocumentFromCloudBlobMetadata(metadata);
when(mockResourceResponse.getResource()).thenReturn(metadataDoc);
return mockResponse;
}
use of com.microsoft.azure.cosmosdb.ResourceResponse 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.ResourceResponse in project ambry by linkedin.
the class AzureCloudDestinationTest method testDeleteAfterPartialCompaction.
/**
* Test delete when record is in Cosmos but not ABS.
*/
@Test
public void testDeleteAfterPartialCompaction() throws Exception {
BlobStorageException ex = mockStorageException(BlobErrorCode.BLOB_NOT_FOUND);
when(mockBlockBlobClient.getPropertiesWithResponse(any(), any(), any())).thenThrow(ex);
// Rig Cosmos to return us a deleted blob on read request
long deletionTime = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(10);
CloudBlobMetadata deletedMetadata = new CloudBlobMetadata().setId(blobId.getID()).setDeletionTime(deletionTime);
Observable<ResourceResponse<Document>> mockResponse = getMockedObservableForSingleResource(deletedMetadata);
when(mockumentClient.readDocument(anyString(), any(RequestOptions.class))).thenReturn(mockResponse);
// Now delete the puppy, Cosmos record should get purged.
try {
assertFalse("Expected update to recover and return false", azureDest.deleteBlob(blobId, deletionTime, (short) 0, dummyCloudUpdateValidator));
} catch (CloudStorageException cex) {
assertTrue(cex.getCause() instanceof BlobStorageException);
assertEquals(((BlobStorageException) cex.getCause()).getErrorCode(), BlobErrorCode.BLOB_NOT_FOUND);
}
assertEquals("Expected recovery", 1, azureMetrics.blobUpdateRecoverCount.getCount());
verify(mockumentClient).deleteDocument(anyString(), any());
}
Aggregations