/// <inheritdoc />
        public async Task <ObjectResult <ContentHashListWithCacheMetadata> > AddContentHashListAsync(
            Context context,
            string cacheNamespace,
            StrongFingerprint strongFingerprint,
            ContentHashListWithCacheMetadata valueToAdd,
            bool forceUpdate)
        {
            try
            {
                ContentHashListResponse addResult = await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                    context,
                    "AddContentHashList",
                    innerCts => _buildCacheHttpClient.AddContentHashListAsync(
                        cacheNamespace,
                        strongFingerprint,
                        valueToAdd,
                        forceUpdate), CancellationToken.None).ConfigureAwait(false);

                // The return value is null if the server fails adding content hash list to the backing store.
                // See BuildCacheService.AddContentHashListAsync for more details about the implementation invariants/guarantees.
                if (addResult != null)
                {
                    DownloadUriCache.Instance.BulkAddDownloadUris(addResult.BlobDownloadUris);
                }

                // add succeeded but returned an empty contenthashlistwith cache metadata. correct this.
                if (addResult?.ContentHashListWithCacheMetadata == null)
                {
                    return
                        (new ObjectResult <ContentHashListWithCacheMetadata>(
                             new ContentHashListWithCacheMetadata(
                                 new ContentHashListWithDeterminism(null, valueToAdd.ContentHashListWithDeterminism.Determinism),
                                 valueToAdd.GetRawExpirationTimeUtc(),
                                 valueToAdd.ContentGuarantee,
                                 valueToAdd.HashOfExistingContentHashList)));
                }
                else if (addResult.ContentHashListWithCacheMetadata.ContentHashListWithDeterminism.ContentHashList != null &&
                         addResult.ContentHashListWithCacheMetadata.HashOfExistingContentHashList == null)
                {
                    return(new ObjectResult <ContentHashListWithCacheMetadata>(
                               new ContentHashListWithCacheMetadata(
                                   addResult.ContentHashListWithCacheMetadata.ContentHashListWithDeterminism,
                                   addResult.ContentHashListWithCacheMetadata.GetRawExpirationTimeUtc(),
                                   addResult.ContentHashListWithCacheMetadata.ContentGuarantee,
                                   addResult.ContentHashListWithCacheMetadata.ContentHashListWithDeterminism.ContentHashList.GetHashOfHashes())));
                }
                else
                {
                    return(new ObjectResult <ContentHashListWithCacheMetadata>(addResult.ContentHashListWithCacheMetadata));
                }
            }
            catch (Exception ex)
            {
                return(new ObjectResult <ContentHashListWithCacheMetadata>(ex));
            }
        }
        /// <inheritdoc />
        public async Task <ObjectResult <IEnumerable <SelectorAndContentHashListWithCacheMetadata> > > GetSelectorsAsync(
            Context context,
            string cacheNamespace,
            Fingerprint weakFingerprint,
            int maxSelectorsToFetch)
        {
            try
            {
                BlobSelectorsResponse selectorsResponse = await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                    context,
                    "GetSelectors",
                    innerCts => _buildCacheHttpClient.GetSelectors(
                        cacheNamespace,
                        weakFingerprint,
                        maxSelectorsToFetch),
                    CancellationToken.None);

                var selectorsToReturn = new List <SelectorAndContentHashListWithCacheMetadata>();
                foreach (
                    BlobSelectorAndContentHashList selectorAndPossible in selectorsResponse.SelectorsAndPossibleContentHashLists)
                {
                    if (selectorAndPossible.ContentHashList != null)
                    {
                        if (selectorAndPossible.ContentHashList.Determinism.IsDeterministic)
                        {
                            BlobContentHashListCache.Instance.AddValue(
                                cacheNamespace,
                                new StrongFingerprint(weakFingerprint, selectorAndPossible.Selector),
                                selectorAndPossible.ContentHashList);
                        }

                        if (selectorAndPossible.ContentHashList.ContentHashListWithDeterminism.MetadataBlobDownloadUri != null)
                        {
                            AddDownloadUriToCache(selectorAndPossible.ContentHashList.ContentHashListWithDeterminism);
                        }
                    }

                    selectorsToReturn.Add(
                        new SelectorAndContentHashListWithCacheMetadata(
                            selectorAndPossible.Selector,
                            null));
                }

                return(new ObjectResult <IEnumerable <SelectorAndContentHashListWithCacheMetadata> >(selectorsToReturn));
            }
            catch (Exception ex)
            {
                return(new ObjectResult <IEnumerable <SelectorAndContentHashListWithCacheMetadata> >(ex));
            }
        }
        /// <inheritdoc />
        public async Task <ObjectResult <ContentHashListWithCacheMetadata> > AddContentHashListAsync(
            Context context,
            string cacheNamespace,
            StrongFingerprint strongFingerprint,
            ContentHashListWithCacheMetadata valueToAdd)
        {
            try
            {
                ContentHashListResponse addResult = await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                    context,
                    "AddContentHashList",
                    innerCts => _buildCacheHttpClient.AddContentHashListAsync(
                        cacheNamespace,
                        strongFingerprint,
                        valueToAdd), CancellationToken.None).ConfigureAwait(false);

                DownloadUriCache.Instance.BulkAddDownloadUris(addResult.BlobDownloadUris);

                // add succeeded but returned an empty contenthashlistwith cache metadata. correct this.
                if (addResult.ContentHashListWithCacheMetadata == null)
                {
                    return
                        (new ObjectResult <ContentHashListWithCacheMetadata>(
                             new ContentHashListWithCacheMetadata(
                                 new ContentHashListWithDeterminism(null, valueToAdd.ContentHashListWithDeterminism.Determinism),
                                 valueToAdd.GetEffectiveExpirationTimeUtc(),
                                 valueToAdd.ContentGuarantee,
                                 valueToAdd.HashOfExistingContentHashList)));
                }
                else if (addResult.ContentHashListWithCacheMetadata.ContentHashListWithDeterminism.ContentHashList != null &&
                         addResult.ContentHashListWithCacheMetadata.HashOfExistingContentHashList == null)
                {
                    return(new ObjectResult <ContentHashListWithCacheMetadata>(
                               new ContentHashListWithCacheMetadata(
                                   addResult.ContentHashListWithCacheMetadata.ContentHashListWithDeterminism,
                                   addResult.ContentHashListWithCacheMetadata.GetEffectiveExpirationTimeUtc(),
                                   addResult.ContentHashListWithCacheMetadata.ContentGuarantee,
                                   addResult.ContentHashListWithCacheMetadata.ContentHashListWithDeterminism.ContentHashList.GetHashOfHashes())));
                }
                else
                {
                    return(new ObjectResult <ContentHashListWithCacheMetadata>(addResult.ContentHashListWithCacheMetadata));
                }
            }
            catch (Exception ex)
            {
                return(new ObjectResult <ContentHashListWithCacheMetadata>(ex));
            }
        }
        /// <inheritdoc />
        public async Task <Result <ContentHashListWithCacheMetadata> > GetContentHashListAsync(
            Context context,
            string cacheNamespace,
            StrongFingerprint strongFingerprint)
        {
            try
            {
                if (!BlobContentHashListCache.Instance.TryGetValue(cacheNamespace, strongFingerprint, out var blobCacheMetadata))
                {
                    BlobContentHashListResponse blobResponse = await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                        context,
                        "GetContentHashList",
                        innerCts => _buildCacheHttpClient.GetContentHashListAsync(cacheNamespace, strongFingerprint),
                        CancellationToken.None)
                                                               .ConfigureAwait(false);

                    blobCacheMetadata = blobResponse.ContentHashListWithCacheMetadata;
                    DownloadUriCache.Instance.BulkAddDownloadUris(blobResponse.BlobDownloadUris);
                    AddDownloadUriToCache(blobCacheMetadata.ContentHashListWithDeterminism);
                }

                // Currently expect the Blob-based service to return null on misses,
                // but the other catches have been left for safety/compat.
                if (blobCacheMetadata == null)
                {
                    return(new Result <ContentHashListWithCacheMetadata>(EmptyContentHashList));
                }

                return(await UnpackBlobContentHashListAsync(context, blobCacheMetadata));
            }
            catch (ContentBagNotFoundException)
            {
                return(new Result <ContentHashListWithCacheMetadata>(EmptyContentHashList));
            }
            catch (CacheServiceException ex) when(ex.ReasonCode == CacheErrorReasonCode.ContentHashListNotFound)
            {
                return(new Result <ContentHashListWithCacheMetadata>(EmptyContentHashList));
            }
            catch (VssServiceResponseException serviceEx) when(serviceEx.HttpStatusCode == HttpStatusCode.NotFound)
            {
                return(new Result <ContentHashListWithCacheMetadata>(EmptyContentHashList));
            }
            catch (Exception ex)
            {
                return(new Result <ContentHashListWithCacheMetadata>(ex));
            }
        }
