Skip to content

Commit

Permalink
add reset command
Browse files Browse the repository at this point in the history
  • Loading branch information
melindawangmsft committed Aug 7, 2023
1 parent 32dcbe4 commit e743e2c
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 28 deletions.
28 changes: 26 additions & 2 deletions Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using AMSMigrate.Ams;
using AMSMigrate.ams;
using AMSMigrate.Ams;
using AMSMigrate.Azure;
using AMSMigrate.Contracts;
using AMSMigrate.Local;
Expand Down Expand Up @@ -75,6 +76,21 @@ This command forcefully removes the Azure Media Services (AMS) account.
await CleanupAsync(context, cleanupOptions, context.GetCancellationToken());
});

var resetOptionsBinder = new ResetOptionsBinder();
var resetCommand = resetOptionsBinder.GetCommand("reset", @"Reset assets back to their original NotMigrated state in the AMS account
Examples to reset assets in the AMS account:
reset -s <subscriptionid> -g <resourcegroup> -n <account> -a true
This command will forcibly revert all assets in the Azure Media Services (AMS) account to their initial NotMigrated state.
reset -s <subscriptionid> -g <resourcegroup> -n <account> -f true
This command will forcefully revert migrated assets that have failed back to their original NotMigrated state within the Azure Media Services (AMS) account.");
rootCommand.Add(resetCommand);
resetCommand.SetHandler(
async context =>
{
var resetOptions =resetOptionsBinder.GetValue(context.BindingContext);
await ResetAsync(context, resetOptions, context.GetCancellationToken());
});

// disable storage migrate option until ready
/*
var storageOptionsBinder = new StorageOptionsBinder();
Expand Down Expand Up @@ -223,7 +239,15 @@ static async Task CleanupAsync(
await ActivatorUtilities.CreateInstance<CleanupCommand>(provider, cleanupOptions)
.MigrateAsync(cancellationToken);
}

static async Task ResetAsync(
InvocationContext context,
ResetOptions resetOptions,
CancellationToken cancellationToken)
{
var provider = context.BindingContext.GetRequiredService<IServiceProvider>();
await ActivatorUtilities.CreateInstance<ResetCommand>(provider, resetOptions)
.MigrateAsync(cancellationToken);
}

static async Task MigrateKeysAsync(
InvocationContext context,
Expand Down
25 changes: 23 additions & 2 deletions ResetOptionsBinder.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
using System;
using AMSMigrate.Contracts;
using FFMpegCore.Enums;
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Binding;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AMSMigrate
{
internal class ResetOptionsBinder
internal class ResetOptionsBinder : BinderBase<ResetOptions>
{
private readonly Option<string> _sourceAccount = new Option<string>(
aliases: new[] { "--source-account-name", "-n" },
Expand All @@ -29,6 +32,24 @@ internal class ResetOptionsBinder
{
IsRequired = false
};
public ResetOptions GetValue(BindingContext context) => GetBoundValue(context);

public Command GetCommand(string name, string description)
{
var command = new Command(name, description);
command.AddOption(_sourceAccount);
command.AddOption(_all);
command.AddOption(_failed);
return command;
}

protected override ResetOptions GetBoundValue(BindingContext bindingContext)
{
return new ResetOptions(
bindingContext.ParseResult.GetValueForOption(_sourceAccount)!,
bindingContext.ParseResult.GetValueForOption(_all),
bindingContext.ParseResult.GetValueForOption(_failed)
);
}
}
}
7 changes: 7 additions & 0 deletions ams/AssetMigrationTracker.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using AMSMigrate.Contracts;
using Azure;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;

Expand Down Expand Up @@ -64,6 +65,12 @@ internal class AssetMigrationTracker : IMigrationTracker<BlobContainerClient, As
internal const string MigrateResultKey = "MigrateResult";
internal const string ManifestNameKey = "ManifestName";
internal const string OutputPathKey = "OutputPath";

public async Task<bool> DeleteMigrationStatus(BlobContainerClient container,string MigratedBlobName)
{
return await container.DeleteBlobIfExistsAsync(MigratedBlobName);
}


public async Task<AssetMigrationResult> GetMigrationStatusAsync(BlobContainerClient container, CancellationToken cancellationToken)
{
Expand Down
12 changes: 6 additions & 6 deletions ams/CleanupCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Azure;
using Azure.Core;
using Azure.ResourceManager.Media;
using Azure.ResourceManager.Media.Models;
using Azure.Storage.Blobs;
using Microsoft.Extensions.Logging;
using Spectre.Console;
Expand Down Expand Up @@ -46,12 +47,6 @@ public override async Task MigrateAsync(CancellationToken cancellationToken)
}

Dictionary<string, bool> stats = new Dictionary<string, bool>();
var totalAssets = await QueryMetricAsync(
account.Id.ToString(),
"AssetCount",
cancellationToken: cancellationToken);

_logger.LogInformation("The total asset count of the media account is {count}.", totalAssets);
AsyncPageable<MediaAssetResource> assets;

//clean up asset
Expand Down Expand Up @@ -111,6 +106,7 @@ private async Task<bool> CleanUpAccountAsync(MediaServicesAccountResource accoun
{
foreach (var streamingEndpoint in endpoints)
{
await streamingEndpoint.StopAsync(WaitUntil.Completed);
await streamingEndpoint.DeleteAsync(WaitUntil.Completed);
}
}
Expand All @@ -125,6 +121,10 @@ private async Task<bool> CleanUpAccountAsync(MediaServicesAccountResource accoun
{
foreach (var liveEvent in liveevents)
{
if (liveEvent?.Data.ResourceState == LiveEventResourceState.Running)
{
await liveEvent.StopAsync(WaitUntil.Completed, new LiveEventActionContent() { RemoveOutputsOnStop = true });
}
await liveEvent.DeleteAsync(WaitUntil.Completed);

Check warning on line 128 in ams/CleanupCommand.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.

Check warning on line 128 in ams/CleanupCommand.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
}
}
Expand Down
51 changes: 33 additions & 18 deletions ams/ResetCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,9 @@
using Azure.Core;
using Azure.ResourceManager.Media;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using Microsoft.Extensions.Logging;
using Spectre.Console;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AMSMigrate.ams
{
Expand All @@ -36,19 +31,13 @@ public ResetCommand(GlobalOptions globalOptions,
public override async Task MigrateAsync(CancellationToken cancellationToken)
{
var account = await GetMediaAccountAsync(_options.AccountName, cancellationToken);
_logger.LogInformation("Begin cleaning up on account: {name}", account.Data.Name);
_logger.LogInformation("Begin reset assets on account: {name}", account.Data.Name);

var storage = await _resourceProvider.GetStorageAccountAsync(account, cancellationToken);
var totalAssets = await QueryMetricAsync(
account.Id.ToString(),
"AssetCount",
cancellationToken: cancellationToken);

_logger.LogInformation("The total asset count of the media account is {count}.", totalAssets);
var storage = await _resourceProvider.GetStorageAccountAsync(account, cancellationToken);
AsyncPageable<MediaAssetResource> assets = account.GetMediaAssets()
.GetAllAsync(cancellationToken: cancellationToken);
List<MediaAssetResource>? assetList = await assets.ToListAsync(cancellationToken);

int resetedAssetCount = 0;
foreach (var asset in assetList)
{
var container = storage.GetContainer(asset);
Expand All @@ -58,13 +47,39 @@ public override async Task MigrateAsync(CancellationToken cancellationToken)
return;
}

// The asset container exists, try to check the metadata list first.

if (_options.all || (_tracker.GetMigrationStatusAsync(container, cancellationToken).Result.Status == MigrationStatus.Failed))
{
container.DeleteBlobAsync(cancellationToken);
try
{
BlobContainerProperties properties = await container.GetPropertiesAsync(cancellationToken: cancellationToken);
if (properties.Metadata != null && properties.Metadata.Count == 0)
{
_logger.LogInformation($"Container '{container.Name}' does not have metadata.");
}
else
{ // Clear container metadata
properties.Metadata.Clear();

Check warning on line 61 in ams/ResetCommand.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.

Check warning on line 61 in ams/ResetCommand.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
var deleteOperation = await container.SetMetadataAsync(properties.Metadata);
if (deleteOperation.GetRawResponse().Status == 200)
{
_logger.LogInformation($"Meda data in Container '{container.Name}' is deleted successfully.");
resetedAssetCount++;
}
else
{
_logger.LogInformation($"Meda data in Container '{container.Name}' does not exist or was not deleted.");
}
}

}
catch (Exception ex)
{
_logger.LogError($"An unexpected error occurred: {ex.Message}");
}

}
}
_logger.LogDebug($"{resetedAssetCount} out of {assetList.Count} assets has been reseted.");
}
}
}
2 changes: 2 additions & 0 deletions contracts/IMigrationTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ interface IMigrationTracker<T, TResult> where TResult : MigrationResult
Task<TResult> GetMigrationStatusAsync(T resource, CancellationToken cancellationToken);

Task UpdateMigrationStatus(T resource, TResult result, CancellationToken cancellationToken);

Task<bool> DeleteMigrationStatus(T resource, string MigratedBlobName);
}
}

0 comments on commit e743e2c

Please sign in to comment.