-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Started extracting backup capabilities in separate NUGET
- Loading branch information
Showing
40 changed files
with
627 additions
and
1,295 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 0 additions & 13 deletions
13
CoreHelpers.WindowsAzure.Storage.Table.Abstractions/StoreOperations.cs
This file was deleted.
Oops, something went wrong.
20 changes: 20 additions & 0 deletions
20
...ble.Backup.Abstractions/CoreHelpers.WindowsAzure.Storage.Table.Backup.Abstractions.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFrameworks>netstandard2.0;netstandard2.1;net48</TargetFrameworks> | ||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> | ||
<LangVersion>6</LangVersion> | ||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | ||
<PackageProjectUrl>https://github.com/CoreHelpers/AzureStorageTable</PackageProjectUrl> | ||
<RepositoryType>git</RepositoryType> | ||
<RepositoryUrl>https://github.com/CoreHelpers/AzureStorageTable.git</RepositoryUrl> | ||
<Description>This projects implements an abstraction for Azure Storage Tables to use POCOs because deriving every entity from ITableEntity or TableEntity looks like a step backwards. The current implementation is intended to be an abstraction to store every existing entity into Azure Table Store.</Description> | ||
<PackageTags>poco dotnet-core dotnet azure azure-storage azure-table-storage</PackageTags> | ||
<Copyright>(c) Dirk Eisenberg</Copyright> | ||
</PropertyGroup> | ||
|
||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\CoreHelpers.WindowsAzure.Storage.Table.Abstractions\CoreHelpers.WindowsAzure.Storage.Table.Abstractions.csproj" /> | ||
</ItemGroup> | ||
</Project> |
11 changes: 11 additions & 0 deletions
11
CoreHelpers.WindowsAzure.Storage.Table.Backup.Abstractions/IBackupContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
|
||
namespace CoreHelpers.WindowsAzure.Storage.Table.Backup.Abstractions | ||
{ | ||
public interface IBackupContext : IDisposable | ||
{ | ||
Task Backup(IStorageContext storageContext, string[] excludedTables = null, bool compress = true); | ||
} | ||
} | ||
|
14 changes: 14 additions & 0 deletions
14
CoreHelpers.WindowsAzure.Storage.Table.Backup.Abstractions/IBackupService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using CoreHelpers.WindowsAzure.Storage.Table.Backup.Abstractions; | ||
|
||
namespace CoreHelpers.WindowsAzure.Storage.Table.Backup | ||
{ | ||
public interface IBackupService | ||
{ | ||
Task<IBackupContext> OpenBackupContext(string targetBlobStorageConnectionString, string targetContainerName, string targetPath, string tableNamePrefix = null); | ||
|
||
Task<IRestoreContext> OpenRestorContext(string sourceBlobStorageConnectionString, string sourceContainerName, string sourcePath, string tableNamePrefix = null); | ||
} | ||
} | ||
|
11 changes: 11 additions & 0 deletions
11
CoreHelpers.WindowsAzure.Storage.Table.Backup.Abstractions/IRestoreContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
|
||
namespace CoreHelpers.WindowsAzure.Storage.Table.Backup.Abstractions | ||
{ | ||
public interface IRestoreContext : IDisposable | ||
{ | ||
// Task BackupTable(IStorageContext storageContext, string tableName, bool compress = true); | ||
} | ||
} | ||
|
154 changes: 154 additions & 0 deletions
154
CoreHelpers.WindowsAzure.Storage.Table.Backup/BackupContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
using Azure.Storage.Blobs; | ||
using CoreHelpers.WindowsAzure.Storage.Table.Backup.Abstractions; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace CoreHelpers.WindowsAzure.Storage.Table.Backup | ||
{ | ||
public class BackupContext : IBackupContext | ||
{ | ||
private ILogger<BackupContext> _logger; | ||
|
||
private string _targetConnectionString; | ||
private string _targetContainer; | ||
private string _targetPath; | ||
private string _targetTableNamePrefix; | ||
private BlobServiceClient _blobServiceClient; | ||
|
||
public BackupContext(ILogger<BackupContext> logger, string connectionString, string container, string path, string tableNamePrefix) | ||
{ | ||
_logger = logger; | ||
_targetConnectionString = connectionString; | ||
_targetContainer = container; | ||
_targetPath = path; | ||
_targetTableNamePrefix = tableNamePrefix; | ||
|
||
_blobServiceClient = new BlobServiceClient(_targetConnectionString); | ||
} | ||
|
||
public async Task Backup(IStorageContext storageContext, string[] excludedTables = null, bool compress = true) | ||
{ | ||
using (_logger.BeginScope("Starting backup procedure...")) | ||
{ | ||
|
||
// generate the excludeTables | ||
var excludedTablesList = new List<string>(); | ||
if (excludedTables != null) | ||
{ | ||
foreach (var tbl in excludedTables) | ||
excludedTablesList.Add(tbl.ToLower()); | ||
} | ||
|
||
// get all tables | ||
var tables = await storageContext.QueryTableList(); | ||
_logger.LogInformation($"Processing {tables.Count} tables"); | ||
|
||
// prepare the backup container | ||
_logger.LogInformation($"Creating target container {_targetContainer} if needed"); | ||
var blobContainerClient = _blobServiceClient.GetBlobContainerClient(_targetContainer); | ||
if (!await blobContainerClient.ExistsAsync()) | ||
await blobContainerClient.CreateIfNotExistsAsync(); | ||
|
||
// prepare the memory stats file | ||
var memoryStatsFile = $"{Path.GetTempFileName()}.csv"; | ||
using (var statsFile = new StreamWriter(memoryStatsFile)) | ||
{ | ||
// use the statfile | ||
_logger.LogInformation($"Statsfile is under {memoryStatsFile}..."); | ||
statsFile.WriteLine($"TableName,PageCounter,ItemCount,MemoryFootprint"); | ||
|
||
// visit every table | ||
foreach (var tableName in tables) | ||
{ | ||
|
||
// filter the table prefix | ||
if (!String.IsNullOrEmpty(_targetTableNamePrefix) && !tableName.StartsWith(_targetTableNamePrefix, StringComparison.CurrentCulture)) | ||
{ | ||
_logger.LogInformation($"Ignoring table {tableName}..."); | ||
continue; | ||
} | ||
|
||
// check the excluded tables | ||
if (excludedTablesList.Contains(tableName.ToLower())) | ||
{ | ||
_logger.LogInformation($"Ignoring table {tableName} (is part of excluded tables)..."); | ||
continue; | ||
} | ||
|
||
using (_logger.BeginScope($"Processing backup for table {tableName}...")) | ||
{ | ||
// do the backup | ||
var fileName = $"{tableName}.json"; | ||
if (!string.IsNullOrEmpty(_targetPath)) { fileName = $"{_targetPath}/{fileName}"; } | ||
if (compress) { fileName += ".gz"; } | ||
|
||
// open block blog reference | ||
var blobClient = blobContainerClient.GetBlobClient(fileName); | ||
|
||
// open the file stream | ||
if (compress) | ||
_logger.LogInformation($"Writing backup to compressed file"); | ||
else | ||
_logger.LogInformation($"Writing backup to non compressed file"); | ||
|
||
// do it | ||
using (var backupFileStream = await blobClient.OpenWriteAsync(false)) | ||
{ | ||
using (var contentWriter = new ZippedStreamWriter(backupFileStream, compress)) | ||
{ | ||
var pageCounter = 0; | ||
var itemCounter = 0; | ||
|
||
var pageLogScope = default(IDisposable); | ||
|
||
await storageContext.ExportToJsonAsync(tableName, contentWriter, (ImportExportOperation operation) => | ||
{ | ||
switch (operation) | ||
{ | ||
case ImportExportOperation.processingPage: | ||
{ | ||
pageCounter++; | ||
pageLogScope = _logger.BeginScope($"Processing page #{pageCounter}"); | ||
break; | ||
} | ||
case ImportExportOperation.processingItem: | ||
{ | ||
itemCounter++; | ||
break; | ||
} | ||
case ImportExportOperation.processedPage: | ||
{ | ||
_logger.LogInformation($"#{itemCounter} processed!"); | ||
statsFile.WriteLine($"{tableName},{pageCounter},{itemCounter},{Process.GetCurrentProcess().WorkingSet64}"); | ||
pageLogScope.Dispose(); | ||
pageLogScope = null; | ||
break; | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
|
||
// ensure we clean up the memory beause sometimes | ||
// we have to much referenced data | ||
GC.Collect(); | ||
|
||
// flush the statfile | ||
await statsFile.FlushAsync(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
|
||
} | ||
} | ||
} | ||
|
33 changes: 33 additions & 0 deletions
33
CoreHelpers.WindowsAzure.Storage.Table.Backup/BackupService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using CoreHelpers.WindowsAzure.Storage.Table.Backup.Abstractions; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace CoreHelpers.WindowsAzure.Storage.Table.Backup | ||
{ | ||
public class BackupService : IBackupService | ||
{ | ||
private ILoggerFactory _loggerFactory; | ||
|
||
public BackupService(ILoggerFactory loggerFactory) | ||
{ | ||
_loggerFactory = loggerFactory; | ||
} | ||
|
||
public async Task<IBackupContext> OpenBackupContext(string targetBlobStorageConnectionString, string targetContainerName, string targetPath, string tableNamePrefix = null) | ||
{ | ||
await Task.CompletedTask; | ||
return new BackupContext( | ||
_loggerFactory.CreateLogger<BackupContext>(), | ||
targetBlobStorageConnectionString, targetContainerName, targetPath, | ||
tableNamePrefix); | ||
} | ||
|
||
public async Task<IRestoreContext> OpenRestorContext(string sourceBlobStorageConnectionString, string sourceContainerName, string sourcePath, string tableNamePrefix = null) | ||
{ | ||
await Task.CompletedTask; | ||
return new RestoreContext(); | ||
} | ||
} | ||
} | ||
|
28 changes: 28 additions & 0 deletions
28
...rs.WindowsAzure.Storage.Table.Backup/CoreHelpers.WindowsAzure.Storage.Table.Backup.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFrameworks>netstandard2.0;netstandard2.1;net48</TargetFrameworks> | ||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> | ||
<LangVersion>6</LangVersion> | ||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | ||
<PackageProjectUrl>https://github.com/CoreHelpers/AzureStorageTable</PackageProjectUrl> | ||
<RepositoryType>git</RepositoryType> | ||
<RepositoryUrl>https://github.com/CoreHelpers/AzureStorageTable.git</RepositoryUrl> | ||
<Description>This projects implements an abstraction for Azure Storage Tables to use POCOs because deriving every entity from ITableEntity or TableEntity looks like a step backwards. The current implementation is intended to be an abstraction to store every existing entity into Azure Table Store.</Description> | ||
<PackageTags>poco dotnet-core dotnet azure azure-storage azure-table-storage</PackageTags> | ||
<Copyright>(c) Dirk Eisenberg</Copyright> | ||
</PropertyGroup> | ||
|
||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\CoreHelpers.WindowsAzure.Storage.Table.Backup.Abstractions\CoreHelpers.WindowsAzure.Storage.Table.Backup.Abstractions.csproj" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<None Remove="Microsoft.Extensions.Logging.Abstractions" /> | ||
<None Remove="Azure.Storage.Blobs" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" /> | ||
<PackageReference Include="Azure.Storage.Blobs" Version="12.13.1" /> | ||
</ItemGroup> | ||
</Project> |
Oops, something went wrong.