Search in sources :

Example 1 with ResourceResponse

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);
}
Also used : ClusterMap(com.github.ambry.clustermap.ClusterMap) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) VcrMetrics(com.github.ambry.cloud.VcrMetrics) MockPartitionId(com.github.ambry.clustermap.MockPartitionId) RequestOptions(com.microsoft.azure.cosmosdb.RequestOptions) CloudBlobMetadata(com.github.ambry.cloud.CloudBlobMetadata) MetricRegistry(com.codahale.metrics.MetricRegistry) MockPartitionId(com.github.ambry.clustermap.MockPartitionId) PartitionId(com.github.ambry.clustermap.PartitionId) Document(com.microsoft.azure.cosmosdb.Document) ResourceResponse(com.microsoft.azure.cosmosdb.ResourceResponse) BlobServiceClient(com.azure.storage.blob.BlobServiceClient) BlobBatchClient(com.azure.storage.blob.batch.BlobBatchClient) BlobId(com.github.ambry.commons.BlobId) AsyncDocumentClient(com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient) Before(org.junit.Before)

Example 2 with ResourceResponse

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;
}
Also used : ResourceResponse(com.microsoft.azure.cosmosdb.ResourceResponse) Document(com.microsoft.azure.cosmosdb.Document)

Example 3 with ResourceResponse

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;
    }
}
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) AccessCondition(com.microsoft.azure.cosmosdb.AccessCondition) Document(com.microsoft.azure.cosmosdb.Document) Map(java.util.Map) DocumentClientException(com.microsoft.azure.cosmosdb.DocumentClientException) CloudStorageException(com.github.ambry.cloud.CloudStorageException) DocumentClientException(com.microsoft.azure.cosmosdb.DocumentClientException)

Example 4 with ResourceResponse

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());
}
Also used : ResourceResponse(com.microsoft.azure.cosmosdb.ResourceResponse) RequestOptions(com.microsoft.azure.cosmosdb.RequestOptions) CloudBlobMetadata(com.github.ambry.cloud.CloudBlobMetadata) CloudStorageException(com.github.ambry.cloud.CloudStorageException) BlobStorageException(com.azure.storage.blob.models.BlobStorageException) Test(org.junit.Test)

Aggregations

ResourceResponse (com.microsoft.azure.cosmosdb.ResourceResponse)4 CloudBlobMetadata (com.github.ambry.cloud.CloudBlobMetadata)3 Document (com.microsoft.azure.cosmosdb.Document)3 RequestOptions (com.microsoft.azure.cosmosdb.RequestOptions)3 CloudStorageException (com.github.ambry.cloud.CloudStorageException)2 VcrMetrics (com.github.ambry.cloud.VcrMetrics)2 BlobId (com.github.ambry.commons.BlobId)2 AsyncDocumentClient (com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient)2 SecretClient (com.azure.security.keyvault.secrets.SecretClient)1 SecretClientBuilder (com.azure.security.keyvault.secrets.SecretClientBuilder)1 BlobServiceClient (com.azure.storage.blob.BlobServiceClient)1 BlobBatchClient (com.azure.storage.blob.batch.BlobBatchClient)1 BlobStorageException (com.azure.storage.blob.models.BlobStorageException)1 MetricRegistry (com.codahale.metrics.MetricRegistry)1 Timer (com.codahale.metrics.Timer)1 Container (com.github.ambry.account.Container)1 CloudRequestAgent (com.github.ambry.cloud.CloudRequestAgent)1 ClusterMap (com.github.ambry.clustermap.ClusterMap)1 MockClusterMap (com.github.ambry.clustermap.MockClusterMap)1 MockPartitionId (com.github.ambry.clustermap.MockPartitionId)1