/// <summary>
        /// Gets the download <see cref="Uri"/> for the specified file as an asynchronous operation.
        /// </summary>
        /// <param name="value">The <see cref="IMetadataApi"/> to get the download URI.</param>
        /// <param name="fileName">The name of the file to download.</param>
        /// <param name="fileHash">The hash of the file to download.</param>
        /// <returns>
        /// A <see cref="Task{T}"/> containing the <see cref="Uri"/> to download the file specified by
        /// <paramref name="fileName"/> and <paramref name="fileHash"/> from as an asynchronous operation.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="value"/> is <see langword="null"/>.
        /// </exception>
        public static async Task <Uri> GetDownloadUriAsync(this IMetadataApi value, string fileName, string fileHash)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            return(await value.GetDownloadUriAsync(fileName, fileHash, null, null));
        }
        public static async Task IMetadataApiExtensions_GetDownloadUriAsync_Throws_If_Value_Is_Null()
        {
            // Arrange
            IMetadataApi value = null;

            string fileName = "MyFileName.dts";
            string fileHash = "58b653e3762e8048995e00024a512c53";

            // Act and Assert
            await Assert.ThrowsAsync <ArgumentNullException>("value", () => value.GetDownloadUriAsync(fileName, fileHash));
        }
        public static async Task IMetadataApiExtensions_GetDownloadUriAsync_Calls_Interface_Method_With_No_File_Range()
        {
            // Arrange
            string fileName = "MyFileName.dts";
            string fileHash = "58b653e3762e8048995e00024a512c53";

            Uri uri = new Uri("https://dn.updates.qas.com/MyFile.dts");

            Mock <IMetadataApi> mock = new Mock <IMetadataApi>();

            mock.Setup((p) => p.GetDownloadUriAsync(fileName, fileHash, null, null))
            .ReturnsAsync(uri)
            .Verifiable();

            IMetadataApi value = mock.Object;

            // Act and Assert
            Uri result = await value.GetDownloadUriAsync(fileName, fileHash);

            mock.Verify();
            Assert.Same(uri, result);
        }
Exemplo n.º 4
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);
            }
        }