/// <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); }
/// <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); } }