/// <inheritdoc /> public async Task <ObjectResult <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 ObjectResult <ContentHashListWithCacheMetadata>(response.ContentHashListWithCacheMetadata)); } return(new ObjectResult <ContentHashListWithCacheMetadata>(EmptyContentHashList)); } catch (CacheServiceException ex) when(ex.ReasonCode == CacheErrorReasonCode.ContentHashListNotFound) { return(new ObjectResult <ContentHashListWithCacheMetadata>(EmptyContentHashList)); } catch (ContentBagNotFoundException) { return(new ObjectResult <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 ObjectResult <ContentHashListWithCacheMetadata>(EmptyContentHashList)); } 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 { 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)); } }
/// <summary> /// Creates an http client that can communicate with a VSTS Build Cache Service. /// </summary> public async Task <IBlobBuildCacheHttpClient> CreateBlobBuildCacheHttpClientAsync(Context context) { RetryPolicy authRetryPolicy = new RetryPolicy <AuthorizationErrorDetectionStrategy>(RetryStrategy.DefaultExponential); var creds = await authRetryPolicy.ExecuteAsync(() => _vssCredentialsFactory.CreateVssCredentialsAsync(_buildCacheBaseUri, _useAad)).ConfigureAwait(false); var httpClientFactory = new ArtifactHttpClientFactory( creds, _httpSendTimeout, tracer: new AppTraceSourceContextAdapter(context, "BuildCacheHttpClientFactory", SourceLevels.All), verifyConnectionCancellationToken: CancellationToken.None); // TODO: Pipe down cancellation support (bug 1365340) IBlobBuildCacheHttpClient client = httpClientFactory.CreateVssHttpClient <IArtifactBlobBuildCacheHttpClient, BlobBuildCacheHttpClient>(_buildCacheBaseUri); await ArtifactHttpClientErrorDetectionStrategy.ExecuteAsync( context, "VerifyBlobBuildCacheHttpClientConnection", () => httpClientFactory.VerifyConnectionAsync(client as IArtifactHttpClient), CancellationToken.None).ConfigureAwait(false); context.TraceMessage( Severity.Debug, $"Verified connection to {_buildCacheBaseUri} with SessionId=[{httpClientFactory.ClientSettings.SessionId}]"); return(client); }
/// <summary> /// Creates an http client that can communicate with a VSTS Build Cache Service. /// </summary> public async Task <IBuildCacheHttpClient> CreateBuildCacheHttpClientAsync(Context context) { IRetryPolicy retryPolicy = RetryPolicyFactory.GetExponentialPolicy(AuthorizationErrorDetectionStrategy.IsTransient); var creds = await retryPolicy.ExecuteAsync( () => _vssCredentialsFactory.GetOrCreateVssCredentialsAsync(_buildCacheBaseUri, _useAad, PatType.CacheReadWrite), CancellationToken.None).ConfigureAwait(false); var httpClientFactory = new ArtifactHttpClientFactory( creds, _httpSendTimeout, tracer: new AppTraceSourceContextAdapter(context, "BuildCacheHttpClientFactory", SourceLevels.All), verifyConnectionCancellationToken: CancellationToken.None); // TODO: Pipe down cancellation support (bug 1365340) IBuildCacheHttpClient client = httpClientFactory.CreateVssHttpClient <IArtifactBuildCacheHttpClient, ItemBuildCacheHttpClient>(_buildCacheBaseUri); await ArtifactHttpClientErrorDetectionStrategy.ExecuteAsync( context, "VerifyBuildCacheHttpClientConnection", () => httpClientFactory.VerifyConnectionAsync(client as IArtifactHttpClient), CancellationToken.None).ConfigureAwait(false); _tracer.Debug(context, $"Verified connection to {_buildCacheBaseUri} with SessionId=[{httpClientFactory.ClientSettings.SessionId}]"); return(client); }
/// <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)); } }