private async Task <Stream> OpenNupkgStreamAsync(RemoteSourceDependencyInfo package, CancellationToken cancellationToken)
        {
            await EnsureDependencyProvider(cancellationToken);

            Task <NupkgEntry> task;

            lock (_nupkgCache)
            {
                if (!_nupkgCache.TryGetValue(package.ContentUri, out task))
                {
                    task = _nupkgCache[package.ContentUri] = OpenNupkgStreamAsyncCore(package, cancellationToken);
                }
            }

            var result = await task;

            if (result == null)
            {
                return(null);
            }

            // Acquire the lock on a file before we open it to prevent this process
            // from opening a file deleted by the logic in HttpSource.GetAsync() in another process
            return(await ConcurrencyUtilities.ExecuteWithFileLockedAsync(result.TempFileName,
                                                                         action : token =>
            {
                return Task.FromResult(
                    new FileStream(result.TempFileName, FileMode.Open, FileAccess.Read,
                                   FileShare.ReadWrite | FileShare.Delete));
            },
                                                                         token : cancellationToken));
        }
Ejemplo n.º 2
0
        private async Task <NupkgEntry> OpenNupkgStreamAsyncCore(RemoteSourceDependencyInfo package, CancellationToken cancellationToken)
        {
            for (var retry = 0; retry != 3; ++retry)
            {
                try
                {
                    using (var data = await _httpSource.GetAsync(
                               package.ContentUri,
                               "nupkg_" + package.Identity.Id + "." + package.Identity.Version.ToString(),
                               retry == 0 ? _cacheAgeLimitNupkg : TimeSpan.Zero,
                               cancellationToken))
                    {
                        return(new NupkgEntry
                        {
                            TempFileName = data.CacheFileName
                        });
                    }
                }
                catch (Exception ex) when(retry < 2)
                {
                    var message = Strings.FormatLog_FailedToDownloadPackage(package.ContentUri) + Environment.NewLine + ex.Message;

                    Logger.LogInformation(message.Yellow().Bold());
                }
                catch (Exception ex) when(retry == 2)
                {
                    var message = Strings.FormatLog_FailedToDownloadPackage(package.ContentUri) + Environment.NewLine + ex.Message;

                    Logger.LogError(message.Red().Bold());
                }
            }

            return(null);
        }
        private async Task <NupkgEntry> OpenNupkgStreamAsyncCore(RemoteSourceDependencyInfo package, CancellationToken cancellationToken)
        {
            for (var retry = 0; retry != 3; ++retry)
            {
                try
                {
                    using (var data = await _httpSource.GetAsync(
                               new HttpSourceCachedRequest(
                                   package.ContentUri,
                                   "nupkg_" + package.Identity.Id + "." + package.Identity.Version.ToNormalizedString(),
                                   CreateCacheContext(retry))
                    {
                        EnsureValidContents = stream => HttpStreamValidation.ValidateNupkg(package.ContentUri, stream)
                    },
                               Logger,
                               cancellationToken))
                    {
                        return(new NupkgEntry
                        {
                            TempFileName = data.CacheFileName
                        });
                    }
                }
                catch (Exception ex) when(retry < 2)
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_FailedToDownloadPackage, package.ContentUri)
                                  + Environment.NewLine
                                  + ExceptionUtilities.DisplayMessage(ex);

                    Logger.LogMinimal(message);
                }
                catch (Exception ex) when(retry == 2)
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_FailedToDownloadPackage, package.ContentUri)
                                  + Environment.NewLine
                                  + ExceptionUtilities.DisplayMessage(ex);

                    Logger.LogError(message);
                }
            }

            return(null);
        }
