public static bool ConnectToStorage(CloudMediaContext context, CredentialsEntry credentials) { try { CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(context.DefaultStorageAccount.Name, credentials.StorageKey), credentials.ReturnStorageSuffix(), true); CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient(); return true; } catch (Exception e) { MessageBox.Show(string.Format("There is a problem when connecting to the Azure storage account.\r\nIs the storage key correct ?\r\n{0}", e.Message), "Storage Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } }
private async void ProcessExportAssetToAnotherAMSAccount(CredentialsEntry DestinationCredentialsEntry, string DestinationStorageAccount, Dictionary<string, string> storagekeys, List<IAsset> SourceAssets, string TargetAssetName, int index, bool DeleteSourceAssets = false, bool CopyDynEnc = false, bool ReWriteLAURL = false, bool CloneAssetFilters = false) { // If upload in the queue, let's wait our turn DoGridTransferWaitIfNeeded(index); CloudMediaContext DestinationContext = Program.ConnectAndGetNewContext(DestinationCredentialsEntry); IAsset TargetAsset = DestinationContext.Assets.Create(TargetAssetName, DestinationStorageAccount, AssetCreationOptions.None); // let's backup the primary file from the first asset to set it to the copied/merged asset var ismAssetFile = SourceAssets.FirstOrDefault().AssetFiles.ToList().Where(f => f.IsPrimary).ToArray(); bool ErrorCopyAsset = false; TextBoxLogWriteLine("Starting the asset copy process."); // let's get cloudblobcontainer for target CloudStorageAccount DestinationCloudStorageAccount = (DestinationStorageAccount == null) ? new CloudStorageAccount(new StorageCredentials(DestinationContext.DefaultStorageAccount.Name, storagekeys[DestinationContext.DefaultStorageAccount.Name]), DestinationCredentialsEntry.ReturnStorageSuffix(), true) : new CloudStorageAccount(new StorageCredentials(DestinationStorageAccount, storagekeys[DestinationStorageAccount]), DestinationCredentialsEntry.ReturnStorageSuffix(), true); var DestinationCloudBlobClient = DestinationCloudStorageAccount.CreateCloudBlobClient(); IAccessPolicy writePolicy = DestinationContext.AccessPolicies.Create("writepolicy", TimeSpan.FromDays(1), AccessPermissions.Write); ILocator DestinationLocator = DestinationContext.Locators.CreateLocator(LocatorType.Sas, TargetAsset, writePolicy); // Get the asset container URI and copy blobs from mediaContainer to assetContainer. Uri targetUri = new Uri(DestinationLocator.Path); CloudBlobContainer DestinationCloudBlobContainer = DestinationCloudBlobClient.GetContainerReference(targetUri.Segments[1]); foreach (IAsset SourceAsset in SourceAssets) // there are several assets only if user wants to do a copy with merge { if (storagekeys.ContainsKey(SourceAsset.StorageAccountName)) { // let's get cloudblobcontainer for source CloudStorageAccount SourceCloudStorageAccount = new CloudStorageAccount(new StorageCredentials(SourceAsset.StorageAccountName, storagekeys[SourceAsset.StorageAccountName]), _credentials.ReturnStorageSuffix(), true); var SourceCloudBlobClient = SourceCloudStorageAccount.CreateCloudBlobClient(); IAccessPolicy readpolicy = _context.AccessPolicies.Create("readpolicy", TimeSpan.FromDays(1), AccessPermissions.Read); ILocator SourceLocator = _context.Locators.CreateLocator(LocatorType.Sas, SourceAsset, readpolicy); // Get the asset container URI and copy blobs from mediaContainer to assetContainer. Uri sourceUri = new Uri(SourceLocator.Path); CloudBlobContainer SourceCloudBlobContainer = SourceCloudBlobClient.GetContainerReference(sourceUri.Segments[1]); ErrorCopyAsset = false; CloudBlockBlob sourceCloudBlockBlob, destinationCloudBlockBlob; long Length = 0; long BytesCopied = 0; double percentComplete = 0; //calculate size foreach (IAssetFile file in SourceAsset.AssetFiles) { Length += file.ContentFileSize; } if (Length == 0) Length = 1; // as this could happen with Live archive and create a divide error // do the copy int nbblob = 0; // foreach (IAssetFile file in SourceAsset.AssetFiles) // For LIve archive, the folder for chiks are returnbed as files. So we detect this case and don't try to copy the folders as asset files IEnumerable<IAssetFile> assetFilesToCopy = SourceAsset.AssetFiles.ToList(); if ( assetFilesToCopy.Where(af => af.Name.Contains(".")).Count() == 2 && assetFilesToCopy.Where(af => af.Name.ToUpper().EndsWith(".ISMC")).Count() == 1 && assetFilesToCopy.Where(af => af.Name.ToUpper().EndsWith(".ISM")).Count() == 1 ) // only 2 files with extensions, and these files are ISMC and ISM { assetFilesToCopy = SourceAsset.AssetFiles.ToList().Where(af => !af.Name.StartsWith("audio_") && !af.Name.StartsWith("video_") && !af.Name.StartsWith("scte35_")); var assetFilesLiveFolders = SourceAsset.AssetFiles.ToList().Where(af => af.Name.StartsWith("audio_") || af.Name.StartsWith("video_") || af.Name.StartsWith("scte35_")); foreach (IAssetFile sourcefolder in assetFilesLiveFolders) { var folder = TargetAsset.AssetFiles.Create(sourcefolder.Name); folder.ContentFileSize = sourcefolder.ContentFileSize; folder.MimeType = sourcefolder.MimeType; folder.Update(); } } foreach (IAssetFile file in assetFilesToCopy) { if (file.IsEncrypted) { TextBoxLogWriteLine(" Cannot copy file '{0}' because it is encrypted.", file.Name, true); } else { bool ErrorCopyAssetFile = false; nbblob++; try { sourceCloudBlockBlob = SourceCloudBlobContainer.GetBlockBlobReference(file.Name); // TO DO: chek if this is a folder or a file sourceCloudBlockBlob.FetchAttributes(); if (sourceCloudBlockBlob.Properties.Length > 0) { if (!TargetAsset.AssetFiles.ToList().Any(f => f.Name == file.Name)) // file does not exist in the target asset { IAssetFile destinationAssetFile = TargetAsset.AssetFiles.Create(file.Name); destinationCloudBlockBlob = DestinationCloudBlobContainer.GetBlockBlobReference(destinationAssetFile.Name); try { destinationCloudBlockBlob.DeleteIfExists(); } catch { // exception if Blob does not exist, which is fine } destinationCloudBlockBlob.StartCopy(file.GetSasUri()); CloudBlockBlob blob; blob = (CloudBlockBlob)DestinationCloudBlobContainer.GetBlobReferenceFromServer(file.Name); while (blob.CopyState.Status == CopyStatus.Pending) { Task.Delay(TimeSpan.FromSeconds(0.5d)).Wait(); blob.FetchAttributes(); percentComplete = (Convert.ToDouble(nbblob) / Convert.ToDouble(SourceAsset.AssetFiles.Count())) * 100d * (long)(BytesCopied + blob.CopyState.BytesCopied) / Length; DoGridTransferUpdateProgressText(string.Format("File '{0}'", file.Name), (int)percentComplete, index); } if (blob.CopyState.Status == CopyStatus.Failed) { DoGridTransferDeclareError(index, blob.CopyState.StatusDescription); ErrorCopyAssetFile = true; ErrorCopyAsset = true; break; } destinationCloudBlockBlob.FetchAttributes(); destinationAssetFile.ContentFileSize = sourceCloudBlockBlob.Properties.Length; destinationAssetFile.Update(); if (sourceCloudBlockBlob.Properties.Length != destinationCloudBlockBlob.Properties.Length) { DoGridTransferDeclareError(index, "Error during blob copy."); ErrorCopyAssetFile = true; ErrorCopyAsset = true; break; } BytesCopied += sourceCloudBlockBlob.Properties.Length; percentComplete = (long)100 * (long)BytesCopied / (long)Length; } else // file already exists.Can occur with merge function { TextBoxLogWriteLine("Failed to copy file '{0} as file already exists in the destination asset.", file.Name, true); ErrorCopyAssetFile = true; } } } catch (Exception ex) { TextBoxLogWriteLine("Failed to copy file '{0}'", file.Name, true); DoGridTransferDeclareError(index, ex); ErrorCopyAsset = true; ErrorCopyAssetFile = true; } if (!ErrorCopyAssetFile) TextBoxLogWriteLine("File '{0}' copied.", file.Name); } } if (!ErrorCopyAsset) // let's do the copy of additional fragblob if there are { List<CloudBlobDirectory> ListDirectories = new List<CloudBlobDirectory>(); // do the copy nbblob = 0; DoGridTransferUpdateProgressText(string.Format("fragblobs", SourceAsset.Name, DestinationCredentialsEntry.AccountName), 0, index); try { var mediablobs = SourceCloudBlobContainer.ListBlobs(); if (mediablobs.ToList().Any(b => b.GetType() == typeof(CloudBlobDirectory))) // there are fragblobs { List<Task> mylistresults = new List<Task>(); foreach (var blob in mediablobs) { if (blob.GetType() == typeof(CloudBlobDirectory)) { CloudBlobDirectory blobdir = (CloudBlobDirectory)blob; ListDirectories.Add(blobdir); TextBoxLogWriteLine("Fragblobs detected (live archive) '{0}'.", blobdir.Prefix); } else if (blob.GetType() == typeof(CloudBlockBlob)) { // we must copy the file.ismc too var blockblob = (CloudBlockBlob)blob; if (blockblob.Name.EndsWith(".ismc") && !SourceAsset.AssetFiles.ToList().Any(f => f.Name == blockblob.Name)) // if there is a .ismc in the blov and not in the asset files, then we need to copy it { CloudBlockBlob targetBlob = DestinationCloudBlobContainer.GetBlockBlobReference(blockblob.Name); // copy using src blob as SAS mylistresults.Add(targetBlob.StartCopyAsync(new Uri(blockblob.Uri.AbsoluteUri + SourceLocator.ContentAccessComponent))); } } } // let's launch the copy of fragblobs double ind = 0; foreach (var dir in ListDirectories) { TextBoxLogWriteLine("Copying fragblobs directory '{0}'....", dir.Prefix); mylistresults.AddRange(AssetInfo.CopyBlobDirectory(dir, DestinationCloudBlobContainer, SourceLocator.ContentAccessComponent));//blobToken)); if (mylistresults.Count > 0) { while (!mylistresults.All(r => r.IsCompleted)) { Task.Delay(TimeSpan.FromSeconds(3d)).Wait(); percentComplete = 100d * (ind + Convert.ToDouble(mylistresults.Where(c => c.IsCompleted).Count()) / Convert.ToDouble(mylistresults.Count)) / Convert.ToDouble(ListDirectories.Count); DoGridTransferUpdateProgressText(string.Format("fragblobs directory '{0}' ({1}/{2})", dir.Prefix, mylistresults.Where(r => r.IsCompleted).Count(), mylistresults.Count), (int)percentComplete, index); } } ind++; mylistresults.Clear(); } } } catch (Exception ex) { TextBoxLogWriteLine("Failed to copy live fragblobs", true); TextBoxLogWriteLine(ex); DoGridTransferDeclareError(index, ex); ErrorCopyAsset = true; } } SourceLocator.Delete(); readpolicy.Delete(); } else { TextBoxLogWriteLine("Error storage key not found for asset '{0}'.", SourceAsset.Name, true); ErrorCopyAsset = true; } } // let's set the primary file if (ismAssetFile.Count() > 0) { AssetInfo.SetFileAsPrimary(TargetAsset, ismAssetFile.FirstOrDefault().Name); } else { AssetInfo.SetISMFileAsPrimary(TargetAsset); } // Copy Dynamic Encryption if (CopyDynEnc && !ErrorCopyAsset) { TextBoxLogWriteLine("Dynamic encryption settings copy..."); try { await DynamicEncryption.CopyDynamicEncryption(SourceAssets.FirstOrDefault(), TargetAsset, ReWriteLAURL); TextBoxLogWriteLine("Dynamic encryption settings copied."); } catch (Exception ex) { TextBoxLogWriteLine("Error when copying Dynamic encryption", true); TextBoxLogWriteLine(ex); } } // Copy filters if (CloneAssetFilters && !ErrorCopyAsset && SourceAssets.FirstOrDefault().AssetFilters.Count() > 0) { try { TextBoxLogWriteLine("Copying filter(s) to cloned asset '{0}'", SourceAssets.FirstOrDefault().Name); foreach (var filter in SourceAssets.FirstOrDefault().AssetFilters) { TargetAsset.AssetFilters.Create(filter.Name, filter.PresentationTimeRange, filter.Tracks); TextBoxLogWriteLine(string.Format("Cloned filter {0} created.", filter.Name)); } } catch (Exception ex) { // Add useful information to the exception TextBoxLogWriteLine("There is a problem when copying filter(s) to the asset '{0}'.", TargetAsset.Name, true); TextBoxLogWriteLine(ex); } } DestinationLocator.Delete(); writePolicy.Delete(); if (!ErrorCopyAsset) { if (DeleteSourceAssets) SourceAssets.ForEach(a => a.Delete()); TextBoxLogWriteLine("Asset copy completed. The new asset in '{0}' has the Id :", DestinationCredentialsEntry.AccountName); TextBoxLogWriteLine(TargetAsset.Id); DoGridTransferDeclareCompleted(index, DestinationCloudBlobContainer.Uri.AbsoluteUri); } DoRefreshGridAssetV(false); }