/// <summary> /// Creates the manifest asset file asynchronously. /// </summary> /// <param name="ingestManifestAsset">The parent manifest asset.</param> /// <param name="filePath">The file path.</param> /// <param name="token"><see cref="CancellationToken"/></param> /// <returns><see cref="Task"/>of type <see cref="IIngestManifestFile"/></returns> public Task <IIngestManifestFile> CreateAsync(IIngestManifestAsset ingestManifestAsset, string filePath, CancellationToken token) { if (ingestManifestAsset == null) { throw new ArgumentNullException("ingestManifestAsset"); } if (string.IsNullOrWhiteSpace(filePath)) { throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, StringTable.ErrorCreatingIngestManifestFileEmptyFilePath)); } AssetCreationOptions options = ingestManifestAsset.Asset.Options; Task <IIngestManifestFile> rootTask = new Task <IIngestManifestFile>(() => { token.ThrowIfCancellationRequested(); IngestManifestAssetCollection.VerifyManifestAsset(ingestManifestAsset); if (!File.Exists(filePath)) { throw new FileNotFoundException(String.Format(CultureInfo.InvariantCulture, StringTable.BulkIngestProvidedFileDoesNotExist, filePath)); } FileInfo info = new FileInfo(filePath); DataServiceContext dataContext = this._cloudMediaContext.DataContextFactory.CreateDataServiceContext(); // Set a MIME type based on the extension of the file name string mimeType = AssetFileData.GetMimeType(filePath); IngestManifestFileData data = new IngestManifestFileData { Name = info.Name, MimeType = mimeType, ParentIngestManifestId = ingestManifestAsset.ParentIngestManifestId, ParentIngestManifestAssetId = ingestManifestAsset.Id, Path = filePath, }; SetEncryptionSettings(ingestManifestAsset, info, options, data); dataContext.AddObject(EntitySet, data); Task <IIngestManifestFile> task = dataContext.SaveChangesAsync(data).ContinueWith <IIngestManifestFile>(t => { t.ThrowIfFaulted(); token.ThrowIfCancellationRequested(); IngestManifestFileData ingestManifestFile = (IngestManifestFileData)t.AsyncState; return(ingestManifestFile); }); return(task.Result); }); rootTask.Start(); return(rootTask); }
/// <summary> /// Creates the manifest asset file asynchronously. /// </summary> /// <param name="ingestManifestAsset">The parent manifest asset.</param> /// <param name="filePath">The file path.</param> /// <param name="token"><see cref="CancellationToken"/></param> /// <returns><see cref="Task"/>of type <see cref="IIngestManifestFile"/></returns> public Task <IIngestManifestFile> CreateAsync(IIngestManifestAsset ingestManifestAsset, string filePath, CancellationToken token) { if (ingestManifestAsset == null) { throw new ArgumentNullException("ingestManifestAsset"); } if (string.IsNullOrWhiteSpace(filePath)) { throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, StringTable.ErrorCreatingIngestManifestFileEmptyFilePath)); } AssetCreationOptions options = ingestManifestAsset.Asset.Options; Task <IIngestManifestFile> rootTask = new Task <IIngestManifestFile>(() => { token.ThrowIfCancellationRequested(); IngestManifestAssetCollection.VerifyManifestAsset(ingestManifestAsset); IMediaDataServiceContext dataContext = this.MediaContext.MediaServicesClassFactory.CreateDataServiceContext(); // Set a MIME type based on the extension of the file name string mimeType = AssetFileData.GetMimeType(filePath); IngestManifestFileData data = new IngestManifestFileData { Name = Path.GetFileName(filePath), MimeType = mimeType, ParentIngestManifestId = ingestManifestAsset.ParentIngestManifestId, ParentIngestManifestAssetId = ingestManifestAsset.Id, Path = filePath, }; SetEncryptionSettings(ingestManifestAsset, options, data); dataContext.AddObject(EntitySet, data); MediaRetryPolicy retryPolicy = this.MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); Task <IIngestManifestFile> task = retryPolicy.ExecuteAsync <IMediaDataServiceResponse>(() => dataContext.SaveChangesAsync(data)) .ContinueWith <IIngestManifestFile>(t => { t.ThrowIfFaulted(); token.ThrowIfCancellationRequested(); IngestManifestFileData ingestManifestFile = (IngestManifestFileData)t.Result.AsyncState; return(ingestManifestFile); }); return(task.Result); }); rootTask.Start(); return(rootTask); }
private static Action GetEncryptionAction( CancellationToken cancellationToken, FileEncryption fileEncryption, IngestManifestFileData file, string destinationPath, FileInfo fileInfo, ConcurrentQueue <Tuple <int, int> > queue, int maxBlockSize) { Action action = () => { cancellationToken.ThrowIfCancellationRequested(); if (queue.Count > 0) { using (var fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read)) { Tuple <int, int> blockIdAndLength; while (queue.TryDequeue(out blockIdAndLength)) { cancellationToken.ThrowIfCancellationRequested(); var buffer = new byte[blockIdAndLength.Item2]; var binaryReader = new BinaryReader(fs); // Move the file system reader to the proper position. fs.Seek(blockIdAndLength.Item1 * (long)maxBlockSize, SeekOrigin.Begin); int readSize = binaryReader.Read(buffer, 0, blockIdAndLength.Item2); while (readSize != blockIdAndLength.Item2) { readSize += binaryReader.Read(buffer, readSize, blockIdAndLength.Item2 - readSize); } bool lockWasTakenForEncode = false; try { Monitor.Enter(fileEncryption, ref lockWasTakenForEncode); using (FileEncryptionTransform encryptor = fileEncryption.GetTransform(file.Name, blockIdAndLength.Item1 * (long)maxBlockSize)) { encryptor.TransformBlock(buffer, 0, readSize, buffer, 0); } } finally { if (lockWasTakenForEncode) { Monitor.Exit(fileEncryption); } } bool lockWasTakenForWrite = false; try { Monitor.Enter(file, ref lockWasTakenForWrite); using (var writeStream = new FileStream(destinationPath, FileMode.Open, FileAccess.Write)) { writeStream.Seek(blockIdAndLength.Item1 * (long)maxBlockSize, SeekOrigin.Begin); writeStream.Write(buffer, 0, readSize); } } finally { if (lockWasTakenForWrite) { Monitor.Exit(file); } } } } } }; return(action); }
private static Action GetEncryptionAction( CancellationToken cancellationToken, FileEncryption fileEncryption, IngestManifestFileData file, string destinationPath, FileInfo fileInfo, ConcurrentQueue<Tuple<int, int>> queue, int maxBlockSize) { Action action = () => { cancellationToken.ThrowIfCancellationRequested(); if (queue.Count > 0) { using (var fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read)) { Tuple<int, int> blockIdAndLength; while (queue.TryDequeue(out blockIdAndLength)) { cancellationToken.ThrowIfCancellationRequested(); var buffer = new byte[blockIdAndLength.Item2]; var binaryReader = new BinaryReader(fs); // Move the file system reader to the proper position. fs.Seek(blockIdAndLength.Item1*(long) maxBlockSize, SeekOrigin.Begin); int readSize = binaryReader.Read(buffer, 0, blockIdAndLength.Item2); while (readSize != blockIdAndLength.Item2) { readSize += binaryReader.Read(buffer, readSize, blockIdAndLength.Item2 - readSize); } bool lockWasTakenForEncode = false; try { Monitor.Enter(fileEncryption, ref lockWasTakenForEncode); using (FileEncryptionTransform encryptor = fileEncryption.GetTransform(file.Name, blockIdAndLength.Item1*(long) maxBlockSize)) { encryptor.TransformBlock(buffer, 0, readSize, buffer, 0); } } finally { if (lockWasTakenForEncode) Monitor.Exit(fileEncryption); } bool lockWasTakenForWrite = false; try { Monitor.Enter(file, ref lockWasTakenForWrite); using (var writeStream = new FileStream(destinationPath, FileMode.Open, FileAccess.Write)) { writeStream.Seek(blockIdAndLength.Item1*(long) maxBlockSize, SeekOrigin.Begin); writeStream.Write(buffer, 0, readSize); } } finally { if (lockWasTakenForWrite) Monitor.Exit(file); } } } } }; return action; }
private static void SetEncryptionSettings(IIngestManifestAsset ingestManifestAsset, AssetCreationOptions options, IngestManifestFileData data) { if (options.HasFlag(AssetCreationOptions.StorageEncrypted)) { var contentKeyData = ingestManifestAsset.Asset.ContentKeys.Where(c => c.ContentKeyType == ContentKeyType.StorageEncryption).FirstOrDefault(); if (contentKeyData == null) { throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, StringTable.StorageEncryptionContentKeyIsMissing, ingestManifestAsset.Asset.Id)); } using (var fileEncryption = new FileEncryption(contentKeyData.GetClearKeyValue(), EncryptionUtils.GetKeyIdAsGuid(contentKeyData.Id))) { if (!fileEncryption.IsInitializationVectorPresent(data.Name)) { fileEncryption.CreateInitializationVectorForFile(data.Name); } ulong iv = fileEncryption.GetInitializationVectorForFile(data.Name); data.IsEncrypted = true; data.EncryptionKeyId = fileEncryption.GetKeyIdentifierAsString(); data.EncryptionScheme = FileEncryption.SchemeName; data.EncryptionVersion = FileEncryption.SchemeVersion; data.InitializationVector = iv.ToString(CultureInfo.InvariantCulture); } } else if (options.HasFlag(AssetCreationOptions.CommonEncryptionProtected)) { data.IsEncrypted = true; data.EncryptionScheme = CommonEncryption.SchemeName; data.EncryptionVersion = CommonEncryption.SchemeVersion; } else if (options.HasFlag(AssetCreationOptions.EnvelopeEncryptionProtected)) { data.IsEncrypted = true; data.EncryptionScheme = EnvelopeEncryption.SchemeName; data.EncryptionVersion = EnvelopeEncryption.SchemeVersion; } }