public int DeletePath(string path) { int itemsDeleted = 0; BlobUrl url = new BlobUrl(path); if (url.Kind == BlobUrlKind.Account) { throw new Exception("Deletion of storage account is not implemented."); } else if (url.Kind == BlobUrlKind.Container) { DeleteContainer(url.Url); itemsDeleted++; } else if (url.Kind == BlobUrlKind.SubfolderOrBlob) { if (BlobExists(url.Url)) { DeleteBlob(url.Url); itemsDeleted++; } else { CloudBlobContainer container = blobClient.GetContainerReference(url.ContainerUrl); if (!container.Exists()) { throw new Exception(string.Format("Blob container '{0}' not found.", path)); } CloudBlobDirectory dir = container.GetDirectoryReference(url.BlobName); if (dir == null) { throw new Exception(string.Format("Blob directory '{0}' not found.", url.BlobName)); } var matchedBlobs = dir.ListBlobs(true, BlobListingDetails.None, null, null); List <string> blobsUrlsToDelete = new List <string>(); foreach (IListBlobItem listBlobItem in matchedBlobs) { //blobsUrlsToDelete.Add(listBlobItem.Uri.AbsoluteUri); CloudBlockBlob blob = container.GetBlockBlobReference(listBlobItem.Uri.AbsoluteUri); blob.Delete(); itemsDeleted++; } //foreach (string urlToDelete in blobsUrlsToDelete) //{ // DeleteBlob(urlToDelete); //} } } return(itemsDeleted); }
static void Main(string[] args) { log = new CustomTraceLog("Starting..............................................", true, false, CustomTraceLogAddLinePostProcessingEvent, null); bool retryOnError = false; bool pauseAtEnd = false; while (true) { try { Console.Clear(); log.AddLine("Attempt:" + attempt); log.AddLineAndIncreaseIdent("Reading .ini file..."); string accountKey = CraftSynth.BuildingBlocks.IO.FileSystem.GetSettingFromIniFile <string>("accountKey", null, true, null, true, null, false, null, '='); log.AddLine("accountKey:" + accountKey.FirstXChars(20, "...hidden")); string blobUrl = CraftSynth.BuildingBlocks.IO.FileSystem.GetSettingFromIniFile <string>("blobUrl", null, true, null, true, null, false, null, '='); log.AddLine("blobUrl:" + blobUrl); string blobIsBlockOrPage = CraftSynth.BuildingBlocks.IO.FileSystem.GetSettingFromIniFile <string>("blobIsBlockOrPage", null, true, null, true, null, false, null, '='); log.AddLine("blobIsBlockOrPage:" + blobIsBlockOrPage); string localFilePath = CraftSynth.BuildingBlocks.IO.FileSystem.GetSettingFromIniFile <string>("localFilePath", null, true, null, true, null, false, null, '='); log.AddLine("localFilePath:" + localFilePath); retryOnError = CraftSynth.BuildingBlocks.IO.FileSystem.GetSettingFromIniFile <bool>("retryOnError", null, true, false, true, false, false, false, '='); log.AddLine("retryOnError:" + retryOnError); pauseAtEnd = CraftSynth.BuildingBlocks.IO.FileSystem.GetSettingFromIniFile <bool>("pauseAtEnd", null, true, false, true, false, false, false, '='); log.AddLine("pauseAtEnd:" + pauseAtEnd); int delayBeetweenChunksInSeconds = CraftSynth.BuildingBlocks.IO.FileSystem.GetSettingFromIniFile <int>("delayBeetweenChunksInSeconds", null, true, 0, false, 0, false, 0, '='); log.AddLine("delayBeetweenChunksInSeconds:" + delayBeetweenChunksInSeconds); log.AddLineAndDecreaseIdent("Done."); if (blobIsBlockOrPage != "Page") { throw new Exception("blobIsBlockOrPage can be only 'Page'. Other case is not implemented yet."); } log.AddLineAndIncreaseIdent("Parsing blob url..."); CraftSynth.BuildingBlocks.IO.AzureStorage.BlobUrl blobUrlClass = new BlobUrl(blobUrl); string accountName = blobUrlClass.StorageName; log.AddLine("accountName:" + accountName); var containerName = blobUrlClass.ContainerName; log.AddLine("containerName:" + containerName); var blobName = blobUrlClass.BlobName; log.AddLine("blobName:" + blobName); log.AddLineAndDecreaseIdent("Done."); int segmentSize = 1 * 1024 * 1024; //1 MB chunk log.AddLineAndIncreaseIdent("Downloading..."); Download(accountName, accountKey, containerName, blobName, localFilePath, segmentSize, delayBeetweenChunksInSeconds); log.AddLine("Downloading done."); break; } catch (Exception e) { Exception de = CraftSynth.BuildingBlocks.Common.Misc.GetDeepestException(e); log.AddLine(de.Message); if (retryOnError) { log.AddLine("Retrying in 10 seconds..."); Thread.Sleep(10000); attempt++; } else { break; } } } if (pauseAtEnd) { Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } }
/// <summary> /// Matches against template in destination parameter and returns all folder paths or azure storage items (containers, directories or blobs) that contain timestamp. /// </summary> /// <param name="destination"></param> /// <param name="azureStorageKey"></param> /// <param name="taskIndex"></param> /// <returns></returns> public static List <KeyValuePair <object, DateTime> > GetDestinationsFromDestinationWithWildcard(string destination, string azureStorageKey, int?taskIndex = null) { //get folder that holds childlen with timestamp in their names: List <KeyValuePair <object, DateTime> > r = new List <KeyValuePair <object, DateTime> >(); string destinationBeforeTimestamp = destination.GetSubstringBefore("[T]"); while (!destinationBeforeTimestamp.EndsWith("/") && !destinationBeforeTimestamp.EndsWith(@"\") && destinationBeforeTimestamp.Length > 0) { destinationBeforeTimestamp = destinationBeforeTimestamp.RemoveLastXChars(1); } destinationBeforeTimestamp = destinationBeforeTimestamp.TrimEnd('/').TrimEnd('\\'); if (destinationBeforeTimestamp.Length == 0) { if (taskIndex.HasValue) { throw new Exception(String.Format("Under task t{0} in destination path '{1}' timestamp [T] was found at invalid position.", taskIndex, destination)); } else { throw new Exception(String.Format("destination path '{1}' timestamp [T] was found at invalid position.", destination)); } } if (string.IsNullOrEmpty(azureStorageKey)) { //work with file system //collect ones with timestamp in name: DateTime?dt = null; var destinationsWithTimestamp = FileSystem.GetFolderPaths(destinationBeforeTimestamp); foreach (string f in destinationsWithTimestamp) { dt = LocateAndParseTimestamp(Path.GetFileName(f)); if (dt != null) { string reparsed = destination.Replace("[T]", dt.Value.ToDateAndTimeInSortableFormatForAzureBlob()); string reparsed2 = destination.Replace("[T]", dt.Value.ToDateAndTimeAsYYYYMMDDHHMM()); if ( string.Compare(reparsed, f, StringComparison.OrdinalIgnoreCase) == 0 || string.Compare(reparsed2, f, StringComparison.OrdinalIgnoreCase) == 0 ) { r.Add(new KeyValuePair <object, DateTime>(f, dt.Value)); } } } } else { //work with azure storage //collect ones with timestamp in name: DateTime?dt = null; BlobUrl destinationUrlBeforeTimestamp = new BlobUrl(destinationBeforeTimestamp); destinationUrlBeforeTimestamp.Key = azureStorageKey; HandlerForBlobs h = new CraftSynth.BuildingBlocks.IO.AzureStorage.HandlerForBlobs(); List <BlobUrl> childs = h.GetChildren(destinationUrlBeforeTimestamp, true); for (int i = childs.Count - 1; i >= 0; i--) { if (childs[i].Kind == BlobUrlKind.Container) { dt = LocateAndParseTimestamp(childs[i].ContainerName); } else if (childs[i].Kind == BlobUrlKind.SubfolderOrBlob) { dt = LocateAndParseTimestamp(childs[i].BlobName); } if (dt == null) { //timestamp couldn't be extracted- skip it } else { string reparsed = destination.Replace("[T]", dt.Value.ToDateAndTimeInSortableFormatForAzureBlob()); string reparsed2 = destination.Replace("[T]", dt.Value.ToDateAndTimeAsYYYYMMDDHHMM()); if ( string.Compare(childs[i].Url, reparsed, StringComparison.OrdinalIgnoreCase) == 0 || string.Compare(childs[i].Url, reparsed2, StringComparison.OrdinalIgnoreCase) == 0 ) { r.Add(new KeyValuePair <object, DateTime>(childs[i], dt.Value)); } } } } return(r); }
public override int GetHashCode() { unchecked { return((Filename != null ? Filename.GetHashCode() : 0) ^ (Additions != null ? Additions.GetHashCode() : 0) ^ (Deletions != null ? Deletions.GetHashCode() : 0) ^ (Changes != null ? Changes.GetHashCode() : 0) ^ (Status != null ? Status.GetHashCode() : 0) ^ (RawUrl != null ? RawUrl.GetHashCode() : 0) ^ (BlobUrl != null ? BlobUrl.GetHashCode() : 0) ^ (Patch != null ? Patch.GetHashCode() : 0) ^ (ContentsUrl != null ? ContentsUrl.GetHashCode() : 0)); } }
public static bool Execute(int taskIndex, string taskTemplate, string currentTimestampString, CustomTraceLog log) { bool allSuccess = true; log.AddLineAndIncreaseIdent("Deleting folders or azure storage items..."); List <string> parts = taskTemplate.GetParameters(); //extract destination path: string destination = parts[1]; log.AddLine("Item(s) to delete: " + destination); //extract destination key: string azureStorageKey = taskTemplate.GetParameterValue <string>("/destkey", false, null, true, null, false, null, '/', ':'); log.AddLine("Azure storage key: " + (azureStorageKey == null ? "This is not Azure storage" : azureStorageKey.Bubble(20, "..."))); if (destination.OccurrencesCount("[T]") > 1) { throw new Exception(String.Format("Under task t{0} in destination path '{1}' multiple timestamps [T] were found. Only none or one occurrance is supported.", taskIndex, destination)); } else if (destination.OccurrencesCount("[T]") == 0) { //just delete or empty single item //extract /DeleteOnlyContent info bool deleteOnlyContent = taskTemplate.GetParameterPresence("/DeleteOnlyContent", false, false, '/'); log.AddLine("DeleteOnlyContent:" + deleteOnlyContent); if (string.IsNullOrEmpty(azureStorageKey)) { //just delete or empty single folder log.AddLine("Deleting folder '" + destination + "' ..."); try { if (!deleteOnlyContent) { Directory.Delete(destination, true); log.AddLine("Deleted."); } else { List <string> subfoldersPaths = CraftSynth.BuildingBlocks.IO.FileSystem.GetFolderPaths(destination); List <string> filesPaths = CraftSynth.BuildingBlocks.IO.FileSystem.GetFilePaths(destination); log.AddLine("Subitems left to process: "); int i = subfoldersPaths.Count + filesPaths.Count; log.AddLine("..." + i); foreach (string subfolder in subfoldersPaths) { Directory.Delete(subfolder, true); i--; log.AddLine("..." + i); } foreach (string filePath in filesPaths) { File.Delete(filePath); i--; log.AddLine("..." + i); } log.AddLine("Emptied."); } } catch (Exception e) { log.AddLine("Failed."); HandlerForLoging.LogException(e, log); allSuccess = false; } } else { //just delete or empty single container,directory or blob BlobUrl destinationUrl = new BlobUrl(destination); destinationUrl.Key = azureStorageKey; log.AddLine(string.Format("Deleting azure storage item: {0}", destinationUrl.Url)); try { var h = new CraftSynth.BuildingBlocks.IO.AzureStorage.HandlerForBlobs(); if (!deleteOnlyContent) { allSuccess = h.Delete(destinationUrl) > 0 && allSuccess; log.AddLine("Deleted."); } else { var childs = h.GetChildren(destinationUrl, true); log.AddLine("Subitems left to process: "); int i = childs.Count; log.AddLine("..." + i); foreach (BlobUrl child in childs) { allSuccess = h.Delete(child) > 0 && allSuccess; i--; log.AddLine("..." + i); } } } catch (Exception e) { log.AddLine("Failed."); HandlerForLoging.LogException(e, log); allSuccess = false; } } } else { //extract /KeepLastXDays:1 info: int?keepLastXDays = null; if (taskTemplate.GetParameterPresence("/KeepLastXDays", false, false, '/', ':')) { keepLastXDays = taskTemplate.GetParameterValue <int>("/KeepLastXDays", true, -1, true, -1, false, -1, '/', ':'); } log.AddLine("KeepLastXDays: " + (keepLastXDays == null ? "No" : keepLastXDays.Value.ToString())); //extract /KeepLastInMonth info bool keepLastInMonth = taskTemplate.GetParameterPresence("/KeepLastInMonth", false, false, '/'); log.AddLine("KeepLastInMonth:" + keepLastInMonth); //extract /KeepLastInYear info bool keepLastInYear = taskTemplate.GetParameterPresence("/KeepLastInYear", false, false, '/'); log.AddLine("KeepLastInYear:" + keepLastInYear); //extract /DeleteOnlyContent info bool deleteOnlyContent = taskTemplate.GetParameterPresence("/DeleteOnlyContent", false, false, '/'); log.AddLine("DeleteOnlyContent:" + deleteOnlyContent); //Traverse all children, collect ones with timestamp in name, check age and delete if too old: if (azureStorageKey.IsNullOrWhiteSpace()) { //folders var deletionItems = HandlerForPaths.GetDestinationsFromDestinationWithWildcard(destination, null, taskIndex); //leave only very old items so they can be deleted: deletionItems = ConsiderRetentionAndReturnItemsForDeletion(deletionItems, currentTimestampString, keepLastXDays, keepLastInMonth, keepLastInYear); //delete old items: log.AddLine("Deleting " + deletionItems.Count + " folder(s) ..."); int deletedCount = 0; foreach (KeyValuePair <object, DateTime> deletionItem in deletionItems) { try { if (!deleteOnlyContent) { Directory.Delete(deletionItem.Key.ToString(), true); } else { List <string> subfoldersPaths = CraftSynth.BuildingBlocks.IO.FileSystem.GetFolderPaths(deletionItem.Key.ToString()); List <string> filesPaths = CraftSynth.BuildingBlocks.IO.FileSystem.GetFilePaths(deletionItem.Key.ToString()); log.AddLine("Subitems left to process: "); int i = subfoldersPaths.Count + filesPaths.Count; log.AddLine("..." + i); foreach (string subfolder in subfoldersPaths) { Directory.Delete(subfolder, true); i--; log.AddLine("..." + i); } foreach (string filePath in filesPaths) { File.Delete(filePath); i--; log.AddLine("..." + i); } } deletedCount++; } catch (Exception e) { HandlerForLoging.LogException(e, log); allSuccess = false; } } if (deletedCount == deletionItems.Count) { if (deleteOnlyContent) { log.AddLine("Emptied successfully."); } else { log.AddLine("Deleted successfully."); } } else { if (deleteOnlyContent) { log.AddLine("Emptied just " + deletedCount + " items."); } else { log.AddLine("Deleted just " + deletedCount + " items."); } } } else { //azure storage items var deletionItems = HandlerForPaths.GetDestinationsFromDestinationWithWildcard(destination, azureStorageKey, taskIndex); //leave only very old items so they can be deleted: deletionItems = ConsiderRetentionAndReturnItemsForDeletion(deletionItems, currentTimestampString, keepLastXDays, keepLastInMonth, keepLastInYear); //delete old items: log.AddLine(string.Format("Deleting {0} Azure storage item(s) ...", deletionItems.Count)); int deletedCount = 0; HandlerForBlobs h = new HandlerForBlobs(); foreach (KeyValuePair <object, DateTime> deletionItem in deletionItems) { (deletionItem.Key as BlobUrl).Key = azureStorageKey; try { bool r = false; if (!deleteOnlyContent) { r = h.Delete(deletionItem.Key as BlobUrl) > 0; } else { var childs = h.GetChildren((deletionItem.Key as BlobUrl), true); log.AddLine("Subitems left to process: "); int i = childs.Count; log.AddLine("..." + i); r = true; foreach (BlobUrl child in childs) { r = h.Delete(child) > 0 && r; i--; log.AddLine("..." + i); } } allSuccess = allSuccess && r; deletedCount++; } catch (Exception e) { HandlerForLoging.LogException(e, log); allSuccess = false; } } if (deletedCount == deletionItems.Count) { log.AddLine("Deleted successfully."); } else { log.AddLine("Deleted just " + deletedCount + " items."); } } } return(allSuccess); }