Ejemplo n.º 4
0
            internal static RemoteV3FindPackageByIdResourceTest Create()
            {
                var serviceAddress  = TestUtility.CreateServiceAddress();
                var packageIdentity = new PackageIdentity(
                    id: "xunit",
                    version: NuGetVersion.Parse("2.2.0-beta1-build3239"));
                var testDirectory = TestDirectory.Create();
                var packageSource = new PackageSource(serviceAddress);

                var dependencyInfoResourceProvider = new Mock <INuGetResourceProvider>();
                var dependencyInfoResource         = new Mock <DependencyInfoResource>();
                var remoteSourceDependencyInfo     = new RemoteSourceDependencyInfo(
                    packageIdentity,
                    listed: true,
                    dependencyGroups: Enumerable.Empty <PackageDependencyGroup>(),
                    contentUri: serviceAddress + "api/v2/package/xunit/2.2.0-beta1-build3239");

                dependencyInfoResource.Setup(x => x.ResolvePackages(
                                                 It.Is <string>(id => id == packageIdentity.Id),
                                                 It.IsNotNull <ILogger>(),
                                                 It.IsAny <CancellationToken>()))
                .ReturnsAsync(new[] { remoteSourceDependencyInfo });

                dependencyInfoResourceProvider.SetupGet(x => x.Before)
                .Returns(Enumerable.Empty <string>());
                dependencyInfoResourceProvider.SetupGet(x => x.After)
                .Returns(Enumerable.Empty <string>());
                dependencyInfoResourceProvider.SetupGet(x => x.ResourceType)
                .Returns(typeof(DependencyInfoResource));
                dependencyInfoResourceProvider.SetupGet(x => x.Name)
                .Returns("DependencyInfoResourceProvider");
                dependencyInfoResourceProvider.Setup(
                    x => x.TryCreate(It.IsNotIn <SourceRepository>(), It.IsAny <CancellationToken>()))
                .ReturnsAsync(new Tuple <bool, INuGetResource>(true, dependencyInfoResource.Object));

                var sourceRepository = new SourceRepository(
                    packageSource,
                    new[] { dependencyInfoResourceProvider.Object });
                var package = SimpleTestPackageUtility.CreateFullPackage(
                    testDirectory.Path,
                    packageIdentity.Id,
                    packageIdentity.Version.ToNormalizedString());
                var packageBytes = File.ReadAllBytes(package.FullName);

                var responses = new Dictionary <string, Func <HttpRequestMessage, Task <HttpResponseMessage> > >
                {
                    {
                        serviceAddress,
                        request => Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)
                        {
                            Content = new TestContent(string.Empty)
                        })
                    },
                    {
                        serviceAddress + $"FindPackagesById()?id='{packageIdentity.Id}'",
                        request => Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)
                        {
                            Content = new TestContent(
                                TestUtility.GetResource(
                                    "NuGet.Protocol.Tests.compiler.resources.XunitFindPackagesById.xml",
                                    typeof(RemoteV3FindPackageByIdResourceTest)))
                        })
                    },
                    {
                        serviceAddress + $"FindPackagesById()?id='{packageIdentity.Id.ToUpper()}'",
                        request => Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)
                        {
                            Content = new TestContent(
                                TestUtility.GetResource(
                                    "NuGet.Protocol.Tests.compiler.resources.XunitFindPackagesById.xml",
                                    typeof(RemoteV3FindPackageByIdResourceTest)))
                        })
                    },
                    {
                        serviceAddress + "api/v2/package/xunit/2.2.0-beta1-build3239",
                        request => Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)
                        {
                            Content = new ByteArrayContent(packageBytes)
                        })
                    },
                    {
                        serviceAddress + $"FindPackagesById()?id='a'",
                        request => Task.FromResult(new HttpResponseMessage(HttpStatusCode.NoContent))
                    }
                };

                var httpSource = new TestHttpSource(packageSource, responses);
                var resource   = new RemoteV3FindPackageByIdResource(
                    sourceRepository,
                    httpSource);

                return(new RemoteV3FindPackageByIdResourceTest(
                           resource,
                           sourceRepository,
                           package,
                           packageIdentity,
                           new SourceCacheContext(),
                           httpSource,
                           testDirectory));
            }
        private async Task<NupkgEntry> OpenNupkgStreamAsyncCore(RemoteSourceDependencyInfo package, CancellationToken cancellationToken)
        {
            for (var retry = 0; retry != 3; ++retry)
            {
                try
                {
                    using (var data = await _httpSource.GetAsync(
                        package.ContentUri,
                        "nupkg_" + package.Identity.Id + "." + package.Identity.Version.ToString(),
                        retry == 0 ? _cacheAgeLimitNupkg : TimeSpan.Zero,
                        cancellationToken))
                    {
                        return new NupkgEntry
                            {
                                TempFileName = data.CacheFileName
                            };
                    }
                }
                catch (Exception ex) when (retry < 2)
                {
                    var message = Strings.FormatLog_FailedToDownloadPackage(package.ContentUri) + Environment.NewLine + ex.Message;
                    Logger.LogInformation(message.Yellow().Bold());
                }
                catch (Exception ex) when (retry == 2)
                {
                    var message = Strings.FormatLog_FailedToDownloadPackage(package.ContentUri) + Environment.NewLine + ex.Message;
                    Logger.LogError(message.Red().Bold());
                }
            }

            return null;
        }
        private async Task<Stream> OpenNupkgStreamAsync(RemoteSourceDependencyInfo package, CancellationToken cancellationToken)
        {
            await EnsureDependencyProvider(cancellationToken);

            Task<NupkgEntry> task;
            lock (_nupkgCache)
            {
                if (!_nupkgCache.TryGetValue(package.ContentUri, out task))
                {
                    task = _nupkgCache[package.ContentUri] = OpenNupkgStreamAsyncCore(package, cancellationToken);
                }
            }

            var result = await task;
            if (result == null)
            {
                return null;
            }

            // Acquire the lock on a file before we open it to prevent this process
            // from opening a file deleted by the logic in HttpSource.GetAsync() in another process
            return await ConcurrencyUtilities.ExecuteWithFileLocked(result.TempFileName, _ =>
                {
                    return Task.FromResult(
                        new FileStream(result.TempFileName, FileMode.Open, FileAccess.Read,
                            FileShare.ReadWrite | FileShare.Delete));
                });
        }