コード例 #1
0
        public static async Task MetadataApi_GetDownloadUriAsync_Returns_File_Download_Uri_Which_Downloads_Correct_File()
        {
            // Arrange
            MetadataApi target = CreateAuthorizedService();

            List <PackageGroup> packages = await target.GetAvailablePackagesAsync();

            DataFile dataFile = packages
                                .SelectMany((p) => p.Packages)
                                .First()
                                .Files
                                .First();

            // Act
            Uri result = await target.GetDownloadUriAsync(dataFile.FileName, dataFile.MD5Hash);

            // Assert
            Assert.NotNull(result);
            Assert.True(result.IsAbsoluteUri);

            string tempPath = Path.Combine(Path.GetTempPath(), dataFile.FileName);

            try
            {
                using (HttpClient client = new HttpClient())
                {
                    using (var request = new HttpRequestMessage(HttpMethod.Get, result))
                    {
                        using (
                            Stream contentStream = await(await client.SendAsync(request)).Content.ReadAsStreamAsync(),
                            stream = new FileStream(tempPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
                        {
                            await contentStream.CopyToAsync(stream);
                        }
                    }
                }

                Assert.True(File.Exists(tempPath));

                byte[] hash;

                using (Stream stream = File.OpenRead(tempPath))
                {
                    Assert.Equal(dataFile.Size, stream.Length);

                    using (HashAlgorithm algorithm = MD5.Create())
                    {
                        hash = algorithm.ComputeHash(stream);
                    }
                }

                string hashString = string.Concat(hash.Select((p) => p.ToString("x2", CultureInfo.InvariantCulture)));

                Assert.Equal(dataFile.MD5Hash, hashString);
            }
            finally
            {
                if (File.Exists(tempPath))
                {
                    File.Delete(tempPath);
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Downloads the specified file from the specified package group as an asynchronous operation.
        /// </summary>
        /// <param name="service">The Metadata API to use to get the download URI.</param>
        /// <param name="fileStore">The file store to register the download with if successfully downloaded.</param>
        /// <param name="group">The package group to download the file from.</param>
        /// <param name="file">The data file to download.</param>
        /// <param name="downloadRootPath">The root path to download data to.</param>
        /// <param name="verifyDownloads">Whether to verify file downloads.</param>
        /// <param name="cancellationToken">The cancellation token to use to cancel any downloads.</param>
        /// <returns>
        /// A <see cref="Task"/> representing the asynchronous operation.
        /// </returns>
        private static async Task DownloadFileAsync(
            IMetadataApi service,
            IFileStore fileStore,
            PackageGroup group,
            DataFile file,
            string downloadRootPath,
            bool verifyDownloads,
            CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            Console.WriteLine("File name: {0}", file.FileName);
            Console.WriteLine("File hash: {0}", file.MD5Hash);
            Console.WriteLine("File size: {0:N0}", file.Size);

            // Query the URIs to download the file from
            Uri uri = await service.GetDownloadUriAsync(file.FileName, file.MD5Hash);

            if (uri == null)
            {
                Console.WriteLine("File '{0}' is not available for download at this time.", file.FileName);
                Console.WriteLine();
                return;
            }

            Console.WriteLine("File URI: {0}", uri);
            Console.WriteLine();

            // Create the path to the directory to download the file to
            string directoryPath = Path.Combine(
                downloadRootPath,
                group.PackageGroupCode,
                group.Vintage);

            string filePath = Path.GetFullPath(Path.Combine(directoryPath, file.FileName));

            // Create the directory if it doesn't already exist
            if (!Directory.Exists(directoryPath))
            {
                Directory.CreateDirectory(directoryPath);
            }

            // Download the file
            Console.WriteLine("Downloading '{0}' ({1}) to '{2}'...", file.FileName, file.MD5Hash, filePath);

            using (HttpClient client = new HttpClient())
            {
                using (HttpResponseMessage response = await client.GetAsync(uri, cancellationToken))
                {
                    response.EnsureSuccessStatusCode();

                    using (Stream stream = await response.Content.ReadAsStreamAsync())
                    {
                        using (Stream fileStream = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
                        {
                            // Ensure any existing file is overwritten
                            fileStream.SetLength(0L);

                            await stream.CopyToAsync(fileStream, 4096, cancellationToken);
                        }
                    }
                }
            }

            // Validate the download is correct, if configured.
            // Don't register the file in the file store as the file download became corrupted somehow.
            if (!verifyDownloads || VerifyDownload(filePath, file.MD5Hash))
            {
                // Register the file with the file store so further invocations
                // of the application don't unnecessarily download the file again
                fileStore.RegisterFile(file.MD5Hash, filePath);
            }
        }