Example #5
0
        /// <inheritdoc />
        public async Task <Result <ContentHashListWithCacheMetadata> > GetContentHashListAsync(
            Context context,
            string cacheNamespace,
            StrongFingerprint strongFingerprint)
        {
            try
            {
                ContentHashListResponse response =
                    await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                        context,
                        "GetContentHashList",
                        innerCts => _buildCacheHttpClient.GetContentHashListAsync(cacheNamespace, strongFingerprint),
                        CancellationToken.None).ConfigureAwait(false);

                DownloadUriCache.Instance.BulkAddDownloadUris(response.BlobDownloadUris);

                // our response should never be null.
                if (response.ContentHashListWithCacheMetadata != null)
                {
                    return(new Result <ContentHashListWithCacheMetadata>(response.ContentHashListWithCacheMetadata));
                }

                return(new Result <ContentHashListWithCacheMetadata>(EmptyContentHashList));
            }
            catch (CacheServiceException ex) when(ex.ReasonCode == CacheErrorReasonCode.ContentHashListNotFound)
            {
                return(new Result <ContentHashListWithCacheMetadata>(EmptyContentHashList));
            }
            catch (ContentBagNotFoundException)
            {
                return(new Result <ContentHashListWithCacheMetadata>(EmptyContentHashList));
            }
            catch (VssServiceResponseException serviceEx) when(serviceEx.HttpStatusCode == HttpStatusCode.NotFound)
            {
                // Currently expect the Item-based service to return VssServiceResponseException on misses,
                // but the other catches have been left for safety/compat.
                return(new Result <ContentHashListWithCacheMetadata>(EmptyContentHashList));
            }
            catch (Exception ex)
            {
                return(new Result <ContentHashListWithCacheMetadata>(ex));
            }
        }
        /// <inheritdoc />
        public async Task <ObjectResult <IEnumerable <SelectorAndContentHashListWithCacheMetadata> > > GetSelectorsAsync(
            Context context,
            string cacheNamespace,
            Fingerprint weakFingerprint,
            int maxSelectorsToFetch)
        {
            try
            {
                var selectorsResponse = await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                    context,
                    "GetSelectors",
                    innerCts => _buildCacheHttpClient.GetSelectors(
                        cacheNamespace,
                        weakFingerprint,
                        maxSelectorsToFetch), CancellationToken.None);

                var selectorsToReturn = new List <SelectorAndContentHashListWithCacheMetadata>();
                foreach (
                    SelectorAndPossibleContentHashListResponse selectorAndPossible in selectorsResponse.SelectorsAndPossibleContentHashLists
                    )
                {
                    if (selectorAndPossible.ContentHashList != null)
                    {
                        DownloadUriCache.Instance.BulkAddDownloadUris(selectorAndPossible.ContentHashList.BlobDownloadUris);
                    }

                    selectorsToReturn.Add(
                        new SelectorAndContentHashListWithCacheMetadata(
                            selectorAndPossible.Selector,
                            selectorAndPossible.ContentHashList?.ContentHashListWithCacheMetadata));
                }

                return(new ObjectResult <IEnumerable <SelectorAndContentHashListWithCacheMetadata> >(selectorsToReturn));
            }
            catch (Exception ex)
            {
                return(new ObjectResult <IEnumerable <SelectorAndContentHashListWithCacheMetadata> >(ex));
            }
        }
        /// <inheritdoc />
        public async Task <ObjectResult <ContentHashListWithCacheMetadata> > AddContentHashListAsync(
            Context context,
            string cacheNamespace,
            StrongFingerprint strongFingerprint,
            ContentHashListWithCacheMetadata valueToAdd)
        {
            try
            {
                Func <System.IO.Stream, System.Threading.CancellationToken, Task <StructResult <ContentHash> > > putStreamFunc =
                    async(stream, cts) =>
                {
                    PutResult putResult = await _blobContentSession.PutStreamAsync(context, HashType.Vso0, stream, cts);

                    if (putResult.Succeeded)
                    {
                        return(new StructResult <ContentHash>(putResult.ContentHash));
                    }

                    return(new StructResult <ContentHash>(putResult));
                };

                StructResult <ContentHash> blobIdOfContentHashListResult =
                    await BlobContentHashListExtensions.PackInBlob(
                        putStreamFunc,
                        valueToAdd.ContentHashListWithDeterminism);

                if (!blobIdOfContentHashListResult.Succeeded)
                {
                    return(new ObjectResult <ContentHashListWithCacheMetadata>(blobIdOfContentHashListResult));
                }

                var blobContentHashListWithDeterminism =
                    new BlobContentHashListWithDeterminism(
                        valueToAdd.ContentHashListWithDeterminism.Determinism.EffectiveGuid,
                        BlobIdentifierToContentHashExtensions.ToBlobIdentifier(blobIdOfContentHashListResult.Data));

                var blobContentHashListWithCacheMetadata = new BlobContentHashListWithCacheMetadata(
                    blobContentHashListWithDeterminism,
                    valueToAdd.GetRawExpirationTimeUtc(),
                    valueToAdd.ContentGuarantee,
                    valueToAdd.HashOfExistingContentHashList);

                BlobContentHashListResponse addResult = await ArtifactHttpClientErrorDetectionStrategy.ExecuteWithTimeoutAsync(
                    context,
                    "AddContentHashList",
                    innerCts => _buildCacheHttpClient.AddContentHashListAsync(
                        cacheNamespace,
                        strongFingerprint,
                        blobContentHashListWithCacheMetadata),
                    CancellationToken.None).ConfigureAwait(false);

                DownloadUriCache.Instance.BulkAddDownloadUris(addResult.BlobDownloadUris);

                // add succeeded but returned an empty contenthashlistwith cache metadata. correct this.
                if (addResult.ContentHashListWithCacheMetadata == null)
                {
                    return
                        (new ObjectResult <ContentHashListWithCacheMetadata>(
                             new ContentHashListWithCacheMetadata(
                                 new ContentHashListWithDeterminism(null, blobContentHashListWithCacheMetadata.Determinism),
                                 blobContentHashListWithCacheMetadata.GetRawExpirationTimeUtc(),
                                 blobContentHashListWithCacheMetadata.ContentGuarantee)));
                }
                else
                {
                    return(await UnpackBlobContentHashListAsync(context, addResult.ContentHashListWithCacheMetadata));
                }
            }
            catch (Exception ex)
            {
                return(new ObjectResult <ContentHashListWithCacheMetadata>(ex));
            }
        }