/// <summary> /// Asynchronously creates new Program. /// </summary> /// <param name="options">Program creation options.</param> /// <returns>The task to create the program.</returns> public Task <IProgram> CreateAsync(ProgramCreationOptions options) { if (options == null) { throw new ArgumentNullException("options"); } if (string.IsNullOrEmpty(options.Name)) { throw new ArgumentException(Resources.ErrorEmptyProgramName); } if (_parentChannel == null) { throw new InvalidOperationException(Resources.ErrorOrphanProgram); } var program = new ProgramData { Name = options.Name, Description = options.Description, ChannelId = _parentChannel.Id, AssetId = options.AssetId, ArchiveWindowLength = options.ArchiveWindowLength, ManifestName = options.ManifestName }; program.SetMediaContext(MediaContext); IMediaDataServiceContext dataContext = MediaContext.MediaServicesClassFactory.CreateDataServiceContext(); dataContext.AddObject(ProgramSet, program); MediaRetryPolicy retryPolicy = MediaContext.MediaServicesClassFactory.GetSaveChangesRetryPolicy(dataContext as IRetryPolicyAdapter); return(retryPolicy.ExecuteAsync(() => dataContext.SaveChangesAsync(program)) .ContinueWith <IProgram>(t => { t.ThrowIfFaulted(); return (ProgramData)t.Result.AsyncState; })); }
private async void DoResetPrograms() { List<IProgram> SelectedPrograms = ReturnSelectedPrograms(); if (SelectedPrograms.FirstOrDefault() != null) { if (SelectedPrograms.Count > 0) { string question = (SelectedPrograms.Count == 1) ? string.Format("Reset program '{0}' ?", SelectedPrograms[0].Name) : string.Format("Reset these {0} programs ?", SelectedPrograms.Count); question += Constants.endline + Constants.endline + "This will delete the program, the related asset and locator and will re-create them with the same ISM file name, locator ID, keys, delivery policies and filters."; question += Constants.endline + Constants.endline + "WARNING: As the new asset will use the same locator ID, this can create issues. Notes:"; question += Constants.endline + "- Encoder must use incremental timestamps"; question += Constants.endline + "- Locator GUID are cached by the streaming endpoints for 5 minutes"; question += Constants.endline + "- The old live archive manifest could have been be cached"; if (MessageBox.Show(question, "Program(s) reset", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK) { foreach (IProgram myP in SelectedPrograms) { if (myP.State != ProgramState.Stopped) // program is not stopped { TextBoxLogWriteLine("Program '{0}' must be stopped in order to reset it. Operation aborted.", myP.Name, true); } else // program is stopped { IAsset asset = myP.Asset; IAsset newAsset = null; string assetName = asset.Name; // backup the asset name string assetstorageaccount = asset.StorageAccountName; // backup the storage account name string programName = myP.Name; // backup program name string programDesc = myP.Description; // backup program description TimeSpan programArchiveWindowLength = myP.ArchiveWindowLength; var locator = asset.Locators.Where(l => l.Type == LocatorType.OnDemandOrigin).ToArray(); IChannel myChannel = myP.Channel; var ismAssetFiles = asset.AssetFiles.ToList().Where(f => f.Name.EndsWith(".ism", StringComparison.OrdinalIgnoreCase)).ToArray(); if (locator.Count() != 1) // no single locator, we do nothing { TextBoxLogWriteLine("Asset of program '{0}' does not have a single locator. Operation aborted.", myP.Name, true); } else if (ismAssetFiles.Count() != 1) { TextBoxLogWriteLine("Asset of program '{0}' does not have a ISM file. Operation aborted.", myP.Name, true); } else { string ismName = Path.GetFileNameWithoutExtension(ismAssetFiles.FirstOrDefault().Name); string locatorID = locator.FirstOrDefault().Id; DateTime locatorExpDateTime = locator.FirstOrDefault().ExpirationDateTime; try { TextBoxLogWriteLine("Deleting program '{0}'", myP.Name); myP.Delete(); } catch (Exception ex) { // Add useful information to the exception TextBoxLogWriteLine("There is a problem when deleting the program {0}.", myP.Name, true); TextBoxLogWriteLine(ex); } try { newAsset = _context.Assets.Create(assetName, assetstorageaccount, AssetCreationOptions.None); } catch (Exception ex) { // Add useful information to the exception TextBoxLogWriteLine("There is a problem when creating the new asset {0}.", assetName, true); TextBoxLogWriteLine(ex); } if (asset != null) { //let's copy the keys foreach (var key in asset.ContentKeys) { newAsset.ContentKeys.Add(key); } //let's copy the policies foreach (var delpol in asset.DeliveryPolicies) { newAsset.DeliveryPolicies.Add(delpol); } //let's copy the filters foreach (var filter in asset.AssetFilters) { try { newAsset.AssetFilters.Create(filter.Name, filter.PresentationTimeRange, filter.Tracks); } catch (Exception ex) { TextBoxLogWriteLine("There is a problem when copying filter {0} the new asset {1}.", filter.Name, assetName, true); TextBoxLogWriteLine(ex); } } //delete try { TextBoxLogWriteLine("Deleting asset '{0}'", asset.Name); DeleteAsset(asset); if (AssetInfo.GetAsset(asset.Id, _context) == null) TextBoxLogWriteLine("Deletion done."); } catch (Exception ex) { // Add useful information to the exception TextBoxLogWriteLine("There is a problem when deleting the asset {0}.", asset.Name, true); TextBoxLogWriteLine(ex); } } // let's use the same expiration date than previous locator IAccessPolicy policy = _context.AccessPolicies.Create("AP:" + assetName, locatorExpDateTime.Subtract(DateTime.UtcNow), AccessPermissions.Read); try { TextBoxLogWriteLine("Creating locator for asset '{0}'", asset.Name); ILocator locat = _context.Locators.CreateLocator(locatorID, LocatorType.OnDemandOrigin, newAsset, policy, null); } catch (Exception ex) { // Add useful information to the exception TextBoxLogWriteLine("There is a problem when creating the locator for the asset '{0}'.", asset.Name, true); TextBoxLogWriteLine(ex); } ProgramCreationOptions options = new ProgramCreationOptions() { AssetId = newAsset.Id, Name = programName, Description = programDesc, ArchiveWindowLength = programArchiveWindowLength, ManifestName = ismName, }; await Task.Run(() => ProgramExecuteAsync(() => myChannel.Programs.CreateAsync(options), programName, "created")); } } } DoRefreshGridProgramV(false); DoRefreshGridAssetV(false); } } } }
private async void DoCreateProgram() { IChannel channel = ReturnSelectedChannels().FirstOrDefault(); if (channel != null) { CreateProgram form = new CreateProgram(_context) { ChannelName = channel.Name, archiveWindowLength = new TimeSpan(4, 0, 0), CreateLocator = true, EnableDynEnc = false, StartProgram = false, ProposeStartProgram = (channel.State == ChannelState.Running), AssetName = Constants.NameconvChannel + "-" + Constants.NameconvProgram, ProposeScaleUnit = _context.StreamingEndpoints.Where(o => o.ScaleUnits > 0).ToList().Count == 0 }; if (form.ShowDialog() == DialogResult.OK) { if (form.ScaleUnit) { Task.Run(async () => { await ScaleStreamingEndpoint(_context.StreamingEndpoints.FirstOrDefault(), 1); }); } TextBoxLogWriteLine("Creating Program '{0}'...", form.ProgramName); string assetname = form.AssetName.Replace(Constants.NameconvProgram, form.ProgramName).Replace(Constants.NameconvChannel, form.ChannelName); IAsset NewAsset; if (form.IsReplica) // special case. We want to create a program with a specific manifest name, locator GUID and encryption key { NewAsset = CreateLiveAssetWithOptionalpecifiedLocatorID(assetname, form.StorageSelected, true, form.EnableDynEnc, form.ReplicaLocatorID); } else // normal case { NewAsset = CreateLiveAssetWithOptionalpecifiedLocatorID(assetname, form.StorageSelected, form.CreateLocator, form.EnableDynEnc); } if (NewAsset != null) { var options = new ProgramCreationOptions() { Name = form.ProgramName, Description = form.ProgramDescription, ArchiveWindowLength = form.archiveWindowLength, AssetId = NewAsset.Id, ManifestName = form.ForceManifestName // if replica is selected or force manifest name is pecified, then we force the manifest name }; var STask = ProgramExecuteAsync( () => channel.Programs.CreateAsync(options), form.ProgramName, "created"); await STask; DoRefreshGridProgramV(false); if (form.StartProgram) { Task.Run(async () => { // let's start the program now IProgram program = _context.Programs.Where(p => p.Name == form.ProgramName && p.ChannelId == channel.Id).FirstOrDefault(); await StartProgramASync(program); } ); } } DoRefreshGridAssetV(false); } } else { MessageBox.Show("No channel has been selected."); } }
private async void ProcessCloneProgramToAnotherAMSAccount(CredentialsEntry DestinationCredentialsEntry, string DestinationStorageAccount, IProgram sourceProgram, bool CopyDynEnc, bool RewriteLAURL, bool CloneLocators, bool CloneAssetFilters) { TextBoxLogWriteLine("Starting the program cloning process."); CloudMediaContext DestinationContext = Program.ConnectAndGetNewContext(DestinationCredentialsEntry); // let's check that target channel exists IChannel clonedchannel = DestinationContext.Channels.Where(c => c.Name == sourceProgram.Channel.Name).FirstOrDefault(); if (clonedchannel == null) { TextBoxLogWriteLine(string.Format("Cloned channel '{0}' not found in destination account!", sourceProgram.Channel.Name), true); return; } // let's check that a program with same name does not already exist for the channel if (DestinationContext.Programs.Where(p => p.Name == sourceProgram.Name && p.ChannelId == clonedchannel.Id).FirstOrDefault() != null) { TextBoxLogWriteLine(string.Format("A program '{0}' has been already found in destination account for channel '{1}'. A new one cannot be created.", sourceProgram.Name, clonedchannel.Name), true); return; } // Cloned asset creation IAsset clonedAsset = DestinationContext.Assets.Create(sourceProgram.Asset.Name, DestinationStorageAccount, AssetCreationOptions.None); TextBoxLogWriteLine(string.Format("Cloned asset {0} created.", sourceProgram.Asset.Name)); if (CopyDynEnc) { TextBoxLogWriteLine("Dynamic encryption settings copy..."); try { await DynamicEncryption.CopyDynamicEncryption(sourceProgram.Asset, clonedAsset, RewriteLAURL); TextBoxLogWriteLine("Dynamic encryption settings copied."); } catch (Exception ex) { TextBoxLogWriteLine("Error when copying Dynamic encryption", true); TextBoxLogWriteLine(ex); } } if (CloneLocators) { try { TextBoxLogWriteLine("Creating locator for cloned asset '{0}'", sourceProgram.Asset.Name); foreach (var streamlocator in sourceProgram.Asset.Locators.Where(l => l.Type == LocatorType.OnDemandOrigin)) { IAccessPolicy policy = DestinationContext.AccessPolicies.Create("AP:" + sourceProgram.Asset.Name, (streamlocator.ExpirationDateTime - DateTime.UtcNow), AccessPermissions.Read); DestinationContext.Locators.CreateLocator(streamlocator.Id, LocatorType.OnDemandOrigin, clonedAsset, policy, streamlocator.StartTime); TextBoxLogWriteLine(string.Format("Cloned locator {0} created.", streamlocator.Id)); } } catch (Exception ex) { // Add useful information to the exception TextBoxLogWriteLine("There is a problem when creating the locator for the asset '{0}'.", clonedAsset.Name, true); TextBoxLogWriteLine(ex); } } if (CloneAssetFilters && sourceProgram.Asset.AssetFilters.Count() > 0) { try { TextBoxLogWriteLine("Copying filter(s) to cloned asset '{0}'", sourceProgram.Asset.Name); foreach (var filter in sourceProgram.Asset.AssetFilters) { // let's remove start and end time var PTR = new PresentationTimeRange(filter.PresentationTimeRange.Timescale, null, null, filter.PresentationTimeRange.PresentationWindowDuration, filter.PresentationTimeRange.LiveBackoffDuration); clonedAsset.AssetFilters.Create(filter.Name, PTR, 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}'.", clonedAsset.Name, true); TextBoxLogWriteLine(ex); } } var options = new ProgramCreationOptions() { Name = sourceProgram.Name, Description = sourceProgram.Description, ArchiveWindowLength = sourceProgram.ArchiveWindowLength, AssetId = clonedAsset.Id, ManifestName = sourceProgram.ManifestName }; var STask = ProgramExecuteAsync( () => clonedchannel.Programs.CreateAsync(options), sourceProgram.Name, "created"); await STask; TextBoxLogWriteLine(string.Format("Cloned program {0} created.", sourceProgram.Name)); }
/// <summary> /// Creates new Program. /// </summary> /// <param name="options">Program creation options.</param> /// <returns>The created program.</returns> public IProgram Create(ProgramCreationOptions options) { return(AsyncHelper.Wait(CreateAsync(options))); }