From 4b3cb1b4fb0c1a466b3ceda88331fccf3c332851 Mon Sep 17 00:00:00 2001 From: SuhorukovAnton Date: Tue, 31 Aug 2021 12:40:28 +0300 Subject: [PATCH 1/5] backup.core: first version --- ASC.Web.sln | 31 +- .../{ => Backup}/ASC.Data.Backup.csproj | 18 +- .../BackupCleanerService.cs | 98 +- .../{ => Backup}/BackupResource.Designer.cs | 162 +- .../{ => Backup}/BackupResource.resx | 132 +- .../BackupSchedulerService.cs | 130 +- .../{ => Backup}/BackupServiceLauncher.cs | 28 +- .../Controllers/BackupController.cs | 542 ++--- .../{ => Backup}/ModelApi/Backup.cs | 0 .../{ => Backup}/ModelApi/BackupRestore.cs | 0 .../{ => Backup}/ModelApi/BackupSchedule.cs | 0 .../ASC.Data.Backup/{ => Backup}/Program.cs | 82 +- .../Properties/launchSettings.json | 0 .../ASC.Data.Backup/{ => Backup}/Startup.cs | 38 +- .../{ => Backup}/appsettings.json | 0 .../Core/ASC.Data.Backup.Core.csproj | 54 + .../{ => Core}/ActionInvoker.cs | 8 +- .../{ => Core}/BackupAjaxHandler.cs | 106 +- .../{ => Core}/BackupFileUploadHandler.cs | 198 +- .../Core/BackupResource.Designer.cs | 81 + .../ASC.Data.Backup/Core/BackupResource.resx | 67 + .../Contracts/BackupServiceModel.cs | 238 +-- .../{ => Core}/Contracts/IBackupService.cs | 0 .../Core/{ => Core}/DbBackupProvider.cs | 42 +- .../Core/{ => Core}/DbHelper.cs | 4 +- .../Core/{ => Core}/FileBackupProvider.cs | 26 +- .../Core/{ => Core}/IBackupProvider.cs | 0 .../Core/{ => Core}/IDataOperator.cs | 2 +- .../Core/{ => Core}/NotifyHelper.cs | 363 ++-- .../Core/{ => Core}/Schedule.cs | 2 +- .../Core/{ => Core}/ZipOperator.cs | 22 +- .../{ => Core}/EF/BackupRecord.cs | 4 +- .../{ => Core}/EF/BackupSchedule.cs | 0 .../{ => Core}/EF/BackupsContext.cs | 6 +- .../Exceptions/DbBackupException.cs | 0 .../{ => Core}/Exceptions/ThrowHelper.cs | 0 .../{ => Core}/Extensions/DataExtensions.cs | 0 .../Extensions/EnumerableExtensions.cs | 0 .../{ => Core}/Extensions/XmlExtensions.cs | 0 .../{ => Core}/Listerners/BackupListener.cs | 2 +- .../{ => Core}/Service/BackupService.cs | 96 +- .../{ => Core}/Service/BackupSettings.cs | 0 .../{ => Core}/Service/BackupWorker.cs | 1803 +++++++++-------- .../{ => Core}/Storage/BackupRepository.cs | 48 +- .../Storage/BackupStorageFactory.cs | 100 +- .../Storage/ConsumerBackupStorage.cs | 12 +- .../Storage/DataStoreBackupStorage.cs | 14 +- .../Storage/DocumentsBackupStorage.cs | 308 +-- .../{ => Core}/Storage/IBackupRepository.cs | 2 +- .../{ => Core}/Storage/IBackupStorage.cs | 0 .../{ => Core}/Storage/LocalBackupStorage.cs | 6 +- .../{ => Core}/Storage/S3BackupStorage.cs | 2 +- .../{ => Core}/Tasks/BackupFileInfo.cs | 0 .../{ => Core}/Tasks/BackupPortalTask.cs | 234 +-- .../{ => Core}/Tasks/ColumnMapper.cs | 0 .../{ => Core}/Tasks/DbFactory.cs | 8 +- .../{ => Core}/Tasks/DeletePortalTask.cs | 4 +- .../{ => Core}/Tasks/KeyHelper.cs | 0 .../Tasks/Modules/AuditModuleSpecifics.cs | 0 .../Tasks/Modules/CalendarModuleSpecifics.cs | 0 .../Tasks/Modules/CommunityModuleSpecifics.cs | 14 +- .../Tasks/Modules/CoreModuleSpecifics.cs | 16 +- .../Tasks/Modules/CrmModuleSpecifics.cs | 24 +- .../Tasks/Modules/FilesModuleSpecifics.cs | 0 .../{ => Core}/Tasks/Modules/Helpers.cs | 16 +- .../Tasks/Modules/IModuleSpecifics.cs | 0 .../Tasks/Modules/MailModuleSpecifics.cs | 0 .../Tasks/Modules/ModuleProvider.cs | 28 +- .../Tasks/Modules/ModuleSpecificsBase.cs | 4 +- .../Tasks/Modules/ProjectsModuleSpecifics.cs | 8 +- .../Tasks/Modules/TenantsModuleSpecifics.cs | 0 .../Tasks/Modules/WebStudioModuleSpecifics.cs | 6 +- .../{ => Core}/Tasks/PortalTaskBase.cs | 88 +- .../{ => Core}/Tasks/RestoreDbModuleTask.cs | 216 +- .../{ => Core}/Tasks/RestorePortalTask.cs | 208 +- .../{ => Core}/Tasks/TransferPortalTask.cs | 36 +- .../{ => Core}/Utils/ConfigurationProvider.cs | 0 .../{ => Core}/Utils/FCKEditorPathUtility.cs | 0 .../{ => Core}/Utils/PathHelper.cs | 0 .../{ => Core}/protos/BackupProgress.proto | 0 .../{ => Core}/protos/DeleteSchedule.proto | 0 .../ASC.Data.Backup/Tasks/Data/DataRowInfo.cs | 106 - .../Tasks/Data/DataRowInfoReader.cs | 100 - .../Tasks/Data/RelationInfo.cs | 108 - .../ASC.Data.Backup/Tasks/Data/TableInfo.cs | 91 - web/ASC.Web.Api/ASC.Web.Api.csproj | 2 +- 86 files changed, 2996 insertions(+), 3198 deletions(-) rename common/services/ASC.Data.Backup/{ => Backup}/ASC.Data.Backup.csproj (82%) rename common/services/ASC.Data.Backup/{Service => Backup}/BackupCleanerService.cs (99%) rename common/services/ASC.Data.Backup/{ => Backup}/BackupResource.Designer.cs (97%) rename common/services/ASC.Data.Backup/{ => Backup}/BackupResource.resx (97%) rename common/services/ASC.Data.Backup/{Service => Backup}/BackupSchedulerService.cs (99%) rename common/services/ASC.Data.Backup/{ => Backup}/BackupServiceLauncher.cs (99%) rename common/services/ASC.Data.Backup/{ => Backup}/Controllers/BackupController.cs (97%) rename common/services/ASC.Data.Backup/{ => Backup}/ModelApi/Backup.cs (100%) rename common/services/ASC.Data.Backup/{ => Backup}/ModelApi/BackupRestore.cs (100%) rename common/services/ASC.Data.Backup/{ => Backup}/ModelApi/BackupSchedule.cs (100%) rename common/services/ASC.Data.Backup/{ => Backup}/Program.cs (98%) rename common/services/ASC.Data.Backup/{ => Backup}/Properties/launchSettings.json (100%) rename common/services/ASC.Data.Backup/{ => Backup}/Startup.cs (99%) rename common/services/ASC.Data.Backup/{ => Backup}/appsettings.json (100%) create mode 100644 common/services/ASC.Data.Backup/Core/ASC.Data.Backup.Core.csproj rename common/services/ASC.Data.Backup/{ => Core}/ActionInvoker.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/BackupAjaxHandler.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/BackupFileUploadHandler.cs (96%) create mode 100644 common/services/ASC.Data.Backup/Core/BackupResource.Designer.cs create mode 100644 common/services/ASC.Data.Backup/Core/BackupResource.resx rename common/services/ASC.Data.Backup/{ => Core}/Contracts/BackupServiceModel.cs (97%) rename common/services/ASC.Data.Backup/{ => Core}/Contracts/IBackupService.cs (100%) rename common/services/ASC.Data.Backup/Core/{ => Core}/DbBackupProvider.cs (99%) rename common/services/ASC.Data.Backup/Core/{ => Core}/DbHelper.cs (99%) rename common/services/ASC.Data.Backup/Core/{ => Core}/FileBackupProvider.cs (99%) rename common/services/ASC.Data.Backup/Core/{ => Core}/IBackupProvider.cs (100%) rename common/services/ASC.Data.Backup/Core/{ => Core}/IDataOperator.cs (99%) rename common/services/ASC.Data.Backup/Core/{ => Core}/NotifyHelper.cs (98%) rename common/services/ASC.Data.Backup/Core/{ => Core}/Schedule.cs (99%) rename common/services/ASC.Data.Backup/Core/{ => Core}/ZipOperator.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/EF/BackupRecord.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/EF/BackupSchedule.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/EF/BackupsContext.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Exceptions/DbBackupException.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Exceptions/ThrowHelper.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Extensions/DataExtensions.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Extensions/EnumerableExtensions.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Extensions/XmlExtensions.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Listerners/BackupListener.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Service/BackupService.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Service/BackupSettings.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Service/BackupWorker.cs (97%) rename common/services/ASC.Data.Backup/{ => Core}/Storage/BackupRepository.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Storage/BackupStorageFactory.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Storage/ConsumerBackupStorage.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Storage/DataStoreBackupStorage.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Storage/DocumentsBackupStorage.cs (98%) rename common/services/ASC.Data.Backup/{ => Core}/Storage/IBackupRepository.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Storage/IBackupStorage.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Storage/LocalBackupStorage.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Storage/S3BackupStorage.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/BackupFileInfo.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/BackupPortalTask.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/ColumnMapper.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/DbFactory.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/DeletePortalTask.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/KeyHelper.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/AuditModuleSpecifics.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/CalendarModuleSpecifics.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/CommunityModuleSpecifics.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/CoreModuleSpecifics.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/CrmModuleSpecifics.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/FilesModuleSpecifics.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/Helpers.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/IModuleSpecifics.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/MailModuleSpecifics.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/ModuleProvider.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/ModuleSpecificsBase.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/ProjectsModuleSpecifics.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/TenantsModuleSpecifics.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/Modules/WebStudioModuleSpecifics.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/PortalTaskBase.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/RestoreDbModuleTask.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/RestorePortalTask.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Tasks/TransferPortalTask.cs (99%) rename common/services/ASC.Data.Backup/{ => Core}/Utils/ConfigurationProvider.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Utils/FCKEditorPathUtility.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/Utils/PathHelper.cs (100%) rename common/services/ASC.Data.Backup/{ => Core}/protos/BackupProgress.proto (100%) rename common/services/ASC.Data.Backup/{ => Core}/protos/DeleteSchedule.proto (100%) delete mode 100644 common/services/ASC.Data.Backup/Tasks/Data/DataRowInfo.cs delete mode 100644 common/services/ASC.Data.Backup/Tasks/Data/DataRowInfoReader.cs delete mode 100644 common/services/ASC.Data.Backup/Tasks/Data/RelationInfo.cs delete mode 100644 common/services/ASC.Data.Backup/Tasks/Data/TableInfo.cs diff --git a/ASC.Web.sln b/ASC.Web.sln index 0d92015d0d..46323af2eb 100644 --- a/ASC.Web.sln +++ b/ASC.Web.sln @@ -1,4 +1,5 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 + +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.28803.202 MinimumVisualStudioVersion = 10.0.40219.1 @@ -57,8 +58,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Feed.Aggregator", "comm EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Thumbnails.Svc", "common\services\ASC.Thumbnails.Svc\ASC.Thumbnails.Svc.csproj", "{1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Backup", "common\services\ASC.Data.Backup\ASC.Data.Backup.csproj", "{DE3DAF51-FB29-41FC-AF41-A4BA8D91BFB6}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Files.Core", "products\ASC.Files\Core\ASC.Files.Core.csproj", "{F0A39728-940D-4DBE-A37A-05D4EB57F342}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Socket.IO.Svc", "common\services\ASC.Socket.IO.Svc\ASC.Socket.IO.Svc.csproj", "{2DADEAD3-0FE9-4199-9817-41A32E6BF450}" @@ -88,12 +87,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Radicale", "common\serv EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.SsoAuth.Svc", "common\services\ASC.SsoAuth.Svc\ASC.SsoAuth.Svc.csproj", "{6AD828EA-FBA2-4D30-B969-756B3BE78E4E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASC.Web.HealthChecks.UI", "web\ASC.Web.HealthChecks.UI\ASC.Web.HealthChecks.UI.csproj", "{0C1A387E-0CD0-4BE8-82FC-9FCAD05BF289}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Web.HealthChecks.UI", "web\ASC.Web.HealthChecks.UI\ASC.Web.HealthChecks.UI.csproj", "{0C1A387E-0CD0-4BE8-82FC-9FCAD05BF289}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.ClearEvents", "common\services\ASC.ClearEvents\ASC.ClearEvents.csproj", "{448221A8-EABA-4200-9192-E08BF241A487}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.CRM.BackgroundTasks", "products\ASC.CRM\BackgroundTasks\ASC.CRM.BackgroundTasks.csproj", "{E52C0E35-A05C-437F-8FF2-3E0AC9F81433}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Backup", "common\services\ASC.Data.Backup\Backup\ASC.Data.Backup.csproj", "{F5CD54D4-E66F-461C-96E2-B617E3324E42}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Backup.Core", "common\services\ASC.Data.Backup\Core\ASC.Data.Backup.Core.csproj", "{45117C68-5197-4AFF-9FC1-1E86E718B727}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -204,10 +207,6 @@ Global {1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}.Debug|Any CPU.Build.0 = Debug|Any CPU {1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}.Release|Any CPU.ActiveCfg = Release|Any CPU {1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}.Release|Any CPU.Build.0 = Release|Any CPU - {DE3DAF51-FB29-41FC-AF41-A4BA8D91BFB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DE3DAF51-FB29-41FC-AF41-A4BA8D91BFB6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DE3DAF51-FB29-41FC-AF41-A4BA8D91BFB6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DE3DAF51-FB29-41FC-AF41-A4BA8D91BFB6}.Release|Any CPU.Build.0 = Release|Any CPU {F0A39728-940D-4DBE-A37A-05D4EB57F342}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F0A39728-940D-4DBE-A37A-05D4EB57F342}.Debug|Any CPU.Build.0 = Debug|Any CPU {F0A39728-940D-4DBE-A37A-05D4EB57F342}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -244,14 +243,14 @@ Global {277F4A2C-07CC-4BC5-B4F3-9695BB2DFFB9}.Debug|Any CPU.Build.0 = Debug|Any CPU {277F4A2C-07CC-4BC5-B4F3-9695BB2DFFB9}.Release|Any CPU.ActiveCfg = Release|Any CPU {277F4A2C-07CC-4BC5-B4F3-9695BB2DFFB9}.Release|Any CPU.Build.0 = Release|Any CPU + {137CA67B-D0F5-4746-B8BC-1888D2859B90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {137CA67B-D0F5-4746-B8BC-1888D2859B90}.Debug|Any CPU.Build.0 = Debug|Any CPU + {137CA67B-D0F5-4746-B8BC-1888D2859B90}.Release|Any CPU.ActiveCfg = Release|Any CPU + {137CA67B-D0F5-4746-B8BC-1888D2859B90}.Release|Any CPU.Build.0 = Release|Any CPU {74998718-3C9A-4A89-B834-14453762C60F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {74998718-3C9A-4A89-B834-14453762C60F}.Debug|Any CPU.Build.0 = Debug|Any CPU {74998718-3C9A-4A89-B834-14453762C60F}.Release|Any CPU.ActiveCfg = Release|Any CPU {74998718-3C9A-4A89-B834-14453762C60F}.Release|Any CPU.Build.0 = Release|Any CPU - {137CA67B-D0F5-4746-B8BC-1888D2859B90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {137CA67B-D0F5-4746-B8BC-1888D2859B90}.Debug|Any CPU.Build.0 = Debug|Any CPU - {137CA67B-D0F5-4746-B8BC-1888D2859B90}.Release|Any CPU.ActiveCfg = Release|Any CPU - {137CA67B-D0F5-4746-B8BC-1888D2859B90}.Release|Any CPU.Build.0 = Release|Any CPU {6AD828EA-FBA2-4D30-B969-756B3BE78E4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6AD828EA-FBA2-4D30-B969-756B3BE78E4E}.Debug|Any CPU.Build.0 = Debug|Any CPU {6AD828EA-FBA2-4D30-B969-756B3BE78E4E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -268,6 +267,14 @@ Global {E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Debug|Any CPU.Build.0 = Debug|Any CPU {E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Release|Any CPU.ActiveCfg = Release|Any CPU {E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Release|Any CPU.Build.0 = Release|Any CPU + {F5CD54D4-E66F-461C-96E2-B617E3324E42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F5CD54D4-E66F-461C-96E2-B617E3324E42}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F5CD54D4-E66F-461C-96E2-B617E3324E42}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F5CD54D4-E66F-461C-96E2-B617E3324E42}.Release|Any CPU.Build.0 = Release|Any CPU + {45117C68-5197-4AFF-9FC1-1E86E718B727}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {45117C68-5197-4AFF-9FC1-1E86E718B727}.Debug|Any CPU.Build.0 = Debug|Any CPU + {45117C68-5197-4AFF-9FC1-1E86E718B727}.Release|Any CPU.ActiveCfg = Release|Any CPU + {45117C68-5197-4AFF-9FC1-1E86E718B727}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/common/services/ASC.Data.Backup/ASC.Data.Backup.csproj b/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj similarity index 82% rename from common/services/ASC.Data.Backup/ASC.Data.Backup.csproj rename to common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj index bd37b4b503..9362e71336 100644 --- a/common/services/ASC.Data.Backup/ASC.Data.Backup.csproj +++ b/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj @@ -12,11 +12,6 @@ none false - - - - - True @@ -33,8 +28,8 @@ - - true + + true all @@ -46,12 +41,9 @@ - - - - - - + + + diff --git a/common/services/ASC.Data.Backup/Service/BackupCleanerService.cs b/common/services/ASC.Data.Backup/Backup/BackupCleanerService.cs similarity index 99% rename from common/services/ASC.Data.Backup/Service/BackupCleanerService.cs rename to common/services/ASC.Data.Backup/Backup/BackupCleanerService.cs index 2bed6d7566..eccf93f26d 100644 --- a/common/services/ASC.Data.Backup/Service/BackupCleanerService.cs +++ b/common/services/ASC.Data.Backup/Backup/BackupCleanerService.cs @@ -26,41 +26,41 @@ using System; using System.Linq; -using System.Threading; - +using System.Threading; + using ASC.Common; using ASC.Common.Logging; -using ASC.Data.Backup.Storage; -using ASC.Files.Core; - -using Microsoft.Extensions.DependencyInjection; +using ASC.Data.Backup.Storage; +using ASC.Files.Core; + +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; namespace ASC.Data.Backup.Service -{ +{ [Scope] internal class BackupCleanerHelperService { - private readonly ILog log; - - private BackupRepository BackupRepository { get; } - private BackupStorageFactory BackupStorageFactory { get; } - - public BackupCleanerHelperService( - IOptionsMonitor options, - BackupRepository backupRepository, + private readonly ILog log; + + private BackupRepository BackupRepository { get; } + private BackupStorageFactory BackupStorageFactory { get; } + + public BackupCleanerHelperService( + IOptionsMonitor options, + BackupRepository backupRepository, BackupStorageFactory backupStorageFactory) { - log = options.CurrentValue; - BackupRepository = backupRepository; - BackupStorageFactory = backupStorageFactory; + log = options.CurrentValue; + BackupRepository = backupRepository; + BackupStorageFactory = backupStorageFactory; } internal void DeleteExpiredBackups(BackupCleanerService backupCleanerService) { - log.Debug("started to clean expired backups"); - + log.Debug("started to clean expired backups"); + var backupsToRemove = BackupRepository.GetExpiredBackupRecords(); log.DebugFormat("found {0} backups which are expired", backupsToRemove.Count); @@ -95,14 +95,14 @@ namespace ASC.Data.Backup.Service backupStorage.Delete(backupRecord.StoragePath); BackupRepository.DeleteBackupRecord(backupRecord.Id); - } - catch (ProviderInfoArgumentException error) - { - log.Warn("can't remove backup record " + backupRecord.Id, error); - if (DateTime.UtcNow > backupRecord.CreatedOn.AddMonths(6)) - { - BackupRepository.DeleteBackupRecord(backupRecord.Id); - } + } + catch (ProviderInfoArgumentException error) + { + log.Warn("can't remove backup record " + backupRecord.Id, error); + if (DateTime.UtcNow > backupRecord.CreatedOn.AddMonths(6)) + { + BackupRepository.DeleteBackupRecord(backupRecord.Id); + } } catch (Exception error) { @@ -110,8 +110,8 @@ namespace ASC.Data.Backup.Service } } } - } - + } + [Singletone(Additional = typeof(BackupCleanerServiceExtension))] public class BackupCleanerService { @@ -119,14 +119,14 @@ namespace ASC.Data.Backup.Service private Timer CleanTimer { get; set; } internal bool IsStarted { get; set; } private ILog Log { get; set; } - public TimeSpan Period { get; set; } - private IServiceProvider ServiceProvider { get; set; } - - public BackupCleanerService( - IOptionsMonitor options, + public TimeSpan Period { get; set; } + private IServiceProvider ServiceProvider { get; set; } + + public BackupCleanerService( + IOptionsMonitor options, IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; + { + ServiceProvider = serviceProvider; Log = options.CurrentValue; Period = TimeSpan.FromMinutes(15); } @@ -164,10 +164,10 @@ namespace ASC.Data.Backup.Service if (Monitor.TryEnter(cleanerLock)) { try - { - - using var scope = ServiceProvider.CreateScope(); - var backupCleanerHelperService = scope.ServiceProvider.GetService(); + { + + using var scope = ServiceProvider.CreateScope(); + var backupCleanerHelperService = scope.ServiceProvider.GetService(); backupCleanerHelperService.DeleteExpiredBackups(this); } catch (Exception error) @@ -180,13 +180,13 @@ namespace ASC.Data.Backup.Service } } } - } - - public class BackupCleanerServiceExtension - { - public static void Register(DIHelper services) - { - services.TryAdd(); - } + } + + public class BackupCleanerServiceExtension + { + public static void Register(DIHelper services) + { + services.TryAdd(); + } } } diff --git a/common/services/ASC.Data.Backup/BackupResource.Designer.cs b/common/services/ASC.Data.Backup/Backup/BackupResource.Designer.cs similarity index 97% rename from common/services/ASC.Data.Backup/BackupResource.Designer.cs rename to common/services/ASC.Data.Backup/Backup/BackupResource.Designer.cs index e24a898531..8ce0296779 100644 --- a/common/services/ASC.Data.Backup/BackupResource.Designer.cs +++ b/common/services/ASC.Data.Backup/Backup/BackupResource.Designer.cs @@ -1,81 +1,81 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ASC.Data.Backup { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class BackupResource { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal BackupResource() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.Data.Backup.BackupResource", typeof(BackupResource).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to The backup file is invalid. Please, use a file created in ONLYOFFICE v11.5 or later.. - /// - internal static string BackupNotFound { - get { - return ResourceManager.GetString("BackupNotFound", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Set Password. - /// - internal static string ButtonSetPassword { - get { - return ResourceManager.GetString("ButtonSetPassword", resourceCulture); - } - } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.Data.Backup { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class BackupResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal BackupResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.Data.Backup.BackupResource", typeof(BackupResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The backup file is invalid. Please, use a file created in ONLYOFFICE v11.5 or later.. + /// + internal static string BackupNotFound { + get { + return ResourceManager.GetString("BackupNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set Password. + /// + internal static string ButtonSetPassword { + get { + return ResourceManager.GetString("ButtonSetPassword", resourceCulture); + } + } + } +} diff --git a/common/services/ASC.Data.Backup/BackupResource.resx b/common/services/ASC.Data.Backup/Backup/BackupResource.resx similarity index 97% rename from common/services/ASC.Data.Backup/BackupResource.resx rename to common/services/ASC.Data.Backup/Backup/BackupResource.resx index af666c1318..69c7f0c17e 100644 --- a/common/services/ASC.Data.Backup/BackupResource.resx +++ b/common/services/ASC.Data.Backup/Backup/BackupResource.resx @@ -1,67 +1,67 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - The backup file is invalid. Please, use a file created in ONLYOFFICE v11.5 or later. - - - Set Password - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The backup file is invalid. Please, use a file created in ONLYOFFICE v11.5 or later. + + + Set Password + \ No newline at end of file diff --git a/common/services/ASC.Data.Backup/Service/BackupSchedulerService.cs b/common/services/ASC.Data.Backup/Backup/BackupSchedulerService.cs similarity index 99% rename from common/services/ASC.Data.Backup/Service/BackupSchedulerService.cs rename to common/services/ASC.Data.Backup/Backup/BackupSchedulerService.cs index c261d3808b..b26a3033f5 100644 --- a/common/services/ASC.Data.Backup/Service/BackupSchedulerService.cs +++ b/common/services/ASC.Data.Backup/Backup/BackupSchedulerService.cs @@ -27,44 +27,44 @@ using System; using System.Linq; using System.Threading; - + using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Billing; using ASC.Data.Backup.Storage; - -using Microsoft.Extensions.DependencyInjection; + +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; namespace ASC.Data.Backup.Service -{ +{ [Scope] internal class BackupSchedulerServiceHelper { private ILog Log { get; } private PaymentManager PaymentManager { get; } - private BackupWorker BackupWorker { get; } - private BackupRepository BackupRepository { get; } - private Schedule Schedule { get; } - private TenantManager TenantManager { get; } - private CoreBaseSettings CoreBaseSettings { get; } - - public BackupSchedulerServiceHelper( - IOptionsMonitor options, - PaymentManager paymentManager, - BackupWorker backupWorker, - BackupRepository backupRepository, - Schedule schedule, - TenantManager tenantManager, + private BackupWorker BackupWorker { get; } + private BackupRepository BackupRepository { get; } + private Schedule Schedule { get; } + private TenantManager TenantManager { get; } + private CoreBaseSettings CoreBaseSettings { get; } + + public BackupSchedulerServiceHelper( + IOptionsMonitor options, + PaymentManager paymentManager, + BackupWorker backupWorker, + BackupRepository backupRepository, + Schedule schedule, + TenantManager tenantManager, CoreBaseSettings coreBaseSettings) { PaymentManager = paymentManager; - BackupWorker = backupWorker; - BackupRepository = backupRepository; - Schedule = schedule; - TenantManager = tenantManager; - CoreBaseSettings = coreBaseSettings; + BackupWorker = backupWorker; + BackupRepository = backupRepository; + Schedule = schedule; + TenantManager = tenantManager; + CoreBaseSettings = coreBaseSettings; Log = options.CurrentValue; } @@ -80,25 +80,25 @@ namespace ASC.Data.Backup.Service return; } try - { - if (CoreBaseSettings.Standalone || TenantManager.GetTenantQuota(schedule.TenantId).AutoBackup) - { - var tariff = PaymentManager.GetTariff(schedule.TenantId); - if (tariff.State < TariffState.Delay) - { - schedule.LastBackupTime = DateTime.UtcNow; - BackupRepository.SaveBackupSchedule(schedule); - Log.DebugFormat("Start scheduled backup: {0}, {1}, {2}, {3}", schedule.TenantId, schedule.BackupMail, schedule.StorageType, schedule.StorageBasePath); - BackupWorker.StartScheduledBackup(schedule); - } - else - { - Log.DebugFormat("Skip portal {0} not paid", schedule.TenantId); - } - } - else - { - Log.DebugFormat("Skip portal {0} haven't access", schedule.TenantId); + { + if (CoreBaseSettings.Standalone || TenantManager.GetTenantQuota(schedule.TenantId).AutoBackup) + { + var tariff = PaymentManager.GetTariff(schedule.TenantId); + if (tariff.State < TariffState.Delay) + { + schedule.LastBackupTime = DateTime.UtcNow; + BackupRepository.SaveBackupSchedule(schedule); + Log.DebugFormat("Start scheduled backup: {0}, {1}, {2}, {3}", schedule.TenantId, schedule.BackupMail, schedule.StorageType, schedule.StorageBasePath); + BackupWorker.StartScheduledBackup(schedule); + } + else + { + Log.DebugFormat("Skip portal {0} not paid", schedule.TenantId); + } + } + else + { + Log.DebugFormat("Skip portal {0} haven't access", schedule.TenantId); } } catch (Exception error) @@ -107,27 +107,27 @@ namespace ASC.Data.Backup.Service } } } - } - + } + [Singletone(Additional = typeof(BackupSchedulerServiceExtension))] public class BackupSchedulerService { private readonly object schedulerLock = new object(); private Timer SchedulerTimer { get; set; } - internal bool IsStarted { get; set; } + internal bool IsStarted { get; set; } public TimeSpan Period { get; set; } - private ILog Log { get; } - private IServiceProvider ServiceProvider { get; } - - public BackupSchedulerService( - IOptionsMonitor options, + private ILog Log { get; } + private IServiceProvider ServiceProvider { get; } + + public BackupSchedulerService( + IOptionsMonitor options, IServiceProvider serviceProvider) - { + { Log = options.CurrentValue; - Period = TimeSpan.FromMinutes(15); - ServiceProvider = serviceProvider; - } - + Period = TimeSpan.FromMinutes(15); + ServiceProvider = serviceProvider; + } + public void Start() { if (!IsStarted && Period > TimeSpan.Zero) @@ -160,9 +160,9 @@ namespace ASC.Data.Backup.Service if (Monitor.TryEnter(schedulerLock)) { try - { - using var scope = ServiceProvider.CreateScope(); - var backupSchedulerServiceHelper = scope.ServiceProvider.GetService(); + { + using var scope = ServiceProvider.CreateScope(); + var backupSchedulerServiceHelper = scope.ServiceProvider.GetService(); backupSchedulerServiceHelper.ScheduleBackupTasks(this); } catch (Exception error) @@ -175,13 +175,13 @@ namespace ASC.Data.Backup.Service } } } - } - - public class BackupSchedulerServiceExtension - { - public static void Register(DIHelper services) - { - services.TryAdd(); - } + } + + public class BackupSchedulerServiceExtension + { + public static void Register(DIHelper services) + { + services.TryAdd(); + } } } diff --git a/common/services/ASC.Data.Backup/BackupServiceLauncher.cs b/common/services/ASC.Data.Backup/Backup/BackupServiceLauncher.cs similarity index 99% rename from common/services/ASC.Data.Backup/BackupServiceLauncher.cs rename to common/services/ASC.Data.Backup/Backup/BackupServiceLauncher.cs index 57d0b94e9c..991dccefa6 100644 --- a/common/services/ASC.Data.Backup/BackupServiceLauncher.cs +++ b/common/services/ASC.Data.Backup/Backup/BackupServiceLauncher.cs @@ -29,42 +29,42 @@ using System.Threading.Tasks; using ASC.Common; using ASC.Common.Utils; -using ASC.Data.Backup.Listerners; -using ASC.Web.Studio.Core.Notify; - +using ASC.Data.Backup.Listerners; +using ASC.Web.Studio.Core.Notify; + using Microsoft.Extensions.Hosting; namespace ASC.Data.Backup.Service { [Singletone] internal class BackupServiceLauncher : IHostedService - { + { private BackupCleanerService CleanerService { get; set; } private BackupSchedulerService SchedulerService { get; set; } private BackupWorker BackupWorker { get; set; } - private ConfigurationExtension Configuration { get; set; } + private ConfigurationExtension Configuration { get; set; } private BackupListener BackupListener { get; set; } - public NotifyConfiguration NotifyConfiguration { get; } - - public BackupServiceLauncher( + public NotifyConfiguration NotifyConfiguration { get; } + + public BackupServiceLauncher( BackupCleanerService cleanerService, BackupSchedulerService schedulerService, BackupWorker backupWorker, ConfigurationExtension configuration, - BackupListener backupListener, + BackupListener backupListener, NotifyConfiguration notifyConfiguration) - { + { CleanerService = cleanerService; SchedulerService = schedulerService; BackupWorker = backupWorker; - Configuration = configuration; + Configuration = configuration; BackupListener = backupListener; - NotifyConfiguration = notifyConfiguration; + NotifyConfiguration = notifyConfiguration; } public Task StartAsync(CancellationToken cancellationToken) - { - NotifyConfiguration.Configure(); + { + NotifyConfiguration.Configure(); var settings = Configuration.GetSetting("backup"); diff --git a/common/services/ASC.Data.Backup/Controllers/BackupController.cs b/common/services/ASC.Data.Backup/Backup/Controllers/BackupController.cs similarity index 97% rename from common/services/ASC.Data.Backup/Controllers/BackupController.cs rename to common/services/ASC.Data.Backup/Backup/Controllers/BackupController.cs index ed2ec55b6b..67b805a5d3 100644 --- a/common/services/ASC.Data.Backup/Controllers/BackupController.cs +++ b/common/services/ASC.Data.Backup/Backup/Controllers/BackupController.cs @@ -1,271 +1,271 @@ - -using System; -using System.Collections.Generic; -using System.Linq; - -using ASC.Common; -using ASC.Core; -using ASC.Data.Backup.Contracts; -using ASC.Data.Backup.ModelApi; -using ASC.Data.Backup.Models; -using ASC.Web.Api.Routing; -using ASC.Web.Studio.Utility; - -using Microsoft.AspNetCore.Mvc; - -using static ASC.Data.Backup.BackupAjaxHandler; - -namespace ASC.Data.Backup.Controllers -{ - [Scope] - [DefaultRoute] - [ApiController] - public class BackupController - { - private BackupAjaxHandler BackupHandler { get; } - private CoreBaseSettings CoreBaseSettings { get; } - private TenantExtra TenantExtra { get; } - - public BackupController( - BackupAjaxHandler backupAjaxHandler, - CoreBaseSettings coreBaseSettings, - TenantExtra tenantExtra) - { - BackupHandler = backupAjaxHandler; - CoreBaseSettings = coreBaseSettings; - TenantExtra = tenantExtra; - } - /// - /// Returns the backup schedule of the current portal - /// - /// Backup - /// Backup Schedule - [Read("getbackupschedule")] - public BackupAjaxHandler.Schedule GetBackupSchedule() - { - if (CoreBaseSettings.Standalone) - { - TenantExtra.DemandControlPanelPermission(); - } - - return BackupHandler.GetSchedule(); - } - - /// - /// Create the backup schedule of the current portal - /// - /// Storage type - /// Storage parameters - /// Max of the backup's stored copies - /// Cron parameters - /// Include mail in the backup - /// Backup - [Create("createbackupschedule")] - public bool CreateBackupScheduleFromBody([FromBody]BackupSchedule backupSchedule) - { - return CreateBackupSchedule(backupSchedule); - } - - [Create("createbackupschedule")] - [Consumes("application/x-www-form-urlencoded")] - public bool CreateBackupScheduleFromForm([FromForm]BackupSchedule backupSchedule) - { - return CreateBackupSchedule(backupSchedule); - } - - private bool CreateBackupSchedule(BackupSchedule backupSchedule) - { - if (CoreBaseSettings.Standalone) - { - TenantExtra.DemandControlPanelPermission(); - } - var storageType = backupSchedule.StorageType == null ? BackupStorageType.Documents : (BackupStorageType)Int32.Parse(backupSchedule.StorageType); - var storageParams = backupSchedule.StorageParams == null ? new Dictionary() : backupSchedule.StorageParams.ToDictionary(r => r.Key.ToString(), r => r.Value.ToString()); - var backupStored = backupSchedule.BackupsStored == null ? 0 : Int32.Parse(backupSchedule.BackupsStored); - var cron = new CronParams() - { - Period = backupSchedule.CronParams.Period == null ? BackupPeriod.EveryDay : (BackupPeriod)Int32.Parse(backupSchedule.CronParams.Period), - Hour = backupSchedule.CronParams.Hour == null ? 0 : Int32.Parse(backupSchedule.CronParams.Hour), - Day = backupSchedule.CronParams.Day == null ? 0 : Int32.Parse(backupSchedule.CronParams.Day), - }; - BackupHandler.CreateSchedule(storageType, storageParams, backupStored, cron, backupSchedule.BackupMail); - return true; - } - - /// - /// Delete the backup schedule of the current portal - /// - /// Backup - [Delete("deletebackupschedule")] - public bool DeleteBackupSchedule() - { - if (CoreBaseSettings.Standalone) - { - TenantExtra.DemandControlPanelPermission(); - } - - BackupHandler.DeleteSchedule(); - - return true; - } - - /// - /// Start a backup of the current portal - /// - /// Storage Type - /// Storage Params - /// Include mail in the backup - /// Backup - /// Backup Progress - [Create("startbackup")] - public BackupProgress StartBackupFromBody([FromBody]Models.Backup backup) - { - return StartBackup(backup); - } - - [Create("startbackup")] - [Consumes("application/x-www-form-urlencoded")] - public BackupProgress StartBackupFromForm([FromForm]Models.Backup backup) - { - return StartBackup(backup); - } - - private BackupProgress StartBackup(Models.Backup backup) - { - if (CoreBaseSettings.Standalone) - { - TenantExtra.DemandControlPanelPermission(); - } - var storageType = backup.StorageType == null ? BackupStorageType.Documents : (BackupStorageType)Int32.Parse(backup.StorageType); - var storageParams = backup.StorageParams == null ? new Dictionary() : backup.StorageParams.ToDictionary(r => r.Key.ToString(), r => r.Value.ToString()); - BackupHandler.StartBackup(storageType, storageParams, backup.BackupMail); - return BackupHandler.GetBackupProgress(); - } - - /// - /// Returns the progress of the started backup - /// - /// Backup - /// Backup Progress - [Read("getbackupprogress")] - public BackupProgress GetBackupProgress() - { - if (CoreBaseSettings.Standalone) - { - TenantExtra.DemandControlPanelPermission(); - } - - return BackupHandler.GetBackupProgress(); - } - - /// - /// Returns the backup history of the started backup - /// - /// Backup - /// Backup History - [Read("getbackuphistory")] - public List GetBackupHistory() - { - if (CoreBaseSettings.Standalone) - { - TenantExtra.DemandControlPanelPermission(); - } - - return BackupHandler.GetBackupHistory(); - } - - /// - /// Delete the backup with the specified id - /// - /// Backup - [Delete("deletebackup/{id}")] - public bool DeleteBackup(Guid id) - { - if (CoreBaseSettings.Standalone) - { - TenantExtra.DemandControlPanelPermission(); - } - - BackupHandler.DeleteBackup(id); - return true; - } - - /// - /// Delete all backups of the current portal - /// - /// Backup - /// Backup History - [Delete("deletebackuphistory")] - public bool DeleteBackupHistory() - { - if (CoreBaseSettings.Standalone) - { - TenantExtra.DemandControlPanelPermission(); - } - - BackupHandler.DeleteAllBackups(); - return true; - } - - /// - /// Start a data restore of the current portal - /// - /// Backup Id - /// Storage Type - /// Storage Params - /// Notify about backup to users - /// Backup - /// Restore Progress - [Create("startrestore")] - public BackupProgress StartBackupRestoreFromBody([FromBody]BackupRestore backupRestore) - { - return StartBackupRestore(backupRestore); - } - - [Create("startrestore")] - [Consumes("application/x-www-form-urlencoded")] - public BackupProgress StartBackupRestoreFromForm([FromForm]BackupRestore backupRestore) - { - return StartBackupRestore(backupRestore); - } - - private BackupProgress StartBackupRestore(BackupRestore backupRestore) - { - if (CoreBaseSettings.Standalone) - { - TenantExtra.DemandControlPanelPermission(); - } - var storageParams = backupRestore.StorageParams == null ? new Dictionary() : backupRestore.StorageParams.ToDictionary(r => r.Key.ToString(), r => r.Value.ToString()); - BackupHandler.StartRestore(backupRestore.BackupId, (BackupStorageType)Int32.Parse(backupRestore.StorageType.ToString()), storageParams, backupRestore.Notify); - return BackupHandler.GetBackupProgress(); - } - - /// - /// Returns the progress of the started restore - /// - /// Backup - /// Restore Progress - [Read("getrestoreprogress", true)] //NOTE: this method doesn't check payment!!! - public BackupProgress GetRestoreProgress() - { - if (CoreBaseSettings.Standalone) - { - TenantExtra.DemandControlPanelPermission(); - } - - return BackupHandler.GetRestoreProgress(); - } - - ///false - [Read("backuptmp")] - public object GetTempPath() - { - if (CoreBaseSettings.Standalone) - { - TenantExtra.DemandControlPanelPermission(); - } - - return BackupHandler.GetTmpFolder(); - } - } -} + +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Common; +using ASC.Core; +using ASC.Data.Backup.Contracts; +using ASC.Data.Backup.ModelApi; +using ASC.Data.Backup.Models; +using ASC.Web.Api.Routing; +using ASC.Web.Studio.Utility; + +using Microsoft.AspNetCore.Mvc; + +using static ASC.Data.Backup.BackupAjaxHandler; + +namespace ASC.Data.Backup.Controllers +{ + [Scope] + [DefaultRoute] + [ApiController] + public class BackupController + { + private BackupAjaxHandler BackupHandler { get; } + private CoreBaseSettings CoreBaseSettings { get; } + private TenantExtra TenantExtra { get; } + + public BackupController( + BackupAjaxHandler backupAjaxHandler, + CoreBaseSettings coreBaseSettings, + TenantExtra tenantExtra) + { + BackupHandler = backupAjaxHandler; + CoreBaseSettings = coreBaseSettings; + TenantExtra = tenantExtra; + } + /// + /// Returns the backup schedule of the current portal + /// + /// Backup + /// Backup Schedule + [Read("getbackupschedule")] + public BackupAjaxHandler.Schedule GetBackupSchedule() + { + if (CoreBaseSettings.Standalone) + { + TenantExtra.DemandControlPanelPermission(); + } + + return BackupHandler.GetSchedule(); + } + + /// + /// Create the backup schedule of the current portal + /// + /// Storage type + /// Storage parameters + /// Max of the backup's stored copies + /// Cron parameters + /// Include mail in the backup + /// Backup + [Create("createbackupschedule")] + public bool CreateBackupScheduleFromBody([FromBody]BackupSchedule backupSchedule) + { + return CreateBackupSchedule(backupSchedule); + } + + [Create("createbackupschedule")] + [Consumes("application/x-www-form-urlencoded")] + public bool CreateBackupScheduleFromForm([FromForm]BackupSchedule backupSchedule) + { + return CreateBackupSchedule(backupSchedule); + } + + private bool CreateBackupSchedule(BackupSchedule backupSchedule) + { + if (CoreBaseSettings.Standalone) + { + TenantExtra.DemandControlPanelPermission(); + } + var storageType = backupSchedule.StorageType == null ? BackupStorageType.Documents : (BackupStorageType)Int32.Parse(backupSchedule.StorageType); + var storageParams = backupSchedule.StorageParams == null ? new Dictionary() : backupSchedule.StorageParams.ToDictionary(r => r.Key.ToString(), r => r.Value.ToString()); + var backupStored = backupSchedule.BackupsStored == null ? 0 : Int32.Parse(backupSchedule.BackupsStored); + var cron = new CronParams() + { + Period = backupSchedule.CronParams.Period == null ? BackupPeriod.EveryDay : (BackupPeriod)Int32.Parse(backupSchedule.CronParams.Period), + Hour = backupSchedule.CronParams.Hour == null ? 0 : Int32.Parse(backupSchedule.CronParams.Hour), + Day = backupSchedule.CronParams.Day == null ? 0 : Int32.Parse(backupSchedule.CronParams.Day), + }; + BackupHandler.CreateSchedule(storageType, storageParams, backupStored, cron, backupSchedule.BackupMail); + return true; + } + + /// + /// Delete the backup schedule of the current portal + /// + /// Backup + [Delete("deletebackupschedule")] + public bool DeleteBackupSchedule() + { + if (CoreBaseSettings.Standalone) + { + TenantExtra.DemandControlPanelPermission(); + } + + BackupHandler.DeleteSchedule(); + + return true; + } + + /// + /// Start a backup of the current portal + /// + /// Storage Type + /// Storage Params + /// Include mail in the backup + /// Backup + /// Backup Progress + [Create("startbackup")] + public BackupProgress StartBackupFromBody([FromBody]Models.Backup backup) + { + return StartBackup(backup); + } + + [Create("startbackup")] + [Consumes("application/x-www-form-urlencoded")] + public BackupProgress StartBackupFromForm([FromForm]Models.Backup backup) + { + return StartBackup(backup); + } + + private BackupProgress StartBackup(Models.Backup backup) + { + if (CoreBaseSettings.Standalone) + { + TenantExtra.DemandControlPanelPermission(); + } + var storageType = backup.StorageType == null ? BackupStorageType.Documents : (BackupStorageType)Int32.Parse(backup.StorageType); + var storageParams = backup.StorageParams == null ? new Dictionary() : backup.StorageParams.ToDictionary(r => r.Key.ToString(), r => r.Value.ToString()); + BackupHandler.StartBackup(storageType, storageParams, backup.BackupMail); + return BackupHandler.GetBackupProgress(); + } + + /// + /// Returns the progress of the started backup + /// + /// Backup + /// Backup Progress + [Read("getbackupprogress")] + public BackupProgress GetBackupProgress() + { + if (CoreBaseSettings.Standalone) + { + TenantExtra.DemandControlPanelPermission(); + } + + return BackupHandler.GetBackupProgress(); + } + + /// + /// Returns the backup history of the started backup + /// + /// Backup + /// Backup History + [Read("getbackuphistory")] + public List GetBackupHistory() + { + if (CoreBaseSettings.Standalone) + { + TenantExtra.DemandControlPanelPermission(); + } + + return BackupHandler.GetBackupHistory(); + } + + /// + /// Delete the backup with the specified id + /// + /// Backup + [Delete("deletebackup/{id}")] + public bool DeleteBackup(Guid id) + { + if (CoreBaseSettings.Standalone) + { + TenantExtra.DemandControlPanelPermission(); + } + + BackupHandler.DeleteBackup(id); + return true; + } + + /// + /// Delete all backups of the current portal + /// + /// Backup + /// Backup History + [Delete("deletebackuphistory")] + public bool DeleteBackupHistory() + { + if (CoreBaseSettings.Standalone) + { + TenantExtra.DemandControlPanelPermission(); + } + + BackupHandler.DeleteAllBackups(); + return true; + } + + /// + /// Start a data restore of the current portal + /// + /// Backup Id + /// Storage Type + /// Storage Params + /// Notify about backup to users + /// Backup + /// Restore Progress + [Create("startrestore")] + public BackupProgress StartBackupRestoreFromBody([FromBody]BackupRestore backupRestore) + { + return StartBackupRestore(backupRestore); + } + + [Create("startrestore")] + [Consumes("application/x-www-form-urlencoded")] + public BackupProgress StartBackupRestoreFromForm([FromForm]BackupRestore backupRestore) + { + return StartBackupRestore(backupRestore); + } + + private BackupProgress StartBackupRestore(BackupRestore backupRestore) + { + if (CoreBaseSettings.Standalone) + { + TenantExtra.DemandControlPanelPermission(); + } + var storageParams = backupRestore.StorageParams == null ? new Dictionary() : backupRestore.StorageParams.ToDictionary(r => r.Key.ToString(), r => r.Value.ToString()); + BackupHandler.StartRestore(backupRestore.BackupId, (BackupStorageType)Int32.Parse(backupRestore.StorageType.ToString()), storageParams, backupRestore.Notify); + return BackupHandler.GetBackupProgress(); + } + + /// + /// Returns the progress of the started restore + /// + /// Backup + /// Restore Progress + [Read("getrestoreprogress", true)] //NOTE: this method doesn't check payment!!! + public BackupProgress GetRestoreProgress() + { + if (CoreBaseSettings.Standalone) + { + TenantExtra.DemandControlPanelPermission(); + } + + return BackupHandler.GetRestoreProgress(); + } + + ///false + [Read("backuptmp")] + public object GetTempPath() + { + if (CoreBaseSettings.Standalone) + { + TenantExtra.DemandControlPanelPermission(); + } + + return BackupHandler.GetTmpFolder(); + } + } +} diff --git a/common/services/ASC.Data.Backup/ModelApi/Backup.cs b/common/services/ASC.Data.Backup/Backup/ModelApi/Backup.cs similarity index 100% rename from common/services/ASC.Data.Backup/ModelApi/Backup.cs rename to common/services/ASC.Data.Backup/Backup/ModelApi/Backup.cs diff --git a/common/services/ASC.Data.Backup/ModelApi/BackupRestore.cs b/common/services/ASC.Data.Backup/Backup/ModelApi/BackupRestore.cs similarity index 100% rename from common/services/ASC.Data.Backup/ModelApi/BackupRestore.cs rename to common/services/ASC.Data.Backup/Backup/ModelApi/BackupRestore.cs diff --git a/common/services/ASC.Data.Backup/ModelApi/BackupSchedule.cs b/common/services/ASC.Data.Backup/Backup/ModelApi/BackupSchedule.cs similarity index 100% rename from common/services/ASC.Data.Backup/ModelApi/BackupSchedule.cs rename to common/services/ASC.Data.Backup/Backup/ModelApi/BackupSchedule.cs diff --git a/common/services/ASC.Data.Backup/Program.cs b/common/services/ASC.Data.Backup/Backup/Program.cs similarity index 98% rename from common/services/ASC.Data.Backup/Program.cs rename to common/services/ASC.Data.Backup/Backup/Program.cs index 5ab5e7e6c2..3dbaf86c51 100644 --- a/common/services/ASC.Data.Backup/Program.cs +++ b/common/services/ASC.Data.Backup/Backup/Program.cs @@ -1,56 +1,56 @@ -using System; +using System; using System.Collections.Generic; using System.IO; -using System.Runtime.InteropServices; -using System.Threading.Tasks; - -using ASC.Api.Core; -using ASC.Common.Utils; - -using Autofac.Extensions.DependencyInjection; - -using Microsoft.AspNetCore.Hosting; +using System.Runtime.InteropServices; +using System.Threading.Tasks; + +using ASC.Api.Core; +using ASC.Common.Utils; + +using Autofac.Extensions.DependencyInjection; + +using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; namespace ASC.Data.Backup { public class Program - { + { public async static Task Main(string[] args) - { - var host = CreateHostBuilder(args).Build(); - + { + var host = CreateHostBuilder(args).Build(); + await host.RunAsync(); } - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .UseSystemd() - .UseWindowsService() + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .UseSystemd() + .UseWindowsService() .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureWebHostDefaults(webBuilder => { - var builder = webBuilder.UseStartup(); - - builder.ConfigureKestrel((hostingContext, serverOptions) => - { - var kestrelConfig = hostingContext.Configuration.GetSection("Kestrel"); - - if (!kestrelConfig.Exists()) return; - - var unixSocket = kestrelConfig.GetValue("ListenUnixSocket"); - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - if (!String.IsNullOrWhiteSpace(unixSocket)) - { - unixSocket = String.Format(unixSocket, hostingContext.HostingEnvironment.ApplicationName.Replace("ASC.", "").Replace(".", "")); - - serverOptions.ListenUnixSocket(unixSocket); - } - } - }); + var builder = webBuilder.UseStartup(); + + builder.ConfigureKestrel((hostingContext, serverOptions) => + { + var kestrelConfig = hostingContext.Configuration.GetSection("Kestrel"); + + if (!kestrelConfig.Exists()) return; + + var unixSocket = kestrelConfig.GetValue("ListenUnixSocket"); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + if (!String.IsNullOrWhiteSpace(unixSocket)) + { + unixSocket = String.Format(unixSocket, hostingContext.HostingEnvironment.ApplicationName.Replace("ASC.", "").Replace(".", "")); + + serverOptions.ListenUnixSocket(unixSocket); + } + } + }); }) .ConfigureAppConfiguration((hostContext, config) => { @@ -70,14 +70,14 @@ namespace ASC.Data.Backup .AddJsonFile("backup.json") .AddJsonFile("kafka.json") .AddJsonFile($"kafka.{env}.json", true) - .AddEnvironmentVariables() + .AddEnvironmentVariables() .AddInMemoryCollection(new Dictionary { {"pathToConf", path } } ); - }) - .ConfigureNLogLogging(); + }) + .ConfigureNLogLogging(); } } diff --git a/common/services/ASC.Data.Backup/Properties/launchSettings.json b/common/services/ASC.Data.Backup/Backup/Properties/launchSettings.json similarity index 100% rename from common/services/ASC.Data.Backup/Properties/launchSettings.json rename to common/services/ASC.Data.Backup/Backup/Properties/launchSettings.json diff --git a/common/services/ASC.Data.Backup/Startup.cs b/common/services/ASC.Data.Backup/Backup/Startup.cs similarity index 99% rename from common/services/ASC.Data.Backup/Startup.cs rename to common/services/ASC.Data.Backup/Backup/Startup.cs index 794da2ed9a..a4a59493d7 100644 --- a/common/services/ASC.Data.Backup/Startup.cs +++ b/common/services/ASC.Data.Backup/Backup/Startup.cs @@ -21,15 +21,15 @@ * in every copy of the program you distribute. * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. * -*/ - +*/ + using ASC.Api.Core; -using ASC.Common; -using ASC.Common.Threading; +using ASC.Common; +using ASC.Common.Threading; using ASC.Data.Backup.Controllers; -using ASC.Data.Backup.Service; -using ASC.Web.Studio.Core.Notify; - +using ASC.Data.Backup.Service; +using ASC.Web.Studio.Core.Notify; + using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -41,22 +41,22 @@ namespace ASC.Data.Backup public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment) : base(configuration, hostEnvironment) { - } + } - public override void ConfigureServices(IServiceCollection services) + public override void ConfigureServices(IServiceCollection services) { - base.ConfigureServices(services); + base.ConfigureServices(services); DIHelper.AddDistributedTaskQueueService(1); - - DIHelper.TryAdd(); - DIHelper.TryAdd(); - DIHelper.TryAdd(); - - DIHelper.TryAdd(); - DIHelper.TryAdd(); - NotifyConfigurationExtension.Register(DIHelper); - + + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + + DIHelper.TryAdd(); + DIHelper.TryAdd(); + NotifyConfigurationExtension.Register(DIHelper); + services.AddHostedService(); } } diff --git a/common/services/ASC.Data.Backup/appsettings.json b/common/services/ASC.Data.Backup/Backup/appsettings.json similarity index 100% rename from common/services/ASC.Data.Backup/appsettings.json rename to common/services/ASC.Data.Backup/Backup/appsettings.json diff --git a/common/services/ASC.Data.Backup/Core/ASC.Data.Backup.Core.csproj b/common/services/ASC.Data.Backup/Core/ASC.Data.Backup.Core.csproj new file mode 100644 index 0000000000..cadb700249 --- /dev/null +++ b/common/services/ASC.Data.Backup/Core/ASC.Data.Backup.Core.csproj @@ -0,0 +1,54 @@ + + + + Exe + net5.0 + Library + NU1701 + + + + + + + + + + + + + + + + true + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + BackupResource.resx + True + True + + + + + + BackupResource.Designer.cs + ResXFileCodeGenerator + + + diff --git a/common/services/ASC.Data.Backup/ActionInvoker.cs b/common/services/ASC.Data.Backup/Core/ActionInvoker.cs similarity index 99% rename from common/services/ASC.Data.Backup/ActionInvoker.cs rename to common/services/ASC.Data.Backup/Core/ActionInvoker.cs index 95668a22f9..e4ce168963 100644 --- a/common/services/ASC.Data.Backup/ActionInvoker.cs +++ b/common/services/ASC.Data.Backup/Core/ActionInvoker.cs @@ -32,7 +32,7 @@ namespace ASC.Data.Backup public static class ActionInvoker { public static void Try( - Action action, + Action action, int maxAttempts, Action onFailure = null, Action onAttemptFailure = null, @@ -65,13 +65,13 @@ namespace ASC.Data.Backup catch (Exception error) { if (countAttempts < maxAttempts) - { + { onAttemptFailure?.Invoke(error); - if (sleepMs > 0) + if (sleepMs > 0) Thread.Sleep(isSleepExponential ? sleepMs * countAttempts : sleepMs); } - else + else { onFailure?.Invoke(error); } diff --git a/common/services/ASC.Data.Backup/BackupAjaxHandler.cs b/common/services/ASC.Data.Backup/Core/BackupAjaxHandler.cs similarity index 99% rename from common/services/ASC.Data.Backup/BackupAjaxHandler.cs rename to common/services/ASC.Data.Backup/Core/BackupAjaxHandler.cs index 03b91d59a6..5dd3db0376 100644 --- a/common/services/ASC.Data.Backup/BackupAjaxHandler.cs +++ b/common/services/ASC.Data.Backup/Core/BackupAjaxHandler.cs @@ -1,24 +1,24 @@ using System; using System.Collections.Generic; -using System.Linq; - -using ASC.Api.Utils; +using System.Linq; + +using ASC.Api.Utils; using ASC.Common; using ASC.Core; using ASC.Core.Billing; using ASC.Core.Common.Configuration; using ASC.Core.Users; -using ASC.Data.Backup.Contracts; -using ASC.Data.Backup.Service; +using ASC.Data.Backup.Contracts; +using ASC.Data.Backup.Service; using ASC.MessagingSystem; using ASC.Notify.Cron; using ASC.Web.Core.PublicResources; using ASC.Web.Studio.Core; -using ASC.Web.Studio.Core.Backup; -using ASC.Web.Studio.Utility; +using ASC.Web.Studio.Core.Backup; +using ASC.Web.Studio.Utility; namespace ASC.Data.Backup -{ +{ [Scope] public class BackupAjaxHandler { @@ -30,23 +30,23 @@ namespace ASC.Data.Backup private SecurityContext SecurityContext { get; } private UserManager UserManager { get; } private TenantExtra TenantExtra { get; } - private ConsumerFactory ConsumerFactory { get; } - private BackupFileUploadHandler BackupFileUploadHandler { get; } - private BackupService BackupService { get; } + private ConsumerFactory ConsumerFactory { get; } + private BackupFileUploadHandler BackupFileUploadHandler { get; } + private BackupService BackupService { get; } #region backup - public BackupAjaxHandler( - BackupService backupService, - TenantManager tenantManager, - MessageService messageService, - CoreBaseSettings coreBaseSettings, - CoreConfiguration coreConfiguration, - PermissionContext permissionContext, - SecurityContext securityContext, - UserManager userManager, - TenantExtra tenantExtra, - ConsumerFactory consumerFactory, + public BackupAjaxHandler( + BackupService backupService, + TenantManager tenantManager, + MessageService messageService, + CoreBaseSettings coreBaseSettings, + CoreConfiguration coreConfiguration, + PermissionContext permissionContext, + SecurityContext securityContext, + UserManager userManager, + TenantExtra tenantExtra, + ConsumerFactory consumerFactory, BackupFileUploadHandler backupFileUploadHandler) { TenantManager = tenantManager; @@ -57,8 +57,8 @@ namespace ASC.Data.Backup SecurityContext = securityContext; UserManager = userManager; TenantExtra = tenantExtra; - ConsumerFactory = consumerFactory; - BackupFileUploadHandler = backupFileUploadHandler; + ConsumerFactory = consumerFactory; + BackupFileUploadHandler = backupFileUploadHandler; BackupService = backupService; } @@ -71,7 +71,7 @@ namespace ASC.Data.Backup TenantId = GetCurrentTenantId(), UserId = SecurityContext.CurrentAccount.ID, BackupMail = backupMail, - StorageType = storageType, + StorageType = storageType, StorageParams = storageParams }; @@ -87,22 +87,22 @@ namespace ASC.Data.Backup break; } - MessageService.Send(MessageAction.StartBackupSetting); - + MessageService.Send(MessageAction.StartBackupSetting); + BackupService.StartBackup(backupRequest); } public BackupProgress GetBackupProgress() { - DemandPermissionsBackup(); - + DemandPermissionsBackup(); + return BackupService.GetBackupProgress(GetCurrentTenantId()); } public BackupProgress GetBackupProgress(int tenantId) { - DemandPermissionsBackup(); - + DemandPermissionsBackup(); + return BackupService.GetBackupProgress(tenantId); } @@ -141,10 +141,10 @@ namespace ASC.Data.Backup BackupMail = backupMail, Cron = cronParams.ToString(), NumberOfBackupsStored = backupsStored, - StorageType = storageType, + StorageType = storageType, StorageParams = storageParams - }; - + }; + switch (storageType) { case BackupStorageType.ThridpartyDocuments: @@ -206,7 +206,7 @@ namespace ASC.Data.Backup BackupMail = schedule.BackupMail != null && (bool)schedule.BackupMail, Cron = schedule.CronParams.ToString(), NumberOfBackupsStored = schedule.BackupsStored == null ? 0 : (int)schedule.BackupsStored, - StorageType = schedule.StorageType, + StorageType = schedule.StorageType, StorageParams = schedule.StorageParams }; @@ -248,7 +248,7 @@ namespace ASC.Data.Backup var restoreRequest = new StartRestoreRequest { TenantId = GetCurrentTenantId(), - NotifyAfterCompletion = notify, + NotifyAfterCompletion = notify, StorageParams = storageParams }; @@ -259,13 +259,13 @@ namespace ASC.Data.Backup else { restoreRequest.StorageType = storageType; - restoreRequest.FilePathOrId = storageParams["filePath"]; - - if (restoreRequest.StorageType == BackupStorageType.Local && !CoreBaseSettings.Standalone) - { - restoreRequest.FilePathOrId = BackupFileUploadHandler.GetFilePath(); + restoreRequest.FilePathOrId = storageParams["filePath"]; + + if (restoreRequest.StorageType == BackupStorageType.Local && !CoreBaseSettings.Standalone) + { + restoreRequest.FilePathOrId = BackupFileUploadHandler.GetFilePath(); } - } + } BackupService.StartRestore(restoreRequest); } @@ -282,9 +282,9 @@ namespace ASC.Data.Backup private void DemandPermissionsRestore() { - PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings); - - if (!SetupInfo.IsVisibleSettings("Restore") || + PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings); + + if (!SetupInfo.IsVisibleSettings("Restore") || (!CoreBaseSettings.Standalone && !TenantManager.GetTenantQuota(TenantManager.GetCurrentTenant().TenantId).Restore)) throw new BillingException(Resource.ErrorNotAllowedOption, "Restore"); } @@ -310,7 +310,7 @@ namespace ASC.Data.Backup } public BackupProgress GetTransferProgress() - { + { return BackupService.GetTransferProgress(GetCurrentTenantId()); } @@ -384,13 +384,13 @@ namespace ASC.Data.Backup public override string ToString() { - return Period switch - { - BackupPeriod.EveryDay => string.Format("0 0 {0} ? * *", Hour), - BackupPeriod.EveryMonth => string.Format("0 0 {0} {1} * ?", Hour, Day), - BackupPeriod.EveryWeek => string.Format("0 0 {0} ? * {1}", Hour, Day), - _ => base.ToString(), - }; + return Period switch + { + BackupPeriod.EveryDay => string.Format("0 0 {0} ? * *", Hour), + BackupPeriod.EveryMonth => string.Format("0 0 {0} {1} * ?", Hour, Day), + BackupPeriod.EveryWeek => string.Format("0 0 {0} ? * {1}", Hour, Day), + _ => base.ToString(), + }; } } diff --git a/common/services/ASC.Data.Backup/BackupFileUploadHandler.cs b/common/services/ASC.Data.Backup/Core/BackupFileUploadHandler.cs similarity index 96% rename from common/services/ASC.Data.Backup/BackupFileUploadHandler.cs rename to common/services/ASC.Data.Backup/Core/BackupFileUploadHandler.cs index a5a2d79116..c2dc6b9b04 100644 --- a/common/services/ASC.Data.Backup/BackupFileUploadHandler.cs +++ b/common/services/ASC.Data.Backup/Core/BackupFileUploadHandler.cs @@ -1,100 +1,100 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2021 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.IO; - -using ASC.Common; -using ASC.Core; - -using Microsoft.AspNetCore.Http; - -namespace ASC.Web.Studio.Core.Backup -{ - [Scope] - public class BackupFileUploadHandler - { - private const long MaxBackupFileSize = 1024L * 1024L * 1024L; - private const string BackupTempFolder = "backup"; - private const string BackupFileName = "backup.tmp"; - - private PermissionContext PermissionContext { get; } - private TempPath TempPath { get; } - private TenantManager TenantManager { get; } - - public BackupFileUploadHandler( - PermissionContext permissionContext, - TempPath tempPath, - TenantManager tenantManager) - { - PermissionContext = permissionContext; - TempPath = tempPath; - TenantManager = tenantManager; - } - - public string ProcessUpload(IFormFile file) - { - if (file == null) - { - return "No files."; - } - - if (!PermissionContext.CheckPermissions(SecutiryConstants.EditPortalSettings)) - { - return "Access denied."; - } - - if (file.Length <= 0 || file.Length > MaxBackupFileSize) - { - return $"File size must be greater than 0 and less than {MaxBackupFileSize} bytes"; - } - - try - { - var filePath = GetFilePath(); - - if (File.Exists(filePath)) - { - File.Delete(filePath); - } - - using (var fileStream = File.Create(filePath)) - { - file.CopyTo(fileStream); - } - - return string.Empty; - } - catch (Exception error) - { - return error.Message; - } - } - - internal string GetFilePath() - { - var folder = Path.Combine(TempPath.GetTempPath(), BackupTempFolder, TenantManager.GetCurrentTenant().TenantId.ToString()); - - if (!Directory.Exists(folder)) - { - Directory.CreateDirectory(folder); - } - - return Path.Combine(folder, BackupFileName); - } - } +/* + * + * (c) Copyright Ascensio System Limited 2010-2021 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + + +using System; +using System.IO; + +using ASC.Common; +using ASC.Core; + +using Microsoft.AspNetCore.Http; + +namespace ASC.Web.Studio.Core.Backup +{ + [Scope] + public class BackupFileUploadHandler + { + private const long MaxBackupFileSize = 1024L * 1024L * 1024L; + private const string BackupTempFolder = "backup"; + private const string BackupFileName = "backup.tmp"; + + private PermissionContext PermissionContext { get; } + private TempPath TempPath { get; } + private TenantManager TenantManager { get; } + + public BackupFileUploadHandler( + PermissionContext permissionContext, + TempPath tempPath, + TenantManager tenantManager) + { + PermissionContext = permissionContext; + TempPath = tempPath; + TenantManager = tenantManager; + } + + public string ProcessUpload(IFormFile file) + { + if (file == null) + { + return "No files."; + } + + if (!PermissionContext.CheckPermissions(SecutiryConstants.EditPortalSettings)) + { + return "Access denied."; + } + + if (file.Length <= 0 || file.Length > MaxBackupFileSize) + { + return $"File size must be greater than 0 and less than {MaxBackupFileSize} bytes"; + } + + try + { + var filePath = GetFilePath(); + + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + + using (var fileStream = File.Create(filePath)) + { + file.CopyTo(fileStream); + } + + return string.Empty; + } + catch (Exception error) + { + return error.Message; + } + } + + internal string GetFilePath() + { + var folder = Path.Combine(TempPath.GetTempPath(), BackupTempFolder, TenantManager.GetCurrentTenant().TenantId.ToString()); + + if (!Directory.Exists(folder)) + { + Directory.CreateDirectory(folder); + } + + return Path.Combine(folder, BackupFileName); + } + } } \ No newline at end of file diff --git a/common/services/ASC.Data.Backup/Core/BackupResource.Designer.cs b/common/services/ASC.Data.Backup/Core/BackupResource.Designer.cs new file mode 100644 index 0000000000..35bf97bd3e --- /dev/null +++ b/common/services/ASC.Data.Backup/Core/BackupResource.Designer.cs @@ -0,0 +1,81 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.Data.Backup.Core { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class BackupResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal BackupResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.Data.Backup.Core.BackupResource", typeof(BackupResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The backup file is invalid. Please, use a file created in ONLYOFFICE v11.5 or later.. + /// + internal static string BackupNotFound { + get { + return ResourceManager.GetString("BackupNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set Password. + /// + internal static string ButtonSetPassword { + get { + return ResourceManager.GetString("ButtonSetPassword", resourceCulture); + } + } + } +} diff --git a/common/services/ASC.Data.Backup/Core/BackupResource.resx b/common/services/ASC.Data.Backup/Core/BackupResource.resx new file mode 100644 index 0000000000..69c7f0c17e --- /dev/null +++ b/common/services/ASC.Data.Backup/Core/BackupResource.resx @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The backup file is invalid. Please, use a file created in ONLYOFFICE v11.5 or later. + + + Set Password + + \ No newline at end of file diff --git a/common/services/ASC.Data.Backup/Contracts/BackupServiceModel.cs b/common/services/ASC.Data.Backup/Core/Contracts/BackupServiceModel.cs similarity index 97% rename from common/services/ASC.Data.Backup/Contracts/BackupServiceModel.cs rename to common/services/ASC.Data.Backup/Core/Contracts/BackupServiceModel.cs index 38cb142337..03066dcf33 100644 --- a/common/services/ASC.Data.Backup/Contracts/BackupServiceModel.cs +++ b/common/services/ASC.Data.Backup/Core/Contracts/BackupServiceModel.cs @@ -23,9 +23,9 @@ * */ -using System; -using System.Collections.Generic; - +using System; +using System.Collections.Generic; + namespace ASC.Data.Backup.Contracts { public enum BackupStorageType @@ -41,130 +41,130 @@ namespace ASC.Data.Backup.Contracts DataStore = 4, ThirdPartyConsumer = 5 - } + } public class StartBackupRequest { - public int TenantId { get; set; } - - - public Guid UserId { get; set; } - - - public bool BackupMail { get; set; } - - - public BackupStorageType StorageType { get; set; } - - - public string StorageBasePath { get; set; } - - - public Dictionary StorageParams { get; set; } - } - - - public class BackupHistoryRecord - { - - public Guid Id { get; set; } - - - public string FileName { get; set; } - - - public BackupStorageType StorageType { get; set; } - - - public DateTime CreatedOn { get; set; } - - - public DateTime ExpiresOn { get; set; } - } - - - public class StartTransferRequest - { - - public int TenantId { get; set; } - - - public string TargetRegion { get; set; } - - - public bool NotifyUsers { get; set; } - - + public int TenantId { get; set; } + + + public Guid UserId { get; set; } + + public bool BackupMail { get; set; } - } - - - public class TransferRegion - { - - public string Name { get; set; } - - - public string BaseDomain { get; set; } - - - public bool IsCurrentRegion { get; set; } - } - - - public class StartRestoreRequest - { - - public int TenantId { get; set; } - - - public Guid BackupId { get; set; } - - - public BackupStorageType StorageType { get; set; } - - - public string FilePathOrId { get; set; } - - - public bool NotifyAfterCompletion { get; set; } - - + + + public BackupStorageType StorageType { get; set; } + + + public string StorageBasePath { get; set; } + + public Dictionary StorageParams { get; set; } - } - - + } + + + public class BackupHistoryRecord + { + + public Guid Id { get; set; } + + + public string FileName { get; set; } + + + public BackupStorageType StorageType { get; set; } + + + public DateTime CreatedOn { get; set; } + + + public DateTime ExpiresOn { get; set; } + } + + + public class StartTransferRequest + { + + public int TenantId { get; set; } + + + public string TargetRegion { get; set; } + + + public bool NotifyUsers { get; set; } + + + public bool BackupMail { get; set; } + } + + + public class TransferRegion + { + + public string Name { get; set; } + + + public string BaseDomain { get; set; } + + + public bool IsCurrentRegion { get; set; } + } + + + public class StartRestoreRequest + { + + public int TenantId { get; set; } + + + public Guid BackupId { get; set; } + + + public BackupStorageType StorageType { get; set; } + + + public string FilePathOrId { get; set; } + + + public bool NotifyAfterCompletion { get; set; } + + + public Dictionary StorageParams { get; set; } + } + + public class CreateScheduleRequest : StartBackupRequest - { - - public string Cron { get; set; } - - + { + + public string Cron { get; set; } + + public int NumberOfBackupsStored { get; set; } - } - - + } + + public class ScheduleResponse - { - - public BackupStorageType StorageType { get; set; } - - - public string StorageBasePath { get; set; } - - - public bool BackupMail { get; set; } - - - public int NumberOfBackupsStored { get; set; } - - - public string Cron { get; set; } - - - public DateTime LastBackupTime { get; set; } - - + { + + public BackupStorageType StorageType { get; set; } + + + public string StorageBasePath { get; set; } + + + public bool BackupMail { get; set; } + + + public int NumberOfBackupsStored { get; set; } + + + public string Cron { get; set; } + + + public DateTime LastBackupTime { get; set; } + + public Dictionary StorageParams { get; set; } } } \ No newline at end of file diff --git a/common/services/ASC.Data.Backup/Contracts/IBackupService.cs b/common/services/ASC.Data.Backup/Core/Contracts/IBackupService.cs similarity index 100% rename from common/services/ASC.Data.Backup/Contracts/IBackupService.cs rename to common/services/ASC.Data.Backup/Core/Contracts/IBackupService.cs diff --git a/common/services/ASC.Data.Backup/Core/DbBackupProvider.cs b/common/services/ASC.Data.Backup/Core/Core/DbBackupProvider.cs similarity index 99% rename from common/services/ASC.Data.Backup/Core/DbBackupProvider.cs rename to common/services/ASC.Data.Backup/Core/Core/DbBackupProvider.cs index 24603332ef..8b157647a2 100644 --- a/common/services/ASC.Data.Backup/Core/DbBackupProvider.cs +++ b/common/services/ASC.Data.Backup/Core/Core/DbBackupProvider.cs @@ -31,20 +31,20 @@ using System.Data; using System.IO; using System.Linq; using System.Threading; -using System.Xml.Linq; - +using System.Xml.Linq; + using ASC.Common; -using ASC.Common.Utils; - +using ASC.Common.Utils; + namespace ASC.Data.Backup -{ +{ [Scope] public class DbBackupProvider : IBackupProvider { private readonly List processedTables = new List(); - private readonly DbHelper dbHelper; - private readonly TempStream tempStream; - + private readonly DbHelper dbHelper; + private readonly TempStream tempStream; + public string Name { get { return "databases"; } @@ -52,8 +52,8 @@ namespace ASC.Data.Backup public DbBackupProvider(DbHelper dbHelper, TempStream tempStream) { - this.dbHelper = dbHelper; - this.tempStream = tempStream; + this.dbHelper = dbHelper; + this.tempStream = tempStream; } public IEnumerable GetElements(int tenant, string[] configs, IDataWriteOperator writer) { @@ -104,13 +104,13 @@ namespace ASC.Data.Backup { if (config.Contains(Path.DirectorySeparatorChar) && !Uri.IsWellFormedUriString(config, UriKind.Relative)) { - var map = new ExeConfigurationFileMap - { - ExeConfigFilename = string.Compare(Path.GetExtension(config), ".config", true) == 0 ? config : CrossPlatform.PathCombine(config, "Web.config") + var map = new ExeConfigurationFileMap + { + ExeConfigFilename = string.Compare(Path.GetExtension(config), ".config", true) == 0 ? config : CrossPlatform.PathCombine(config, "Web.config") }; return ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None); } - return ConfigurationManager.OpenExeConfiguration(config); + return ConfigurationManager.OpenExeConfiguration(config); } public IEnumerable GetConnectionStrings(string[] configs) @@ -178,12 +178,12 @@ namespace ASC.Data.Backup foreach (DataColumn c in dataTable.Columns) { if (c.DataType == typeof(DateTime)) c.DateTimeMode = DataSetDateTime.Unspecified; - } - - using (var file = tempStream.Create()) - { - dataTable.WriteXml(file, XmlWriteMode.WriteSchema); - writer.WriteEntry(string.Format("{0}\\{1}\\{2}", Name, connectionString.Name, table).ToLower(), file); + } + + using (var file = tempStream.Create()) + { + dataTable.WriteXml(file, XmlWriteMode.WriteSchema); + writer.WriteEntry(string.Format("{0}\\{1}\\{2}", Name, connectionString.Name, table).ToLower(), file); } processedTables.Add(table); @@ -224,6 +224,6 @@ namespace ASC.Data.Backup processedTables.Add(table); } } - } + } } } diff --git a/common/services/ASC.Data.Backup/Core/DbHelper.cs b/common/services/ASC.Data.Backup/Core/Core/DbHelper.cs similarity index 99% rename from common/services/ASC.Data.Backup/Core/DbHelper.cs rename to common/services/ASC.Data.Backup/Core/Core/DbHelper.cs index 21a4474512..3df6f196eb 100644 --- a/common/services/ASC.Data.Backup/Core/DbHelper.cs +++ b/common/services/ASC.Data.Backup/Core/Core/DbHelper.cs @@ -11,14 +11,14 @@ using System.Xml.XPath; using ASC.Common; using ASC.Common.Logging; -using ASC.Common.Utils; +using ASC.Common.Utils; using ASC.Data.Backup.EF.Context; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.Data.Backup -{ +{ [Scope] public class DbHelper : IDisposable { diff --git a/common/services/ASC.Data.Backup/Core/FileBackupProvider.cs b/common/services/ASC.Data.Backup/Core/Core/FileBackupProvider.cs similarity index 99% rename from common/services/ASC.Data.Backup/Core/FileBackupProvider.cs rename to common/services/ASC.Data.Backup/Core/Core/FileBackupProvider.cs index 54607383cd..5494183ad2 100644 --- a/common/services/ASC.Data.Backup/Core/FileBackupProvider.cs +++ b/common/services/ASC.Data.Backup/Core/Core/FileBackupProvider.cs @@ -28,25 +28,25 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Xml.Linq; - +using System.Xml.Linq; + using ASC.Common; using ASC.Common.Logging; -using ASC.Common.Utils; -using ASC.Data.Storage; - +using ASC.Common.Utils; +using ASC.Data.Storage; + using Microsoft.Extensions.Options; namespace ASC.Data.Backup -{ +{ [Scope] public class FileBackupProvider : IBackupProvider { private readonly IEnumerable allowedModules; private readonly ILog log; private StorageFactory StorageFactory { get; set; } - private StorageFactoryConfig StorageFactoryConfig { get; set; } - + private StorageFactoryConfig StorageFactoryConfig { get; set; } + public FileBackupProvider(IOptionsMonitor options, StorageFactory storageFactory, StorageFactoryConfig storageFactoryConfig) { StorageFactory = storageFactory; @@ -90,7 +90,7 @@ namespace ASC.Data.Backup { try { - using var stream = storage.GetReadStream(file.Domain, file.Path); + using var stream = storage.GetReadStream(file.Domain, file.Path); writer.WriteEntry(backupPath, stream); break; } @@ -240,10 +240,10 @@ namespace ASC.Data.Backup return Equals(other.Module, Module) && Equals(other.Domain, Domain) && Equals(other.Path, Path); } - public override int GetHashCode() - { - return HashCode.Combine(Module, Domain, Path); - } + public override int GetHashCode() + { + return HashCode.Combine(Module, Domain, Path); + } } } } \ No newline at end of file diff --git a/common/services/ASC.Data.Backup/Core/IBackupProvider.cs b/common/services/ASC.Data.Backup/Core/Core/IBackupProvider.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/IBackupProvider.cs rename to common/services/ASC.Data.Backup/Core/Core/IBackupProvider.cs diff --git a/common/services/ASC.Data.Backup/Core/IDataOperator.cs b/common/services/ASC.Data.Backup/Core/Core/IDataOperator.cs similarity index 99% rename from common/services/ASC.Data.Backup/Core/IDataOperator.cs rename to common/services/ASC.Data.Backup/Core/Core/IDataOperator.cs index 323a323d9d..a2d6f46bb3 100644 --- a/common/services/ASC.Data.Backup/Core/IDataOperator.cs +++ b/common/services/ASC.Data.Backup/Core/Core/IDataOperator.cs @@ -37,7 +37,7 @@ namespace ASC.Data.Backup public interface IDataReadOperator : IDisposable { - Stream GetEntry(string key); + Stream GetEntry(string key); IEnumerable GetEntries(string key); } } \ No newline at end of file diff --git a/common/services/ASC.Data.Backup/Core/NotifyHelper.cs b/common/services/ASC.Data.Backup/Core/Core/NotifyHelper.cs similarity index 98% rename from common/services/ASC.Data.Backup/Core/NotifyHelper.cs rename to common/services/ASC.Data.Backup/Core/Core/NotifyHelper.cs index 818b8cb274..db8968d5c6 100644 --- a/common/services/ASC.Data.Backup/Core/NotifyHelper.cs +++ b/common/services/ASC.Data.Backup/Core/Core/NotifyHelper.cs @@ -25,222 +25,223 @@ using System; -using System.Collections.Generic; -using System.Linq; - +using System.Collections.Generic; +using System.Linq; + using ASC.Common; -using ASC.Core; -using ASC.Core.Tenants; -using ASC.Core.Users; -using ASC.Notify.Model; -using ASC.Notify.Patterns; -using ASC.Notify.Recipients; -using ASC.Web.Core.Users; -using ASC.Web.Core.WhiteLabel; -using ASC.Web.Studio.Core.Notify; -using ASC.Web.Studio.Utility; - -using Microsoft.Extensions.DependencyInjection; - +using ASC.Core; +using ASC.Core.Tenants; +using ASC.Core.Users; +using ASC.Data.Backup.Core; +using ASC.Notify.Model; +using ASC.Notify.Patterns; +using ASC.Notify.Recipients; +using ASC.Web.Core.Users; +using ASC.Web.Core.WhiteLabel; +using ASC.Web.Studio.Core.Notify; +using ASC.Web.Studio.Utility; + +using Microsoft.Extensions.DependencyInjection; + namespace ASC.Data.Backup -{ +{ [Singletone(Additional = typeof(NotifyHelperExtension))] public class NotifyHelper - { - private IServiceProvider ServiceProvider { get; } - + { + private IServiceProvider ServiceProvider { get; } + public NotifyHelper(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } + { + ServiceProvider = serviceProvider; + } public void SendAboutTransferStart(Tenant tenant, string targetRegion, bool notifyUsers) - { + { MigrationNotify(tenant, Actions.MigrationPortalStart, targetRegion, string.Empty, notifyUsers); } public void SendAboutTransferComplete(Tenant tenant, string targetRegion, string targetAddress, bool notifyOnlyOwner, int toTenantId) - { + { MigrationNotify(tenant, Actions.MigrationPortalSuccessV115, targetRegion, targetAddress, !notifyOnlyOwner, toTenantId); } public void SendAboutTransferError(Tenant tenant, string targetRegion, string resultAddress, bool notifyOnlyOwner) - { + { MigrationNotify(tenant, !string.IsNullOrEmpty(targetRegion) ? Actions.MigrationPortalError : Actions.MigrationPortalServerFailure, targetRegion, resultAddress, !notifyOnlyOwner); } public void SendAboutBackupCompleted(Guid userId) - { - using var scope = ServiceProvider.CreateScope(); - var scopeClass = scope.ServiceProvider.GetService(); - var (userManager, studioNotifyHelper, studioNotifySource, displayUserSettingsHelper, _) = scopeClass; - var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope); - - client.SendNoticeToAsync( - Actions.BackupCreated, - new[] { studioNotifyHelper.ToRecipient(userId) }, - new[] { StudioNotifyService.EMailSenderName }, + { + using var scope = ServiceProvider.CreateScope(); + var scopeClass = scope.ServiceProvider.GetService(); + var (userManager, studioNotifyHelper, studioNotifySource, displayUserSettingsHelper, _) = scopeClass; + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope); + + client.SendNoticeToAsync( + Actions.BackupCreated, + new[] { studioNotifyHelper.ToRecipient(userId) }, + new[] { StudioNotifyService.EMailSenderName }, new TagValue(Tags.OwnerName, userManager.GetUsers(userId).DisplayUserName(displayUserSettingsHelper))); } public void SendAboutRestoreStarted(Tenant tenant, bool notifyAllUsers) - { - using var scope = ServiceProvider.CreateScope(); - var scopeClass = scope.ServiceProvider.GetService(); - var (userManager, studioNotifyHelper, studioNotifySource, displayUserSettingsHelper, _) = scopeClass; - var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope); - - var owner = userManager.GetUsers(tenant.OwnerId); - var users = - notifyAllUsers - ? studioNotifyHelper.RecipientFromEmail(userManager.GetUsers(EmployeeStatus.Active).Where(r => r.ActivationStatus == EmployeeActivationStatus.Activated).Select(u => u.Email).ToList(), false) - : owner.ActivationStatus == EmployeeActivationStatus.Activated ? studioNotifyHelper.RecipientFromEmail(owner.Email, false) : new IDirectRecipient[0]; - - client.SendNoticeToAsync( - Actions.RestoreStarted, - users, + { + using var scope = ServiceProvider.CreateScope(); + var scopeClass = scope.ServiceProvider.GetService(); + var (userManager, studioNotifyHelper, studioNotifySource, displayUserSettingsHelper, _) = scopeClass; + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope); + + var owner = userManager.GetUsers(tenant.OwnerId); + var users = + notifyAllUsers + ? studioNotifyHelper.RecipientFromEmail(userManager.GetUsers(EmployeeStatus.Active).Where(r => r.ActivationStatus == EmployeeActivationStatus.Activated).Select(u => u.Email).ToList(), false) + : owner.ActivationStatus == EmployeeActivationStatus.Activated ? studioNotifyHelper.RecipientFromEmail(owner.Email, false) : new IDirectRecipient[0]; + + client.SendNoticeToAsync( + Actions.RestoreStarted, + users, new[] { StudioNotifyService.EMailSenderName }); } public void SendAboutRestoreCompleted(Tenant tenant, bool notifyAllUsers) - { - using var scope = ServiceProvider.CreateScope(); - var scopeClass = scope.ServiceProvider.GetService(); - var tenantManager = scope.ServiceProvider.GetService(); - var commonLinkUtility = scope.ServiceProvider.GetService(); - var (userManager, studioNotifyHelper, studioNotifySource, displayUserSettingsHelper, authManager) = scopeClass; - var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope); - - var owner = userManager.GetUsers(tenant.OwnerId); - var users = notifyAllUsers - ? userManager.GetUsers(EmployeeStatus.Active) - : new[] { userManager.GetUsers(tenantManager.GetCurrentTenant().OwnerId) }; - - foreach (var user in users) - { - var hash = authManager.GetUserPasswordStamp(user.ID).ToString("s"); - var confirmationUrl = commonLinkUtility.GetConfirmationUrl(user.Email, ConfirmType.PasswordChange, hash); - - Func greenButtonText = () => BackupResource.ButtonSetPassword; - - client.SendNoticeToAsync( - Actions.RestoreCompletedV115, - new IRecipient[] { user }, - new[] { StudioNotifyService.EMailSenderName }, - null, - TagValues.GreenButton(greenButtonText, confirmationUrl)); - } - } - - private void MigrationNotify(Tenant tenant, INotifyAction action, string region, string url, bool notify, int? toTenantId = null) - { - using var scope = ServiceProvider.CreateScope(); - var scopeClass = scope.ServiceProvider.GetService(); - var (userManager, studioNotifyHelper, studioNotifySource, _, authManager) = scopeClass; - var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope); - var commonLinkUtility = scope.ServiceProvider.GetService(); - - var users = userManager.GetUsers() - .Where(u => notify ? u.ActivationStatus.HasFlag(EmployeeActivationStatus.Activated) : u.IsOwner(tenant)) - .ToArray(); - - if (users.Any()) - { - var args = CreateArgs(scope, region, url); - if (action == Actions.MigrationPortalSuccessV115) - { - foreach (var user in users) - { - var currentArgs = new List(args); - - var newTenantId = toTenantId.HasValue ? toTenantId.Value : tenant.TenantId; - var hash = authManager.GetUserPasswordStamp(user.ID).ToString("s"); - var confirmationUrl = url + "/" + commonLinkUtility.GetConfirmationUrlRelative(newTenantId, user.Email, ConfirmType.PasswordChange, hash); - - Func greenButtonText = () => BackupResource.ButtonSetPassword; - currentArgs.Add(TagValues.GreenButton(greenButtonText, confirmationUrl)); - - client.SendNoticeToAsync( - action, - null, - new IRecipient[] { user }, - new[] { StudioNotifyService.EMailSenderName }, - currentArgs.ToArray()); - } - } - else - { - client.SendNoticeToAsync( - action, - null, - users.Select(u => studioNotifyHelper.ToRecipient(u.ID)).ToArray(), - new[] { StudioNotifyService.EMailSenderName }, - args.ToArray()); - } - } - } - - private List CreateArgs(IServiceScope scope,string region, string url) - { - var args = new List() - { - new TagValue(Tags.RegionName, TransferResourceHelper.GetRegionDescription(region)), - new TagValue(Tags.PortalUrl, url) - }; - - if (!string.IsNullOrEmpty(url)) - { - args.Add(new TagValue(CommonTags.VirtualRootPath, url)); - args.Add(new TagValue(CommonTags.ProfileUrl, url + scope.ServiceProvider.GetService().GetMyStaff())); - args.Add(new TagValue(CommonTags.LetterLogo, scope.ServiceProvider.GetService().GetLogoDark(true))); - } - return args; + { + using var scope = ServiceProvider.CreateScope(); + var scopeClass = scope.ServiceProvider.GetService(); + var tenantManager = scope.ServiceProvider.GetService(); + var commonLinkUtility = scope.ServiceProvider.GetService(); + var (userManager, studioNotifyHelper, studioNotifySource, displayUserSettingsHelper, authManager) = scopeClass; + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope); + + var owner = userManager.GetUsers(tenant.OwnerId); + var users = notifyAllUsers + ? userManager.GetUsers(EmployeeStatus.Active) + : new[] { userManager.GetUsers(tenantManager.GetCurrentTenant().OwnerId) }; + + foreach (var user in users) + { + var hash = authManager.GetUserPasswordStamp(user.ID).ToString("s"); + var confirmationUrl = commonLinkUtility.GetConfirmationUrl(user.Email, ConfirmType.PasswordChange, hash); + + Func greenButtonText = () => BackupResource.ButtonSetPassword; + + client.SendNoticeToAsync( + Actions.RestoreCompletedV115, + new IRecipient[] { user }, + new[] { StudioNotifyService.EMailSenderName }, + null, + TagValues.GreenButton(greenButtonText, confirmationUrl)); + } + } + + private void MigrationNotify(Tenant tenant, INotifyAction action, string region, string url, bool notify, int? toTenantId = null) + { + using var scope = ServiceProvider.CreateScope(); + var scopeClass = scope.ServiceProvider.GetService(); + var (userManager, studioNotifyHelper, studioNotifySource, _, authManager) = scopeClass; + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope); + var commonLinkUtility = scope.ServiceProvider.GetService(); + + var users = userManager.GetUsers() + .Where(u => notify ? u.ActivationStatus.HasFlag(EmployeeActivationStatus.Activated) : u.IsOwner(tenant)) + .ToArray(); + + if (users.Any()) + { + var args = CreateArgs(scope, region, url); + if (action == Actions.MigrationPortalSuccessV115) + { + foreach (var user in users) + { + var currentArgs = new List(args); + + var newTenantId = toTenantId.HasValue ? toTenantId.Value : tenant.TenantId; + var hash = authManager.GetUserPasswordStamp(user.ID).ToString("s"); + var confirmationUrl = url + "/" + commonLinkUtility.GetConfirmationUrlRelative(newTenantId, user.Email, ConfirmType.PasswordChange, hash); + + Func greenButtonText = () => BackupResource.ButtonSetPassword; + currentArgs.Add(TagValues.GreenButton(greenButtonText, confirmationUrl)); + + client.SendNoticeToAsync( + action, + null, + new IRecipient[] { user }, + new[] { StudioNotifyService.EMailSenderName }, + currentArgs.ToArray()); + } + } + else + { + client.SendNoticeToAsync( + action, + null, + users.Select(u => studioNotifyHelper.ToRecipient(u.ID)).ToArray(), + new[] { StudioNotifyService.EMailSenderName }, + args.ToArray()); + } + } + } + + private List CreateArgs(IServiceScope scope,string region, string url) + { + var args = new List() + { + new TagValue(Tags.RegionName, TransferResourceHelper.GetRegionDescription(region)), + new TagValue(Tags.PortalUrl, url) + }; + + if (!string.IsNullOrEmpty(url)) + { + args.Add(new TagValue(CommonTags.VirtualRootPath, url)); + args.Add(new TagValue(CommonTags.ProfileUrl, url + scope.ServiceProvider.GetService().GetMyStaff())); + args.Add(new TagValue(CommonTags.LetterLogo, scope.ServiceProvider.GetService().GetLogoDark(true))); + } + return args; } } - + [Scope] - public class NotifyHelperScope - { - private AuthManager AuthManager { get; } - private UserManager UserManager { get; } - private StudioNotifyHelper StudioNotifyHelper { get; } - private StudioNotifySource StudioNotifySource { get; } - private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } - - public NotifyHelperScope( - UserManager userManager, - StudioNotifyHelper studioNotifyHelper, - StudioNotifySource studioNotifySource, - DisplayUserSettingsHelper displayUserSettingsHelper, - AuthManager authManager) - { - UserManager = userManager; - StudioNotifyHelper = studioNotifyHelper; - StudioNotifySource = studioNotifySource; - DisplayUserSettingsHelper = displayUserSettingsHelper; - AuthManager = authManager; - } - - public void Deconstruct( - out UserManager userManager, - out StudioNotifyHelper studioNotifyHelper, - out StudioNotifySource studioNotifySource, - out DisplayUserSettingsHelper displayUserSettingsHelper, - out AuthManager authManager - ) - { - userManager = UserManager; - studioNotifyHelper = StudioNotifyHelper; - studioNotifySource = StudioNotifySource; - displayUserSettingsHelper = DisplayUserSettingsHelper; - authManager = AuthManager; - } + public class NotifyHelperScope + { + private AuthManager AuthManager { get; } + private UserManager UserManager { get; } + private StudioNotifyHelper StudioNotifyHelper { get; } + private StudioNotifySource StudioNotifySource { get; } + private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } + + public NotifyHelperScope( + UserManager userManager, + StudioNotifyHelper studioNotifyHelper, + StudioNotifySource studioNotifySource, + DisplayUserSettingsHelper displayUserSettingsHelper, + AuthManager authManager) + { + UserManager = userManager; + StudioNotifyHelper = studioNotifyHelper; + StudioNotifySource = studioNotifySource; + DisplayUserSettingsHelper = displayUserSettingsHelper; + AuthManager = authManager; + } + + public void Deconstruct( + out UserManager userManager, + out StudioNotifyHelper studioNotifyHelper, + out StudioNotifySource studioNotifySource, + out DisplayUserSettingsHelper displayUserSettingsHelper, + out AuthManager authManager + ) + { + userManager = UserManager; + studioNotifyHelper = StudioNotifyHelper; + studioNotifySource = StudioNotifySource; + displayUserSettingsHelper = DisplayUserSettingsHelper; + authManager = AuthManager; + } } public class NotifyHelperExtension { public static void Register(DIHelper services) - { + { services.TryAdd(); } } diff --git a/common/services/ASC.Data.Backup/Core/Schedule.cs b/common/services/ASC.Data.Backup/Core/Core/Schedule.cs similarity index 99% rename from common/services/ASC.Data.Backup/Core/Schedule.cs rename to common/services/ASC.Data.Backup/Core/Core/Schedule.cs index 6d034f5b40..228be978c3 100644 --- a/common/services/ASC.Data.Backup/Core/Schedule.cs +++ b/common/services/ASC.Data.Backup/Core/Core/Schedule.cs @@ -11,7 +11,7 @@ using ASC.Notify.Cron; using Microsoft.Extensions.Options; namespace ASC.Data.Backup -{ +{ [Scope] public class Schedule { diff --git a/common/services/ASC.Data.Backup/Core/ZipOperator.cs b/common/services/ASC.Data.Backup/Core/Core/ZipOperator.cs similarity index 99% rename from common/services/ASC.Data.Backup/Core/ZipOperator.cs rename to common/services/ASC.Data.Backup/Core/Core/ZipOperator.cs index f578570b56..764080ab7c 100644 --- a/common/services/ASC.Data.Backup/Core/ZipOperator.cs +++ b/common/services/ASC.Data.Backup/Core/Core/ZipOperator.cs @@ -26,29 +26,29 @@ using System.Collections.Generic; using System.IO; -using System.Text; - -using ASC.Common; - -using ICSharpCode.SharpZipLib.GZip; -using ICSharpCode.SharpZipLib.Tar; +using System.Text; + +using ASC.Common; + +using ICSharpCode.SharpZipLib.GZip; +using ICSharpCode.SharpZipLib.Tar; namespace ASC.Data.Backup -{ +{ public class ZipWriteOperator : IDataWriteOperator { private readonly GZipOutputStream gZipOutputStream; private readonly TarOutputStream tarOutputStream; - private readonly Stream file; - + private readonly Stream file; + private TempStream TempStream { get; } public ZipWriteOperator(TempStream tempStream, string targetFile) { file = new FileStream(targetFile, FileMode.Create); gZipOutputStream = new GZipOutputStream(file); - tarOutputStream = new TarOutputStream(gZipOutputStream, Encoding.UTF8); - TempStream = tempStream; + tarOutputStream = new TarOutputStream(gZipOutputStream, Encoding.UTF8); + TempStream = tempStream; } public void WriteEntry(string key, Stream stream) diff --git a/common/services/ASC.Data.Backup/EF/BackupRecord.cs b/common/services/ASC.Data.Backup/Core/EF/BackupRecord.cs similarity index 99% rename from common/services/ASC.Data.Backup/EF/BackupRecord.cs rename to common/services/ASC.Data.Backup/Core/EF/BackupRecord.cs index e10ada610d..062e447a04 100644 --- a/common/services/ASC.Data.Backup/EF/BackupRecord.cs +++ b/common/services/ASC.Data.Backup/Core/EF/BackupRecord.cs @@ -17,8 +17,8 @@ namespace ASC.Data.Backup.EF.Model [Column("is_scheduled")] public bool IsScheduled { get; set; } - public string Name { get; set; } - + public string Name { get; set; } + public string Hash { get; set; } [Column("storage_type")] diff --git a/common/services/ASC.Data.Backup/EF/BackupSchedule.cs b/common/services/ASC.Data.Backup/Core/EF/BackupSchedule.cs similarity index 100% rename from common/services/ASC.Data.Backup/EF/BackupSchedule.cs rename to common/services/ASC.Data.Backup/Core/EF/BackupSchedule.cs diff --git a/common/services/ASC.Data.Backup/EF/BackupsContext.cs b/common/services/ASC.Data.Backup/Core/EF/BackupsContext.cs similarity index 99% rename from common/services/ASC.Data.Backup/EF/BackupsContext.cs rename to common/services/ASC.Data.Backup/Core/EF/BackupsContext.cs index d674c0e7d5..9723eed968 100644 --- a/common/services/ASC.Data.Backup/EF/BackupsContext.cs +++ b/common/services/ASC.Data.Backup/Core/EF/BackupsContext.cs @@ -19,13 +19,13 @@ namespace ASC.Data.Backup.EF.Context public BackupsContext(DbContextOptions options) : base(options) { - } - + } + protected override void OnModelCreating(ModelBuilder modelBuilder) { ModelBuilderWrapper .From(modelBuilder, Provider) - .AddDbTenant() + .AddDbTenant() .AddDbTariff(); } } diff --git a/common/services/ASC.Data.Backup/Exceptions/DbBackupException.cs b/common/services/ASC.Data.Backup/Core/Exceptions/DbBackupException.cs similarity index 100% rename from common/services/ASC.Data.Backup/Exceptions/DbBackupException.cs rename to common/services/ASC.Data.Backup/Core/Exceptions/DbBackupException.cs diff --git a/common/services/ASC.Data.Backup/Exceptions/ThrowHelper.cs b/common/services/ASC.Data.Backup/Core/Exceptions/ThrowHelper.cs similarity index 100% rename from common/services/ASC.Data.Backup/Exceptions/ThrowHelper.cs rename to common/services/ASC.Data.Backup/Core/Exceptions/ThrowHelper.cs diff --git a/common/services/ASC.Data.Backup/Extensions/DataExtensions.cs b/common/services/ASC.Data.Backup/Core/Extensions/DataExtensions.cs similarity index 100% rename from common/services/ASC.Data.Backup/Extensions/DataExtensions.cs rename to common/services/ASC.Data.Backup/Core/Extensions/DataExtensions.cs diff --git a/common/services/ASC.Data.Backup/Extensions/EnumerableExtensions.cs b/common/services/ASC.Data.Backup/Core/Extensions/EnumerableExtensions.cs similarity index 100% rename from common/services/ASC.Data.Backup/Extensions/EnumerableExtensions.cs rename to common/services/ASC.Data.Backup/Core/Extensions/EnumerableExtensions.cs diff --git a/common/services/ASC.Data.Backup/Extensions/XmlExtensions.cs b/common/services/ASC.Data.Backup/Core/Extensions/XmlExtensions.cs similarity index 100% rename from common/services/ASC.Data.Backup/Extensions/XmlExtensions.cs rename to common/services/ASC.Data.Backup/Core/Extensions/XmlExtensions.cs diff --git a/common/services/ASC.Data.Backup/Listerners/BackupListener.cs b/common/services/ASC.Data.Backup/Core/Listerners/BackupListener.cs similarity index 99% rename from common/services/ASC.Data.Backup/Listerners/BackupListener.cs rename to common/services/ASC.Data.Backup/Core/Listerners/BackupListener.cs index 2c174c584b..6828fd591c 100644 --- a/common/services/ASC.Data.Backup/Listerners/BackupListener.cs +++ b/common/services/ASC.Data.Backup/Core/Listerners/BackupListener.cs @@ -9,7 +9,7 @@ using ASC.Data.Backup.Service; using Microsoft.Extensions.DependencyInjection; namespace ASC.Data.Backup.Listerners -{ +{ [Singletone] public class BackupListener { diff --git a/common/services/ASC.Data.Backup/Service/BackupService.cs b/common/services/ASC.Data.Backup/Core/Service/BackupService.cs similarity index 99% rename from common/services/ASC.Data.Backup/Service/BackupService.cs rename to common/services/ASC.Data.Backup/Core/Service/BackupService.cs index 0ba6c0cd9c..6e2a4f43d7 100644 --- a/common/services/ASC.Data.Backup/Service/BackupService.cs +++ b/common/services/ASC.Data.Backup/Core/Service/BackupService.cs @@ -28,20 +28,20 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.ServiceModel; - +using System.ServiceModel; + using ASC.Common; using ASC.Common.Logging; using ASC.Common.Utils; using ASC.Data.Backup.Contracts; using ASC.Data.Backup.EF.Model; using ASC.Data.Backup.Storage; -using ASC.Data.Backup.Utils; - -using Microsoft.Extensions.Options; - -using Newtonsoft.Json; - +using ASC.Data.Backup.Utils; + +using Microsoft.Extensions.Options; + +using Newtonsoft.Json; + namespace ASC.Data.Backup.Service { [Scope] @@ -190,34 +190,34 @@ namespace ASC.Data.Backup.Service } public List GetTransferRegions() - { - var settings = Configuration.GetSetting("backup"); - return settings.WebConfigs.Elements.Select(configElement => - { - var config = Utils.ConfigurationProvider.Open(PathHelper.ToRootedConfigPath(configElement.Path)); - var baseDomain = config.AppSettings.Settings["core:base-domain"].Value; - return new TransferRegion - { - Name = configElement.Region, - BaseDomain = baseDomain, - IsCurrentRegion = configElement.Region.Equals(settings.WebConfigs.CurrentRegion, StringComparison.InvariantCultureIgnoreCase) - }; - }) - .ToList(); + { + var settings = Configuration.GetSetting("backup"); + return settings.WebConfigs.Elements.Select(configElement => + { + var config = Utils.ConfigurationProvider.Open(PathHelper.ToRootedConfigPath(configElement.Path)); + var baseDomain = config.AppSettings.Settings["core:base-domain"].Value; + return new TransferRegion + { + Name = configElement.Region, + BaseDomain = baseDomain, + IsCurrentRegion = configElement.Region.Equals(settings.WebConfigs.CurrentRegion, StringComparison.InvariantCultureIgnoreCase) + }; + }) + .ToList(); } public void CreateSchedule(CreateScheduleRequest request) { BackupRepository.SaveBackupSchedule( - new BackupSchedule() - { - TenantId = request.TenantId, - Cron = request.Cron, - BackupMail = request.BackupMail, - BackupsStored = request.NumberOfBackupsStored, - StorageType = request.StorageType, - StorageBasePath = request.StorageBasePath, - StorageParams = JsonConvert.SerializeObject(request.StorageParams) + new BackupSchedule() + { + TenantId = request.TenantId, + Cron = request.Cron, + BackupMail = request.BackupMail, + BackupsStored = request.NumberOfBackupsStored, + StorageType = request.StorageType, + StorageBasePath = request.StorageBasePath, + StorageParams = JsonConvert.SerializeObject(request.StorageParams) }); } @@ -229,23 +229,23 @@ namespace ASC.Data.Backup.Service public ScheduleResponse GetSchedule(int tenantId) { var schedule = BackupRepository.GetBackupSchedule(tenantId); - if (schedule != null) - { - var tmp = new ScheduleResponse - { - StorageType = schedule.StorageType, - StorageBasePath = schedule.StorageBasePath, - BackupMail = schedule.BackupMail, - NumberOfBackupsStored = schedule.BackupsStored, - Cron = schedule.Cron, - LastBackupTime = schedule.LastBackupTime, - StorageParams = JsonConvert.DeserializeObject>(schedule.StorageParams) - }; - return tmp; - } - else - { - return null; + if (schedule != null) + { + var tmp = new ScheduleResponse + { + StorageType = schedule.StorageType, + StorageBasePath = schedule.StorageBasePath, + BackupMail = schedule.BackupMail, + NumberOfBackupsStored = schedule.BackupsStored, + Cron = schedule.Cron, + LastBackupTime = schedule.LastBackupTime, + StorageParams = JsonConvert.DeserializeObject>(schedule.StorageParams) + }; + return tmp; + } + else + { + return null; } } } diff --git a/common/services/ASC.Data.Backup/Service/BackupSettings.cs b/common/services/ASC.Data.Backup/Core/Service/BackupSettings.cs similarity index 100% rename from common/services/ASC.Data.Backup/Service/BackupSettings.cs rename to common/services/ASC.Data.Backup/Core/Service/BackupSettings.cs diff --git a/common/services/ASC.Data.Backup/Service/BackupWorker.cs b/common/services/ASC.Data.Backup/Core/Service/BackupWorker.cs similarity index 97% rename from common/services/ASC.Data.Backup/Service/BackupWorker.cs rename to common/services/ASC.Data.Backup/Core/Service/BackupWorker.cs index 290f5494f0..634a54d7d3 100644 --- a/common/services/ASC.Data.Backup/Service/BackupWorker.cs +++ b/common/services/ASC.Data.Backup/Core/Service/BackupWorker.cs @@ -1,901 +1,902 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2020 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Security.Cryptography; -using System.Threading; - -using ASC.Common; -using ASC.Common.Caching; -using ASC.Common.Logging; -using ASC.Common.Threading; -using ASC.Common.Utils; -using ASC.Core; -using ASC.Core.Tenants; -using ASC.Data.Backup.Contracts; -using ASC.Data.Backup.EF.Model; -using ASC.Data.Backup.Storage; -using ASC.Data.Backup.Tasks; -using ASC.Data.Backup.Tasks.Modules; -using ASC.Data.Backup.Utils; - -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; - -using Newtonsoft.Json; - -namespace ASC.Data.Backup.Service -{ - [Singletone(Additional = typeof(BackupWorkerExtension))] - public class BackupWorker - { - private ILog Log { get; set; } - private DistributedTaskQueue ProgressQueue { get; set; } - internal string TempFolder { get; set; } - private string CurrentRegion { get; set; } - private Dictionary ConfigPaths { get; set; } - private int Limit { get; set; } - private string UpgradesPath { get; set; } - private ICacheNotify CacheBackupProgress { get; } - private FactoryProgressItem FactoryProgressItem { get; set; } - private TempPath TempPath { get; } - - private readonly object SynchRoot = new object(); - - public BackupWorker( - IOptionsMonitor options, - ICacheNotify cacheBackupProgress, - DistributedTaskQueueOptionsManager progressQueue, - FactoryProgressItem factoryProgressItem, - TempPath tempPath) - { - Log = options.CurrentValue; - ProgressQueue = progressQueue.Get(); - CacheBackupProgress = cacheBackupProgress; - FactoryProgressItem = factoryProgressItem; - TempPath = tempPath; - } - - public void Start(BackupSettings settings) - { - TempFolder = TempPath.GetTempPath(); - if (!Directory.Exists(TempFolder)) - { - Directory.CreateDirectory(TempFolder); - } - - Limit = settings.Limit; - UpgradesPath = settings.UpgradesPath; - CurrentRegion = settings.WebConfigs.CurrentRegion; - ConfigPaths = settings.WebConfigs.Elements.ToDictionary(el => el.Region, el => PathHelper.ToRootedConfigPath(el.Path)); - ConfigPaths[CurrentRegion] = PathHelper.ToRootedConfigPath(settings.WebConfigs.CurrentPath); - - var invalidConfigPath = ConfigPaths.Values.FirstOrDefault(path => !File.Exists(path)); - if (invalidConfigPath != null) - { - Log.WarnFormat("Configuration file {0} not found", invalidConfigPath); - } - } - - public void Stop() - { - if (ProgressQueue != null) - { - var tasks = ProgressQueue.GetTasks(); - foreach (var t in tasks) - { - ProgressQueue.CancelTask(t.Id); - } - - ProgressQueue = null; - } - } - - public BackupProgress StartBackup(StartBackupRequest request) - { - lock (SynchRoot) - { - var item = ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == request.TenantId); - if (item != null && item.IsCompleted) - { - ProgressQueue.RemoveTask(item.Id); - item = null; - } - if (item == null) - { - item = FactoryProgressItem.CreateBackupProgressItem(request, false, TempFolder, Limit, CurrentRegion, ConfigPaths); - ProgressQueue.QueueTask(item); - } - - item.PublishChanges(); - - return ToBackupProgress(item); - } - } - - public void StartScheduledBackup(BackupSchedule schedule) - { - lock (SynchRoot) - { - var item = ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == schedule.TenantId); - if (item != null && item.IsCompleted) - { - ProgressQueue.RemoveTask(item.Id); - item = null; - } - if (item == null) - { - item = FactoryProgressItem.CreateBackupProgressItem(schedule, false, TempFolder, Limit, CurrentRegion, ConfigPaths); - ProgressQueue.QueueTask(item); - } - } - } - - public BackupProgress GetBackupProgress(int tenantId) - { - lock (SynchRoot) - { - return ToBackupProgress(ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == tenantId)); - } - } - - public BackupProgress GetTransferProgress(int tenantId) - { - lock (SynchRoot) - { - return ToBackupProgress(ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == tenantId)); - } - } - - public BackupProgress GetRestoreProgress(int tenantId) - { - lock (SynchRoot) - { - return ToBackupProgress(ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == tenantId)); - } - } - - public void ResetBackupError(int tenantId) - { - lock (SynchRoot) - { - var progress = ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == tenantId); - if (progress != null) - { - progress.Exception = null; - } - } - } - - public void ResetRestoreError(int tenantId) - { - lock (SynchRoot) - { - var progress = ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == tenantId); - if (progress != null) - { - progress.Exception = null; - } - } - } - - public BackupProgress StartRestore(StartRestoreRequest request) - { - lock (SynchRoot) - { - var item = ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == request.TenantId); - if (item != null && item.IsCompleted) - { - ProgressQueue.RemoveTask(item.Id); - item = null; - } - if (item == null) - { - item = FactoryProgressItem.CreateRestoreProgressItem(request, TempFolder, UpgradesPath, CurrentRegion, ConfigPaths); - ProgressQueue.QueueTask(item); - } - return ToBackupProgress(item); - } - } - - public BackupProgress StartTransfer(int tenantId, string targetRegion, bool transferMail, bool notify) - { - lock (SynchRoot) - { - var item = ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == tenantId); - if (item != null && item.IsCompleted) - { - ProgressQueue.RemoveTask(item.Id); - item = null; - } - - if (item == null) - { - item = FactoryProgressItem.CreateTransferProgressItem(targetRegion, transferMail, tenantId, TempFolder, Limit, notify, CurrentRegion, ConfigPaths); - ProgressQueue.QueueTask(item); - } - - return ToBackupProgress(item); - } - } - - - private BackupProgress ToBackupProgress(BaseBackupProgressItem progressItem) - { - if (progressItem == null) - { - return null; - } - var progress = new BackupProgress - { - IsCompleted = progressItem.IsCompleted, - Progress = (int)progressItem.Percentage, - Error = progressItem.Exception != null ? progressItem.Exception.Message : "", - TenantId = progressItem.TenantId, - BackupProgressEnum = progressItem.BackupProgressItemEnum.Convert() - }; - - if (progressItem is BackupProgressItem backupProgressItem && backupProgressItem.Link != null) - { - progress.Link = backupProgressItem.Link; - } - else - { - if (progressItem is TransferProgressItem transferProgressItem && transferProgressItem.Link != null) - { - progress.Link = transferProgressItem.Link; - } - } - - return progress; - } - - internal static string GetBackupHash(string path) - { - using (var sha256 = SHA256.Create()) - using (var fileStream = File.OpenRead(path)) - { - fileStream.Position = 0; - var hash = sha256.ComputeHash(fileStream); - return BitConverter.ToString(hash).Replace("-", string.Empty); - } - } - } - - public enum BackupProgressItemEnum - { - Backup, - Restore, - Transfer - } - - public static class BackupProgressItemEnumConverter - { - public static BackupProgressEnum Convert(this BackupProgressItemEnum backupProgressItemEnum) - { - return backupProgressItemEnum switch - { - BackupProgressItemEnum.Backup => BackupProgressEnum.Backup, - BackupProgressItemEnum.Restore => BackupProgressEnum.Restore, - BackupProgressItemEnum.Transfer => BackupProgressEnum.Transfer, - _ => BackupProgressEnum.Backup - }; - } - } - - public abstract class BaseBackupProgressItem : DistributedTaskProgress - { - private int? tenantId; - public int TenantId - { - get - { - return tenantId ?? GetProperty(nameof(tenantId)); - } - set - { - tenantId = value; - SetProperty(nameof(tenantId), value); - } - } - - public abstract BackupProgressItemEnum BackupProgressItemEnum { get; } - - public abstract object Clone(); - - protected ILog Log { get; set; } - - protected IServiceProvider ServiceProvider { get; set; } - - public BaseBackupProgressItem(IOptionsMonitor options, IServiceProvider serviceProvider) - { - Log = options.CurrentValue; - ServiceProvider = serviceProvider; - } - } - - [Transient] - public class BackupProgressItem : BaseBackupProgressItem - { - private const string ArchiveFormat = "tar.gz"; - - public BackupProgressItem(IOptionsMonitor options, IServiceProvider serviceProvider) : base(options, serviceProvider) - { - } - - public override BackupProgressItemEnum BackupProgressItemEnum { get => BackupProgressItemEnum.Backup; } - - private bool IsScheduled { get; set; } - private Guid UserId { get; set; } - private BackupStorageType StorageType { get; set; } - private string StorageBasePath { get; set; } - public bool BackupMail { get; set; } - public Dictionary StorageParams { get; set; } - public string Link { get; private set; } - public string TempFolder { get; set; } - private string CurrentRegion { get; set; } - private Dictionary ConfigPaths { get; set; } - private int Limit { get; set; } - - public void Init(BackupSchedule schedule, bool isScheduled, string tempFolder, int limit, string currentRegion, Dictionary configPaths) - { - UserId = Guid.Empty; - TenantId = schedule.TenantId; - StorageType = schedule.StorageType; - StorageBasePath = schedule.StorageBasePath; - BackupMail = schedule.BackupMail; - StorageParams = JsonConvert.DeserializeObject>(schedule.StorageParams); - IsScheduled = isScheduled; - TempFolder = tempFolder; - Limit = limit; - CurrentRegion = currentRegion; - ConfigPaths = configPaths; - } - - public void Init(StartBackupRequest request, bool isScheduled, string tempFolder, int limit, string currentRegion, Dictionary configPaths) - { - UserId = request.UserId; - TenantId = request.TenantId; - StorageType = request.StorageType; - StorageBasePath = request.StorageBasePath; - BackupMail = request.BackupMail; - StorageParams = request.StorageParams.ToDictionary(r => r.Key, r => r.Value); - IsScheduled = isScheduled; - TempFolder = tempFolder; - Limit = limit; - CurrentRegion = currentRegion; - ConfigPaths = configPaths; - } - - protected override void DoJob() - { - if (ThreadPriority.BelowNormal < Thread.CurrentThread.Priority) - { - Thread.CurrentThread.Priority = ThreadPriority.BelowNormal; - } - - using var scope = ServiceProvider.CreateScope(); - var scopeClass = scope.ServiceProvider.GetService(); - var (tenantManager, backupStorageFactory, notifyHelper, backupRepository, backupWorker, backupPortalTask, _, _, coreBaseSettings) = scopeClass; - - var tenant = tenantManager.GetTenant(TenantId); - var dateTime = coreBaseSettings.Standalone ? DateTime.Now : DateTime.UtcNow; - var backupName = string.Format("{0}_{1:yyyy-MM-dd_HH-mm-ss}.{2}", tenantManager.GetTenant(TenantId).TenantAlias, dateTime, ArchiveFormat); - - var tempFile = CrossPlatform.PathCombine(TempFolder, backupName); - var storagePath = tempFile; - try - { - var backupTask = backupPortalTask; - - backupTask.Init(TenantId, ConfigPaths[CurrentRegion], tempFile, Limit); - if (!BackupMail) - { - backupTask.IgnoreModule(ModuleName.Mail); - } - - backupTask.ProgressChanged += (sender, args) => - { - Percentage = 0.9 * args.Progress; - PublishChanges(); - }; - - backupTask.RunJob(); - - var backupStorage = backupStorageFactory.GetBackupStorage(StorageType, TenantId, StorageParams); - if (backupStorage != null) - { - storagePath = backupStorage.Upload(StorageBasePath, tempFile, UserId); - Link = backupStorage.GetPublicLink(storagePath); - } - - var repo = backupRepository; - repo.SaveBackupRecord( - new BackupRecord - { - Id = Guid.Parse(Id), - TenantId = TenantId, - IsScheduled = IsScheduled, - Name = Path.GetFileName(tempFile), - StorageType = StorageType, - StorageBasePath = StorageBasePath, - StoragePath = storagePath, - CreatedOn = DateTime.UtcNow, - ExpiresOn = StorageType == BackupStorageType.DataStore ? DateTime.UtcNow.AddDays(1) : DateTime.MinValue, - StorageParams = JsonConvert.SerializeObject(StorageParams), - Hash = BackupWorker.GetBackupHash(tempFile) - }); - - Percentage = 100; - - if (UserId != Guid.Empty && !IsScheduled) - { - notifyHelper.SendAboutBackupCompleted(UserId); - } - - IsCompleted = true; - PublishChanges(); - } - catch (Exception error) - { - Log.ErrorFormat("RunJob - Params: {0}, Error = {1}", new { Id, Tenant = TenantId, File = tempFile, BasePath = StorageBasePath, }, error); - Exception = error; - IsCompleted = true; - } - finally - { - try - { - PublishChanges(); - } - catch (Exception error) - { - Log.Error("publish", error); - } - - try - { - if (!(storagePath == tempFile && StorageType == BackupStorageType.Local)) - { - File.Delete(tempFile); - } - } - catch (Exception error) - { - Log.Error("can't delete file: {0}", error); - } - } - } - - public override object Clone() - { - return MemberwiseClone(); - } - } - - [Transient] - public class RestoreProgressItem : BaseBackupProgressItem - { - public RestoreProgressItem(IOptionsMonitor options, IServiceProvider serviceProvider) : base(options, serviceProvider) - { - } - - public override BackupProgressItemEnum BackupProgressItemEnum { get => BackupProgressItemEnum.Restore; } - public BackupStorageType StorageType { get; set; } - public string StoragePath { get; set; } - public bool Notify { get; set; } - public Dictionary StorageParams { get; set; } - public string TempFolder { get; set; } - private string CurrentRegion { get; set; } - private string UpgradesPath { get; set; } - private Dictionary ConfigPaths { get; set; } - - public void Init(StartRestoreRequest request, string tempFolder, string upgradesPath, string currentRegion, Dictionary configPaths) - { - TenantId = request.TenantId; - Notify = request.NotifyAfterCompletion; - StoragePath = request.FilePathOrId; - StorageType = request.StorageType; - TempFolder = tempFolder; - UpgradesPath = upgradesPath; - CurrentRegion = currentRegion; - ConfigPaths = configPaths; - } - - protected override void DoJob() - { - using var scope = ServiceProvider.CreateScope(); - var scopeClass = scope.ServiceProvider.GetService(); - var (tenantManager, backupStorageFactory, notifyHelper, backupRepository, backupWorker, _, restorePortalTask, _, coreBaseSettings) = scopeClass; - Tenant tenant = null; - var tempFile = PathHelper.GetTempFileName(TempFolder); - try - { - tenant = tenantManager.GetTenant(TenantId); - tenantManager.SetCurrentTenant(tenant); - notifyHelper.SendAboutRestoreStarted(tenant, Notify); - var storage = backupStorageFactory.GetBackupStorage(StorageType, TenantId, StorageParams); - storage.Download(StoragePath, tempFile); - - if (!coreBaseSettings.Standalone) - { - var backupHash = BackupWorker.GetBackupHash(tempFile); - var record = backupRepository.GetBackupRecord(backupHash, TenantId); - if (record == null) - { - throw new Exception(BackupResource.BackupNotFound); - } - } - - Percentage = 10; - - tenant.SetStatus(TenantStatus.Restoring); - tenantManager.SaveTenant(tenant); - - var columnMapper = new ColumnMapper(); - columnMapper.SetMapping("tenants_tenants", "alias", tenant.TenantAlias, (Guid.Parse(Id)).ToString("N")); - columnMapper.Commit(); - - var restoreTask = restorePortalTask; - restoreTask.Init(ConfigPaths[CurrentRegion], tempFile, TenantId, columnMapper, UpgradesPath); - restoreTask.ProgressChanged += (sender, args) => - { - Percentage = Percentage = (10d + 0.65 * args.Progress); - PublishChanges(); - }; - restoreTask.RunJob(); - - Tenant restoredTenant = null; - - if (restoreTask.Dump) - { - AscCacheNotify.OnClearCache(); - - if (Notify) - { - var tenants = tenantManager.GetTenants(); - foreach (var t in tenants) - { - notifyHelper.SendAboutRestoreCompleted(t, Notify); - } - } - } - else - { - tenantManager.RemoveTenant(tenant.TenantId); - - restoredTenant = tenantManager.GetTenant(columnMapper.GetTenantMapping()); - restoredTenant.SetStatus(TenantStatus.Active); - restoredTenant.TenantAlias = tenant.TenantAlias; - restoredTenant.PaymentId = string.Empty; - if (string.IsNullOrEmpty(restoredTenant.MappedDomain) && !string.IsNullOrEmpty(tenant.MappedDomain)) - { - restoredTenant.MappedDomain = tenant.MappedDomain; - } - tenantManager.SaveTenant(restoredTenant); - tenantManager.SetCurrentTenant(restoredTenant); - // sleep until tenants cache expires - Thread.Sleep(TimeSpan.FromMinutes(2)); - - notifyHelper.SendAboutRestoreCompleted(restoredTenant, Notify); - } - - Percentage = 75; - - PublishChanges(); - - File.Delete(tempFile); - - Percentage = 100; - PublishChanges(); - } - catch (Exception error) - { - Log.Error(error); - Exception = error; - - if (tenant != null) - { - tenant.SetStatus(TenantStatus.Active); - tenantManager.SaveTenant(tenant); - } - } - finally - { - try - { - PublishChanges(); - } - catch (Exception error) - { - Log.Error("publish", error); - } - - if (File.Exists(tempFile)) - { - File.Delete(tempFile); - } - } - } - - public override object Clone() - { - return MemberwiseClone(); - } - - - } - - [Transient] - public class TransferProgressItem : BaseBackupProgressItem - { - public TransferProgressItem(IOptionsMonitor options, IServiceProvider serviceProvider) : base(options, serviceProvider) - { - } - - public override BackupProgressItemEnum BackupProgressItemEnum { get => BackupProgressItemEnum.Transfer; } - public string TargetRegion { get; set; } - public bool TransferMail { get; set; } - public bool Notify { get; set; } - - public string Link { get; set; } - public string TempFolder { get; set; } - public Dictionary ConfigPaths { get; set; } - public string CurrentRegion { get; set; } - public int Limit { get; set; } - - public void Init( - string targetRegion, - bool transferMail, - int tenantId, - string tempFolder, - int limit, - bool notify, - string currentRegion, - Dictionary configPaths) - { - TenantId = tenantId; - TargetRegion = targetRegion; - TransferMail = transferMail; - Notify = notify; - TempFolder = tempFolder; - ConfigPaths = configPaths; - CurrentRegion = currentRegion; - Limit = limit; - - } - - protected override void DoJob() - { - using var scope = ServiceProvider.CreateScope(); - var scopeClass = scope.ServiceProvider.GetService(); - var (tenantManager, _, notifyHelper, _, backupWorker, _, _, transferPortalTask, _) = scopeClass; - var tempFile = PathHelper.GetTempFileName(TempFolder); - var tenant = tenantManager.GetTenant(TenantId); - var alias = tenant.TenantAlias; - - try - { - notifyHelper.SendAboutTransferStart(tenant, TargetRegion, Notify); - var transferProgressItem = transferPortalTask; - transferProgressItem.Init(TenantId, ConfigPaths[CurrentRegion], ConfigPaths[TargetRegion], Limit, TempFolder); - transferProgressItem.ProgressChanged += (sender, args) => - { - Percentage = args.Progress; - PublishChanges(); - }; - if (!TransferMail) - { - transferProgressItem.IgnoreModule(ModuleName.Mail); - } - transferProgressItem.RunJob(); - - Link = GetLink(alias, false); - notifyHelper.SendAboutTransferComplete(tenant, TargetRegion, Link, !Notify, transferProgressItem.ToTenantId); - PublishChanges(); - } - catch (Exception error) - { - Log.Error(error); - Exception = error; - - Link = GetLink(alias, true); - notifyHelper.SendAboutTransferError(tenant, TargetRegion, Link, !Notify); - } - finally - { - try - { - PublishChanges(); - } - catch (Exception error) - { - Log.Error("publish", error); - } - - if (File.Exists(tempFile)) - { - File.Delete(tempFile); - } - } - } - - private string GetLink(string alias, bool isErrorLink) - { - return "https://" + alias + "." + ConfigurationProvider.Open(ConfigPaths[isErrorLink ? CurrentRegion : TargetRegion]).AppSettings.Settings["core:base-domain"].Value; - } - - public override object Clone() - { - return MemberwiseClone(); - } - } - - [Singletone(Additional = typeof(FactoryProgressItemExtension))] - public class FactoryProgressItem - { - public IServiceProvider ServiceProvider { get; } - - public FactoryProgressItem(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } - - public BackupProgressItem CreateBackupProgressItem( - StartBackupRequest request, - bool isScheduled, - string tempFolder, - int limit, - string currentRegion, - Dictionary configPaths) - { - var item = ServiceProvider.GetService(); - item.Init(request, isScheduled, tempFolder, limit, currentRegion, configPaths); - return item; - } - - public BackupProgressItem CreateBackupProgressItem( - BackupSchedule schedule, - bool isScheduled, - string tempFolder, - int limit, - string currentRegion, - Dictionary configPaths - ) - { - var item = ServiceProvider.GetService(); - item.Init(schedule, isScheduled, tempFolder, limit, currentRegion, configPaths); - return item; - } - - public RestoreProgressItem CreateRestoreProgressItem( - StartRestoreRequest request, - string tempFolder, - string upgradesPath, - string currentRegion, - Dictionary configPaths - ) - { - var item = ServiceProvider.GetService(); - item.Init(request, tempFolder, upgradesPath, currentRegion, configPaths); - return item; - } - - public TransferProgressItem CreateTransferProgressItem( - string targetRegion, - bool transferMail, - int tenantId, - string tempFolder, - int limit, - bool notify, - string currentRegion, - Dictionary configPaths - ) - { - var item = ServiceProvider.GetService(); - item.Init(targetRegion, transferMail, tenantId, tempFolder, limit, notify, currentRegion, configPaths); - return item; - } - } - - [Scope] - internal class BackupWorkerScope - { - private TenantManager TenantManager { get; } - private BackupStorageFactory BackupStorageFactory { get; } - private NotifyHelper NotifyHelper { get; } - private BackupRepository BackupRepository { get; } - private BackupWorker BackupWorker { get; } - private BackupPortalTask BackupPortalTask { get; } - private RestorePortalTask RestorePortalTask { get; } - private TransferPortalTask TransferPortalTask { get; } - private CoreBaseSettings CoreBaseSettings { get; } - - public BackupWorkerScope(TenantManager tenantManager, - BackupStorageFactory backupStorageFactory, - NotifyHelper notifyHelper, - BackupRepository backupRepository, - BackupWorker backupWorker, - BackupPortalTask backupPortalTask, - RestorePortalTask restorePortalTask, - TransferPortalTask transferPortalTask, - CoreBaseSettings coreBaseSettings) - { - TenantManager = tenantManager; - BackupStorageFactory = backupStorageFactory; - NotifyHelper = notifyHelper; - BackupRepository = backupRepository; - BackupWorker = backupWorker; - BackupPortalTask = backupPortalTask; - RestorePortalTask = restorePortalTask; - TransferPortalTask = transferPortalTask; - CoreBaseSettings = coreBaseSettings; - } - - public void Deconstruct(out TenantManager tenantManager, - out BackupStorageFactory backupStorageFactory, - out NotifyHelper notifyHelper, - out BackupRepository backupRepository, - out BackupWorker backupWorker, - out BackupPortalTask backupPortalTask, - out RestorePortalTask restorePortalTask, - out TransferPortalTask transferPortalTask, - out CoreBaseSettings coreBaseSettings) - { - tenantManager = TenantManager; - backupStorageFactory = BackupStorageFactory; - notifyHelper = NotifyHelper; - backupRepository = BackupRepository; - backupWorker = BackupWorker; - backupPortalTask = BackupPortalTask; - restorePortalTask = RestorePortalTask; - transferPortalTask = TransferPortalTask; - coreBaseSettings = CoreBaseSettings; - } - } - - public class BackupWorkerExtension - { - public static void Register(DIHelper services) - { - services.TryAdd(); - services.AddDistributedTaskQueueService(5); - } - } - - public class FactoryProgressItemExtension - { - public static void Register(DIHelper services) - { - services.TryAdd(); - services.TryAdd(); - services.TryAdd(); - } - } -} +/* + * + * (c) Copyright Ascensio System Limited 2010-2020 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Threading; + +using ASC.Common; +using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Common.Threading; +using ASC.Common.Utils; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.Data.Backup.Contracts; +using ASC.Data.Backup.Core; +using ASC.Data.Backup.EF.Model; +using ASC.Data.Backup.Storage; +using ASC.Data.Backup.Tasks; +using ASC.Data.Backup.Tasks.Modules; +using ASC.Data.Backup.Utils; + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +using Newtonsoft.Json; + +namespace ASC.Data.Backup.Service +{ + [Singletone(Additional = typeof(BackupWorkerExtension))] + public class BackupWorker + { + private ILog Log { get; set; } + private DistributedTaskQueue ProgressQueue { get; set; } + internal string TempFolder { get; set; } + private string CurrentRegion { get; set; } + private Dictionary ConfigPaths { get; set; } + private int Limit { get; set; } + private string UpgradesPath { get; set; } + private ICacheNotify CacheBackupProgress { get; } + private FactoryProgressItem FactoryProgressItem { get; set; } + private TempPath TempPath { get; } + + private readonly object SynchRoot = new object(); + + public BackupWorker( + IOptionsMonitor options, + ICacheNotify cacheBackupProgress, + DistributedTaskQueueOptionsManager progressQueue, + FactoryProgressItem factoryProgressItem, + TempPath tempPath) + { + Log = options.CurrentValue; + ProgressQueue = progressQueue.Get(); + CacheBackupProgress = cacheBackupProgress; + FactoryProgressItem = factoryProgressItem; + TempPath = tempPath; + } + + public void Start(BackupSettings settings) + { + TempFolder = TempPath.GetTempPath(); + if (!Directory.Exists(TempFolder)) + { + Directory.CreateDirectory(TempFolder); + } + + Limit = settings.Limit; + UpgradesPath = settings.UpgradesPath; + CurrentRegion = settings.WebConfigs.CurrentRegion; + ConfigPaths = settings.WebConfigs.Elements.ToDictionary(el => el.Region, el => PathHelper.ToRootedConfigPath(el.Path)); + ConfigPaths[CurrentRegion] = PathHelper.ToRootedConfigPath(settings.WebConfigs.CurrentPath); + + var invalidConfigPath = ConfigPaths.Values.FirstOrDefault(path => !File.Exists(path)); + if (invalidConfigPath != null) + { + Log.WarnFormat("Configuration file {0} not found", invalidConfigPath); + } + } + + public void Stop() + { + if (ProgressQueue != null) + { + var tasks = ProgressQueue.GetTasks(); + foreach (var t in tasks) + { + ProgressQueue.CancelTask(t.Id); + } + + ProgressQueue = null; + } + } + + public BackupProgress StartBackup(StartBackupRequest request) + { + lock (SynchRoot) + { + var item = ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == request.TenantId); + if (item != null && item.IsCompleted) + { + ProgressQueue.RemoveTask(item.Id); + item = null; + } + if (item == null) + { + item = FactoryProgressItem.CreateBackupProgressItem(request, false, TempFolder, Limit, CurrentRegion, ConfigPaths); + ProgressQueue.QueueTask(item); + } + + item.PublishChanges(); + + return ToBackupProgress(item); + } + } + + public void StartScheduledBackup(BackupSchedule schedule) + { + lock (SynchRoot) + { + var item = ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == schedule.TenantId); + if (item != null && item.IsCompleted) + { + ProgressQueue.RemoveTask(item.Id); + item = null; + } + if (item == null) + { + item = FactoryProgressItem.CreateBackupProgressItem(schedule, false, TempFolder, Limit, CurrentRegion, ConfigPaths); + ProgressQueue.QueueTask(item); + } + } + } + + public BackupProgress GetBackupProgress(int tenantId) + { + lock (SynchRoot) + { + return ToBackupProgress(ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == tenantId)); + } + } + + public BackupProgress GetTransferProgress(int tenantId) + { + lock (SynchRoot) + { + return ToBackupProgress(ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == tenantId)); + } + } + + public BackupProgress GetRestoreProgress(int tenantId) + { + lock (SynchRoot) + { + return ToBackupProgress(ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == tenantId)); + } + } + + public void ResetBackupError(int tenantId) + { + lock (SynchRoot) + { + var progress = ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == tenantId); + if (progress != null) + { + progress.Exception = null; + } + } + } + + public void ResetRestoreError(int tenantId) + { + lock (SynchRoot) + { + var progress = ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == tenantId); + if (progress != null) + { + progress.Exception = null; + } + } + } + + public BackupProgress StartRestore(StartRestoreRequest request) + { + lock (SynchRoot) + { + var item = ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == request.TenantId); + if (item != null && item.IsCompleted) + { + ProgressQueue.RemoveTask(item.Id); + item = null; + } + if (item == null) + { + item = FactoryProgressItem.CreateRestoreProgressItem(request, TempFolder, UpgradesPath, CurrentRegion, ConfigPaths); + ProgressQueue.QueueTask(item); + } + return ToBackupProgress(item); + } + } + + public BackupProgress StartTransfer(int tenantId, string targetRegion, bool transferMail, bool notify) + { + lock (SynchRoot) + { + var item = ProgressQueue.GetTasks().FirstOrDefault(t => t.TenantId == tenantId); + if (item != null && item.IsCompleted) + { + ProgressQueue.RemoveTask(item.Id); + item = null; + } + + if (item == null) + { + item = FactoryProgressItem.CreateTransferProgressItem(targetRegion, transferMail, tenantId, TempFolder, Limit, notify, CurrentRegion, ConfigPaths); + ProgressQueue.QueueTask(item); + } + + return ToBackupProgress(item); + } + } + + + private BackupProgress ToBackupProgress(BaseBackupProgressItem progressItem) + { + if (progressItem == null) + { + return null; + } + var progress = new BackupProgress + { + IsCompleted = progressItem.IsCompleted, + Progress = (int)progressItem.Percentage, + Error = progressItem.Exception != null ? progressItem.Exception.Message : "", + TenantId = progressItem.TenantId, + BackupProgressEnum = progressItem.BackupProgressItemEnum.Convert() + }; + + if (progressItem is BackupProgressItem backupProgressItem && backupProgressItem.Link != null) + { + progress.Link = backupProgressItem.Link; + } + else + { + if (progressItem is TransferProgressItem transferProgressItem && transferProgressItem.Link != null) + { + progress.Link = transferProgressItem.Link; + } + } + + return progress; + } + + internal static string GetBackupHash(string path) + { + using (var sha256 = SHA256.Create()) + using (var fileStream = File.OpenRead(path)) + { + fileStream.Position = 0; + var hash = sha256.ComputeHash(fileStream); + return BitConverter.ToString(hash).Replace("-", string.Empty); + } + } + } + + public enum BackupProgressItemEnum + { + Backup, + Restore, + Transfer + } + + public static class BackupProgressItemEnumConverter + { + public static BackupProgressEnum Convert(this BackupProgressItemEnum backupProgressItemEnum) + { + return backupProgressItemEnum switch + { + BackupProgressItemEnum.Backup => BackupProgressEnum.Backup, + BackupProgressItemEnum.Restore => BackupProgressEnum.Restore, + BackupProgressItemEnum.Transfer => BackupProgressEnum.Transfer, + _ => BackupProgressEnum.Backup + }; + } + } + + public abstract class BaseBackupProgressItem : DistributedTaskProgress + { + private int? tenantId; + public int TenantId + { + get + { + return tenantId ?? GetProperty(nameof(tenantId)); + } + set + { + tenantId = value; + SetProperty(nameof(tenantId), value); + } + } + + public abstract BackupProgressItemEnum BackupProgressItemEnum { get; } + + public abstract object Clone(); + + protected ILog Log { get; set; } + + protected IServiceProvider ServiceProvider { get; set; } + + public BaseBackupProgressItem(IOptionsMonitor options, IServiceProvider serviceProvider) + { + Log = options.CurrentValue; + ServiceProvider = serviceProvider; + } + } + + [Transient] + public class BackupProgressItem : BaseBackupProgressItem + { + private const string ArchiveFormat = "tar.gz"; + + public BackupProgressItem(IOptionsMonitor options, IServiceProvider serviceProvider) : base(options, serviceProvider) + { + } + + public override BackupProgressItemEnum BackupProgressItemEnum { get => BackupProgressItemEnum.Backup; } + + private bool IsScheduled { get; set; } + private Guid UserId { get; set; } + private BackupStorageType StorageType { get; set; } + private string StorageBasePath { get; set; } + public bool BackupMail { get; set; } + public Dictionary StorageParams { get; set; } + public string Link { get; private set; } + public string TempFolder { get; set; } + private string CurrentRegion { get; set; } + private Dictionary ConfigPaths { get; set; } + private int Limit { get; set; } + + public void Init(BackupSchedule schedule, bool isScheduled, string tempFolder, int limit, string currentRegion, Dictionary configPaths) + { + UserId = Guid.Empty; + TenantId = schedule.TenantId; + StorageType = schedule.StorageType; + StorageBasePath = schedule.StorageBasePath; + BackupMail = schedule.BackupMail; + StorageParams = JsonConvert.DeserializeObject>(schedule.StorageParams); + IsScheduled = isScheduled; + TempFolder = tempFolder; + Limit = limit; + CurrentRegion = currentRegion; + ConfigPaths = configPaths; + } + + public void Init(StartBackupRequest request, bool isScheduled, string tempFolder, int limit, string currentRegion, Dictionary configPaths) + { + UserId = request.UserId; + TenantId = request.TenantId; + StorageType = request.StorageType; + StorageBasePath = request.StorageBasePath; + BackupMail = request.BackupMail; + StorageParams = request.StorageParams.ToDictionary(r => r.Key, r => r.Value); + IsScheduled = isScheduled; + TempFolder = tempFolder; + Limit = limit; + CurrentRegion = currentRegion; + ConfigPaths = configPaths; + } + + protected override void DoJob() + { + if (ThreadPriority.BelowNormal < Thread.CurrentThread.Priority) + { + Thread.CurrentThread.Priority = ThreadPriority.BelowNormal; + } + + using var scope = ServiceProvider.CreateScope(); + var scopeClass = scope.ServiceProvider.GetService(); + var (tenantManager, backupStorageFactory, notifyHelper, backupRepository, backupWorker, backupPortalTask, _, _, coreBaseSettings) = scopeClass; + + var tenant = tenantManager.GetTenant(TenantId); + var dateTime = coreBaseSettings.Standalone ? DateTime.Now : DateTime.UtcNow; + var backupName = string.Format("{0}_{1:yyyy-MM-dd_HH-mm-ss}.{2}", tenantManager.GetTenant(TenantId).TenantAlias, dateTime, ArchiveFormat); + + var tempFile = CrossPlatform.PathCombine(TempFolder, backupName); + var storagePath = tempFile; + try + { + var backupTask = backupPortalTask; + + backupTask.Init(TenantId, ConfigPaths[CurrentRegion], tempFile, Limit); + if (!BackupMail) + { + backupTask.IgnoreModule(ModuleName.Mail); + } + + backupTask.ProgressChanged += (sender, args) => + { + Percentage = 0.9 * args.Progress; + PublishChanges(); + }; + + backupTask.RunJob(); + + var backupStorage = backupStorageFactory.GetBackupStorage(StorageType, TenantId, StorageParams); + if (backupStorage != null) + { + storagePath = backupStorage.Upload(StorageBasePath, tempFile, UserId); + Link = backupStorage.GetPublicLink(storagePath); + } + + var repo = backupRepository; + repo.SaveBackupRecord( + new BackupRecord + { + Id = Guid.Parse(Id), + TenantId = TenantId, + IsScheduled = IsScheduled, + Name = Path.GetFileName(tempFile), + StorageType = StorageType, + StorageBasePath = StorageBasePath, + StoragePath = storagePath, + CreatedOn = DateTime.UtcNow, + ExpiresOn = StorageType == BackupStorageType.DataStore ? DateTime.UtcNow.AddDays(1) : DateTime.MinValue, + StorageParams = JsonConvert.SerializeObject(StorageParams), + Hash = BackupWorker.GetBackupHash(tempFile) + }); + + Percentage = 100; + + if (UserId != Guid.Empty && !IsScheduled) + { + notifyHelper.SendAboutBackupCompleted(UserId); + } + + IsCompleted = true; + PublishChanges(); + } + catch (Exception error) + { + Log.ErrorFormat("RunJob - Params: {0}, Error = {1}", new { Id, Tenant = TenantId, File = tempFile, BasePath = StorageBasePath, }, error); + Exception = error; + IsCompleted = true; + } + finally + { + try + { + PublishChanges(); + } + catch (Exception error) + { + Log.Error("publish", error); + } + + try + { + if (!(storagePath == tempFile && StorageType == BackupStorageType.Local)) + { + File.Delete(tempFile); + } + } + catch (Exception error) + { + Log.Error("can't delete file: {0}", error); + } + } + } + + public override object Clone() + { + return MemberwiseClone(); + } + } + + [Transient] + public class RestoreProgressItem : BaseBackupProgressItem + { + public RestoreProgressItem(IOptionsMonitor options, IServiceProvider serviceProvider) : base(options, serviceProvider) + { + } + + public override BackupProgressItemEnum BackupProgressItemEnum { get => BackupProgressItemEnum.Restore; } + public BackupStorageType StorageType { get; set; } + public string StoragePath { get; set; } + public bool Notify { get; set; } + public Dictionary StorageParams { get; set; } + public string TempFolder { get; set; } + private string CurrentRegion { get; set; } + private string UpgradesPath { get; set; } + private Dictionary ConfigPaths { get; set; } + + public void Init(StartRestoreRequest request, string tempFolder, string upgradesPath, string currentRegion, Dictionary configPaths) + { + TenantId = request.TenantId; + Notify = request.NotifyAfterCompletion; + StoragePath = request.FilePathOrId; + StorageType = request.StorageType; + TempFolder = tempFolder; + UpgradesPath = upgradesPath; + CurrentRegion = currentRegion; + ConfigPaths = configPaths; + } + + protected override void DoJob() + { + using var scope = ServiceProvider.CreateScope(); + var scopeClass = scope.ServiceProvider.GetService(); + var (tenantManager, backupStorageFactory, notifyHelper, backupRepository, backupWorker, _, restorePortalTask, _, coreBaseSettings) = scopeClass; + Tenant tenant = null; + var tempFile = PathHelper.GetTempFileName(TempFolder); + try + { + tenant = tenantManager.GetTenant(TenantId); + tenantManager.SetCurrentTenant(tenant); + notifyHelper.SendAboutRestoreStarted(tenant, Notify); + var storage = backupStorageFactory.GetBackupStorage(StorageType, TenantId, StorageParams); + storage.Download(StoragePath, tempFile); + + if (!coreBaseSettings.Standalone) + { + var backupHash = BackupWorker.GetBackupHash(tempFile); + var record = backupRepository.GetBackupRecord(backupHash, TenantId); + if (record == null) + { + throw new Exception(BackupResource.BackupNotFound); + } + } + + Percentage = 10; + + tenant.SetStatus(TenantStatus.Restoring); + tenantManager.SaveTenant(tenant); + + var columnMapper = new ColumnMapper(); + columnMapper.SetMapping("tenants_tenants", "alias", tenant.TenantAlias, (Guid.Parse(Id)).ToString("N")); + columnMapper.Commit(); + + var restoreTask = restorePortalTask; + restoreTask.Init(ConfigPaths[CurrentRegion], tempFile, TenantId, columnMapper, UpgradesPath); + restoreTask.ProgressChanged += (sender, args) => + { + Percentage = Percentage = (10d + 0.65 * args.Progress); + PublishChanges(); + }; + restoreTask.RunJob(); + + Tenant restoredTenant = null; + + if (restoreTask.Dump) + { + AscCacheNotify.OnClearCache(); + + if (Notify) + { + var tenants = tenantManager.GetTenants(); + foreach (var t in tenants) + { + notifyHelper.SendAboutRestoreCompleted(t, Notify); + } + } + } + else + { + tenantManager.RemoveTenant(tenant.TenantId); + + restoredTenant = tenantManager.GetTenant(columnMapper.GetTenantMapping()); + restoredTenant.SetStatus(TenantStatus.Active); + restoredTenant.TenantAlias = tenant.TenantAlias; + restoredTenant.PaymentId = string.Empty; + if (string.IsNullOrEmpty(restoredTenant.MappedDomain) && !string.IsNullOrEmpty(tenant.MappedDomain)) + { + restoredTenant.MappedDomain = tenant.MappedDomain; + } + tenantManager.SaveTenant(restoredTenant); + tenantManager.SetCurrentTenant(restoredTenant); + // sleep until tenants cache expires + Thread.Sleep(TimeSpan.FromMinutes(2)); + + notifyHelper.SendAboutRestoreCompleted(restoredTenant, Notify); + } + + Percentage = 75; + + PublishChanges(); + + File.Delete(tempFile); + + Percentage = 100; + PublishChanges(); + } + catch (Exception error) + { + Log.Error(error); + Exception = error; + + if (tenant != null) + { + tenant.SetStatus(TenantStatus.Active); + tenantManager.SaveTenant(tenant); + } + } + finally + { + try + { + PublishChanges(); + } + catch (Exception error) + { + Log.Error("publish", error); + } + + if (File.Exists(tempFile)) + { + File.Delete(tempFile); + } + } + } + + public override object Clone() + { + return MemberwiseClone(); + } + + + } + + [Transient] + public class TransferProgressItem : BaseBackupProgressItem + { + public TransferProgressItem(IOptionsMonitor options, IServiceProvider serviceProvider) : base(options, serviceProvider) + { + } + + public override BackupProgressItemEnum BackupProgressItemEnum { get => BackupProgressItemEnum.Transfer; } + public string TargetRegion { get; set; } + public bool TransferMail { get; set; } + public bool Notify { get; set; } + + public string Link { get; set; } + public string TempFolder { get; set; } + public Dictionary ConfigPaths { get; set; } + public string CurrentRegion { get; set; } + public int Limit { get; set; } + + public void Init( + string targetRegion, + bool transferMail, + int tenantId, + string tempFolder, + int limit, + bool notify, + string currentRegion, + Dictionary configPaths) + { + TenantId = tenantId; + TargetRegion = targetRegion; + TransferMail = transferMail; + Notify = notify; + TempFolder = tempFolder; + ConfigPaths = configPaths; + CurrentRegion = currentRegion; + Limit = limit; + + } + + protected override void DoJob() + { + using var scope = ServiceProvider.CreateScope(); + var scopeClass = scope.ServiceProvider.GetService(); + var (tenantManager, _, notifyHelper, _, backupWorker, _, _, transferPortalTask, _) = scopeClass; + var tempFile = PathHelper.GetTempFileName(TempFolder); + var tenant = tenantManager.GetTenant(TenantId); + var alias = tenant.TenantAlias; + + try + { + notifyHelper.SendAboutTransferStart(tenant, TargetRegion, Notify); + var transferProgressItem = transferPortalTask; + transferProgressItem.Init(TenantId, ConfigPaths[CurrentRegion], ConfigPaths[TargetRegion], Limit, TempFolder); + transferProgressItem.ProgressChanged += (sender, args) => + { + Percentage = args.Progress; + PublishChanges(); + }; + if (!TransferMail) + { + transferProgressItem.IgnoreModule(ModuleName.Mail); + } + transferProgressItem.RunJob(); + + Link = GetLink(alias, false); + notifyHelper.SendAboutTransferComplete(tenant, TargetRegion, Link, !Notify, transferProgressItem.ToTenantId); + PublishChanges(); + } + catch (Exception error) + { + Log.Error(error); + Exception = error; + + Link = GetLink(alias, true); + notifyHelper.SendAboutTransferError(tenant, TargetRegion, Link, !Notify); + } + finally + { + try + { + PublishChanges(); + } + catch (Exception error) + { + Log.Error("publish", error); + } + + if (File.Exists(tempFile)) + { + File.Delete(tempFile); + } + } + } + + private string GetLink(string alias, bool isErrorLink) + { + return "https://" + alias + "." + ConfigurationProvider.Open(ConfigPaths[isErrorLink ? CurrentRegion : TargetRegion]).AppSettings.Settings["core:base-domain"].Value; + } + + public override object Clone() + { + return MemberwiseClone(); + } + } + + [Singletone(Additional = typeof(FactoryProgressItemExtension))] + public class FactoryProgressItem + { + public IServiceProvider ServiceProvider { get; } + + public FactoryProgressItem(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + } + + public BackupProgressItem CreateBackupProgressItem( + StartBackupRequest request, + bool isScheduled, + string tempFolder, + int limit, + string currentRegion, + Dictionary configPaths) + { + var item = ServiceProvider.GetService(); + item.Init(request, isScheduled, tempFolder, limit, currentRegion, configPaths); + return item; + } + + public BackupProgressItem CreateBackupProgressItem( + BackupSchedule schedule, + bool isScheduled, + string tempFolder, + int limit, + string currentRegion, + Dictionary configPaths + ) + { + var item = ServiceProvider.GetService(); + item.Init(schedule, isScheduled, tempFolder, limit, currentRegion, configPaths); + return item; + } + + public RestoreProgressItem CreateRestoreProgressItem( + StartRestoreRequest request, + string tempFolder, + string upgradesPath, + string currentRegion, + Dictionary configPaths + ) + { + var item = ServiceProvider.GetService(); + item.Init(request, tempFolder, upgradesPath, currentRegion, configPaths); + return item; + } + + public TransferProgressItem CreateTransferProgressItem( + string targetRegion, + bool transferMail, + int tenantId, + string tempFolder, + int limit, + bool notify, + string currentRegion, + Dictionary configPaths + ) + { + var item = ServiceProvider.GetService(); + item.Init(targetRegion, transferMail, tenantId, tempFolder, limit, notify, currentRegion, configPaths); + return item; + } + } + + [Scope] + internal class BackupWorkerScope + { + private TenantManager TenantManager { get; } + private BackupStorageFactory BackupStorageFactory { get; } + private NotifyHelper NotifyHelper { get; } + private BackupRepository BackupRepository { get; } + private BackupWorker BackupWorker { get; } + private BackupPortalTask BackupPortalTask { get; } + private RestorePortalTask RestorePortalTask { get; } + private TransferPortalTask TransferPortalTask { get; } + private CoreBaseSettings CoreBaseSettings { get; } + + public BackupWorkerScope(TenantManager tenantManager, + BackupStorageFactory backupStorageFactory, + NotifyHelper notifyHelper, + BackupRepository backupRepository, + BackupWorker backupWorker, + BackupPortalTask backupPortalTask, + RestorePortalTask restorePortalTask, + TransferPortalTask transferPortalTask, + CoreBaseSettings coreBaseSettings) + { + TenantManager = tenantManager; + BackupStorageFactory = backupStorageFactory; + NotifyHelper = notifyHelper; + BackupRepository = backupRepository; + BackupWorker = backupWorker; + BackupPortalTask = backupPortalTask; + RestorePortalTask = restorePortalTask; + TransferPortalTask = transferPortalTask; + CoreBaseSettings = coreBaseSettings; + } + + public void Deconstruct(out TenantManager tenantManager, + out BackupStorageFactory backupStorageFactory, + out NotifyHelper notifyHelper, + out BackupRepository backupRepository, + out BackupWorker backupWorker, + out BackupPortalTask backupPortalTask, + out RestorePortalTask restorePortalTask, + out TransferPortalTask transferPortalTask, + out CoreBaseSettings coreBaseSettings) + { + tenantManager = TenantManager; + backupStorageFactory = BackupStorageFactory; + notifyHelper = NotifyHelper; + backupRepository = BackupRepository; + backupWorker = BackupWorker; + backupPortalTask = BackupPortalTask; + restorePortalTask = RestorePortalTask; + transferPortalTask = TransferPortalTask; + coreBaseSettings = CoreBaseSettings; + } + } + + public class BackupWorkerExtension + { + public static void Register(DIHelper services) + { + services.TryAdd(); + services.AddDistributedTaskQueueService(5); + } + } + + public class FactoryProgressItemExtension + { + public static void Register(DIHelper services) + { + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + } + } +} diff --git a/common/services/ASC.Data.Backup/Storage/BackupRepository.cs b/common/services/ASC.Data.Backup/Core/Storage/BackupRepository.cs similarity index 99% rename from common/services/ASC.Data.Backup/Storage/BackupRepository.cs rename to common/services/ASC.Data.Backup/Core/Storage/BackupRepository.cs index 89dad1e969..c442e973c1 100644 --- a/common/services/ASC.Data.Backup/Storage/BackupRepository.cs +++ b/common/services/ASC.Data.Backup/Core/Storage/BackupRepository.cs @@ -26,18 +26,18 @@ using System; using System.Collections.Generic; -using System.Linq; - -using ASC.Common; -using ASC.Core.Common.EF; +using System.Linq; + +using ASC.Common; +using ASC.Core.Common.EF; using ASC.Core.Tenants; using ASC.Data.Backup.EF.Context; -using ASC.Data.Backup.EF.Model; +using ASC.Data.Backup.EF.Model; namespace ASC.Data.Backup.Storage -{ +{ [Scope] public class BackupRepository : IBackupRepository - { + { private Lazy LazyBackupsContext { get; } private BackupsContext BackupContext { get => LazyBackupsContext.Value; } @@ -49,21 +49,21 @@ namespace ASC.Data.Backup.Storage public void SaveBackupRecord(BackupRecord backup) { BackupContext.AddOrUpdate(r => r.Backups, backup); - BackupContext.SaveChanges(); + BackupContext.SaveChanges(); } public BackupRecord GetBackupRecord(Guid id) - { - return BackupContext.Backups.SingleOrDefault(b => b.Id == id); - } - - public BackupRecord GetBackupRecord(string hash, int tenant) - { - return BackupContext.Backups.SingleOrDefault(b => b.Hash == hash && b.TenantId == tenant); - } + { + return BackupContext.Backups.SingleOrDefault(b => b.Id == id); + } + + public BackupRecord GetBackupRecord(string hash, int tenant) + { + return BackupContext.Backups.SingleOrDefault(b => b.Hash == hash && b.TenantId == tenant); + } public List GetExpiredBackupRecords() - { + { return BackupContext.Backups.Where(b => b.ExpiresOn != DateTime.MinValue && b.ExpiresOn <= DateTime.UtcNow).ToList(); } @@ -104,18 +104,18 @@ namespace ASC.Data.Backup.Storage public List GetBackupSchedules() { var query = BackupContext.Schedules.Join(BackupContext.Tenants, - s => s.TenantId, + s => s.TenantId, t => t.Id, - (s, t) => new { schedule = s, tenant = t }) - .Where(q => q.tenant.Status == TenantStatus.Active) - .Select(q => q.schedule); + (s, t) => new { schedule = s, tenant = t }) + .Where(q => q.tenant.Status == TenantStatus.Active) + .Select(q => q.schedule); return query.ToList(); } public BackupSchedule GetBackupSchedule(int tenantId) - { - return BackupContext.Schedules.SingleOrDefault(s => s.TenantId == tenantId); - } + { + return BackupContext.Schedules.SingleOrDefault(s => s.TenantId == tenantId); + } } } diff --git a/common/services/ASC.Data.Backup/Storage/BackupStorageFactory.cs b/common/services/ASC.Data.Backup/Core/Storage/BackupStorageFactory.cs similarity index 99% rename from common/services/ASC.Data.Backup/Storage/BackupStorageFactory.cs rename to common/services/ASC.Data.Backup/Core/Storage/BackupStorageFactory.cs index 1baf5def6a..1047310e08 100644 --- a/common/services/ASC.Data.Backup/Storage/BackupStorageFactory.cs +++ b/common/services/ASC.Data.Backup/Core/Storage/BackupStorageFactory.cs @@ -25,92 +25,92 @@ using System; -using System.Collections.Generic; - +using System.Collections.Generic; + using ASC.Common; -using ASC.Common.Logging; +using ASC.Common.Logging; using ASC.Common.Utils; using ASC.Core; -using ASC.Data.Backup.Contracts; +using ASC.Data.Backup.Contracts; using ASC.Data.Backup.EF.Model; using ASC.Data.Backup.Service; -using ASC.Data.Backup.Utils; - -using Microsoft.Extensions.Options; - -using Newtonsoft.Json; - +using ASC.Data.Backup.Utils; + +using Microsoft.Extensions.Options; + +using Newtonsoft.Json; + namespace ASC.Data.Backup.Storage -{ +{ [Scope] public class BackupStorageFactory { private ConfigurationExtension Configuration { get; } private DocumentsBackupStorage DocumentsBackupStorage { get; } - private DataStoreBackupStorage DataStoreBackupStorage { get; } - private ILog Log { get; } + private DataStoreBackupStorage DataStoreBackupStorage { get; } + private ILog Log { get; } private LocalBackupStorage LocalBackupStorage { get; } private ConsumerBackupStorage ConsumerBackupStorage { get; } private TenantManager TenantManager { get; } - public BackupStorageFactory( - ConsumerBackupStorage consumerBackupStorage, - LocalBackupStorage localBackupStorage, - ConfigurationExtension configuration, - DocumentsBackupStorage documentsBackupStorage, - TenantManager tenantManager, - DataStoreBackupStorage dataStoreBackupStorage, + public BackupStorageFactory( + ConsumerBackupStorage consumerBackupStorage, + LocalBackupStorage localBackupStorage, + ConfigurationExtension configuration, + DocumentsBackupStorage documentsBackupStorage, + TenantManager tenantManager, + DataStoreBackupStorage dataStoreBackupStorage, IOptionsMonitor options) { Configuration = configuration; DocumentsBackupStorage = documentsBackupStorage; - DataStoreBackupStorage = dataStoreBackupStorage; - Log = options.CurrentValue; + DataStoreBackupStorage = dataStoreBackupStorage; + Log = options.CurrentValue; LocalBackupStorage = localBackupStorage; ConsumerBackupStorage = consumerBackupStorage; TenantManager = tenantManager; - } - + } + public IBackupStorage GetBackupStorage(BackupRecord record) - { - try - { - return GetBackupStorage(record.StorageType, record.TenantId, JsonConvert.DeserializeObject>(record.StorageParams)); - } - catch (Exception error) - { - Log.Error("can't get backup storage for record " + record.Id, error); - return null; + { + try + { + return GetBackupStorage(record.StorageType, record.TenantId, JsonConvert.DeserializeObject>(record.StorageParams)); } - } + catch (Exception error) + { + Log.Error("can't get backup storage for record " + record.Id, error); + return null; + } + } public IBackupStorage GetBackupStorage(BackupStorageType type, int tenantId, Dictionary storageParams) { var settings = Configuration.GetSetting("backup"); - var webConfigPath = PathHelper.ToRootedConfigPath(settings.WebConfigs.CurrentPath); - + var webConfigPath = PathHelper.ToRootedConfigPath(settings.WebConfigs.CurrentPath); + switch (type) { case BackupStorageType.Documents: - case BackupStorageType.ThridpartyDocuments: - { - DocumentsBackupStorage.Init(tenantId, webConfigPath); - return DocumentsBackupStorage; + case BackupStorageType.ThridpartyDocuments: + { + DocumentsBackupStorage.Init(tenantId, webConfigPath); + return DocumentsBackupStorage; } - case BackupStorageType.DataStore: - { - DataStoreBackupStorage.Init(tenantId, webConfigPath); - return DataStoreBackupStorage; + case BackupStorageType.DataStore: + { + DataStoreBackupStorage.Init(tenantId, webConfigPath); + return DataStoreBackupStorage; } case BackupStorageType.Local: return LocalBackupStorage; - case BackupStorageType.ThirdPartyConsumer: - { - if (storageParams == null) return null; - TenantManager.SetCurrentTenant(tenantId); - ConsumerBackupStorage.Init(storageParams); - return ConsumerBackupStorage; + case BackupStorageType.ThirdPartyConsumer: + { + if (storageParams == null) return null; + TenantManager.SetCurrentTenant(tenantId); + ConsumerBackupStorage.Init(storageParams); + return ConsumerBackupStorage; } default: throw new InvalidOperationException("Unknown storage type."); diff --git a/common/services/ASC.Data.Backup/Storage/ConsumerBackupStorage.cs b/common/services/ASC.Data.Backup/Core/Storage/ConsumerBackupStorage.cs similarity index 99% rename from common/services/ASC.Data.Backup/Storage/ConsumerBackupStorage.cs rename to common/services/ASC.Data.Backup/Core/Storage/ConsumerBackupStorage.cs index 61c6fccd32..251c26539f 100644 --- a/common/services/ASC.Data.Backup/Storage/ConsumerBackupStorage.cs +++ b/common/services/ASC.Data.Backup/Core/Storage/ConsumerBackupStorage.cs @@ -34,7 +34,7 @@ using ASC.Data.Storage; using ASC.Data.Storage.Configuration; namespace ASC.Data.Backup.Storage -{ +{ [Scope] public class ConsumerBackupStorage : IBackupStorage { @@ -52,16 +52,16 @@ namespace ASC.Data.Backup.Storage } public string Upload(string storageBasePath, string localPath, Guid userId) { - using var stream = File.OpenRead(localPath); - var storagePath = Path.GetFileName(localPath); - Store.Save(Domain, storagePath, stream, ACL.Private); + using var stream = File.OpenRead(localPath); + var storagePath = Path.GetFileName(localPath); + Store.Save(Domain, storagePath, stream, ACL.Private); return storagePath; } public void Download(string storagePath, string targetLocalPath) { - using var source = Store.GetReadStream(Domain, storagePath); - using var destination = File.OpenWrite(targetLocalPath); + using var source = Store.GetReadStream(Domain, storagePath); + using var destination = File.OpenWrite(targetLocalPath); source.CopyTo(destination); } diff --git a/common/services/ASC.Data.Backup/Storage/DataStoreBackupStorage.cs b/common/services/ASC.Data.Backup/Core/Storage/DataStoreBackupStorage.cs similarity index 99% rename from common/services/ASC.Data.Backup/Storage/DataStoreBackupStorage.cs rename to common/services/ASC.Data.Backup/Core/Storage/DataStoreBackupStorage.cs index 928f4ed684..8ac44080bb 100644 --- a/common/services/ASC.Data.Backup/Storage/DataStoreBackupStorage.cs +++ b/common/services/ASC.Data.Backup/Core/Storage/DataStoreBackupStorage.cs @@ -31,7 +31,7 @@ using ASC.Common; using ASC.Data.Storage; namespace ASC.Data.Backup.Storage -{ +{ [Scope] public class DataStoreBackupStorage : IBackupStorage { @@ -50,16 +50,16 @@ namespace ASC.Data.Backup.Storage } public string Upload(string storageBasePath, string localPath, Guid userId) { - using var stream = File.OpenRead(localPath); - var storagePath = Path.GetFileName(localPath); - GetDataStore().Save("", storagePath, stream); + using var stream = File.OpenRead(localPath); + var storagePath = Path.GetFileName(localPath); + GetDataStore().Save("", storagePath, stream); return storagePath; } public void Download(string storagePath, string targetLocalPath) { - using var source = GetDataStore().GetReadStream("", storagePath); - using var destination = File.OpenWrite(targetLocalPath); + using var source = GetDataStore().GetReadStream("", storagePath); + using var destination = File.OpenWrite(targetLocalPath); source.CopyTo(destination); } @@ -68,7 +68,7 @@ namespace ASC.Data.Backup.Storage var dataStore = GetDataStore(); if (dataStore.IsFile("", storagePath)) { - dataStore.Delete("", storagePath); + dataStore.Delete("", storagePath); } } diff --git a/common/services/ASC.Data.Backup/Storage/DocumentsBackupStorage.cs b/common/services/ASC.Data.Backup/Core/Storage/DocumentsBackupStorage.cs similarity index 98% rename from common/services/ASC.Data.Backup/Storage/DocumentsBackupStorage.cs rename to common/services/ASC.Data.Backup/Core/Storage/DocumentsBackupStorage.cs index e9403c6b95..2ff9ef461c 100644 --- a/common/services/ASC.Data.Backup/Storage/DocumentsBackupStorage.cs +++ b/common/services/ASC.Data.Backup/Core/Storage/DocumentsBackupStorage.cs @@ -25,198 +25,198 @@ using System; -using System.IO; - -using ASC.Common; +using System.IO; + +using ASC.Common; using ASC.Core; using ASC.Data.Storage; -using ASC.Files.Core; -using ASC.Web.Studio.Core; -//using File = ASC.Files.Core.File; - -using Microsoft.Extensions.DependencyInjection; +using ASC.Files.Core; +using ASC.Web.Studio.Core; +//using File = ASC.Files.Core.File; + +using Microsoft.Extensions.DependencyInjection; namespace ASC.Data.Backup.Storage -{ +{ [Scope] public class DocumentsBackupStorage : IBackupStorage { private int TenantId { get; set; } - private string WebConfigPath { get; set; } - private SetupInfo SetupInfo { get; } + private string WebConfigPath { get; set; } + private SetupInfo SetupInfo { get; } private TenantManager TenantManager { get; set; } private SecurityContext SecurityContext { get; set; } private IDaoFactory DaoFactory { get; set; } - private StorageFactory StorageFactory { get; set; } - private IServiceProvider ServiceProvider { get; } - - public DocumentsBackupStorage( - SetupInfo setupInfo, - TenantManager tenantManager, - SecurityContext securityContext, - IDaoFactory daoFactory, - StorageFactory storageFactory, + private StorageFactory StorageFactory { get; set; } + private IServiceProvider ServiceProvider { get; } + + public DocumentsBackupStorage( + SetupInfo setupInfo, + TenantManager tenantManager, + SecurityContext securityContext, + IDaoFactory daoFactory, + StorageFactory storageFactory, IServiceProvider serviceProvider) - { - SetupInfo = setupInfo; + { + SetupInfo = setupInfo; TenantManager = tenantManager; SecurityContext = securityContext; DaoFactory = daoFactory; - StorageFactory = storageFactory; - ServiceProvider = serviceProvider; + StorageFactory = storageFactory; + ServiceProvider = serviceProvider; } - public void Init(int tenantId, string webConfigPath) - { + public void Init(int tenantId, string webConfigPath) + { TenantId = tenantId; - WebConfigPath = webConfigPath; + WebConfigPath = webConfigPath; } public string Upload(string folderId, string localPath, Guid userId) - { - TenantManager.SetCurrentTenant(TenantId); - if (!userId.Equals(Guid.Empty)) - { - SecurityContext.AuthenticateMeWithoutCookie(userId); - } - else - { - var tenant = TenantManager.GetTenant(TenantId); - SecurityContext.AuthenticateMeWithoutCookie(tenant.OwnerId); - } - - if (int.TryParse(folderId, out var fId)) - { - return Upload(fId, localPath).ToString(); - } - + { + TenantManager.SetCurrentTenant(TenantId); + if (!userId.Equals(Guid.Empty)) + { + SecurityContext.AuthenticateMeWithoutCookie(userId); + } + else + { + var tenant = TenantManager.GetTenant(TenantId); + SecurityContext.AuthenticateMeWithoutCookie(tenant.OwnerId); + } + + if (int.TryParse(folderId, out var fId)) + { + return Upload(fId, localPath).ToString(); + } + return Upload(folderId, localPath); } public void Download(string fileId, string targetLocalPath) - { - TenantManager.SetCurrentTenant(TenantId); - - if (int.TryParse(fileId, out var fId)) - { - DownloadDao(fId, targetLocalPath); - return; - } - - DownloadDao(fileId, targetLocalPath); + { + TenantManager.SetCurrentTenant(TenantId); + + if (int.TryParse(fileId, out var fId)) + { + DownloadDao(fId, targetLocalPath); + return; + } + + DownloadDao(fileId, targetLocalPath); } public void Delete(string fileId) - { - TenantManager.SetCurrentTenant(TenantId); - - if (int.TryParse(fileId, out var fId)) - { - DeleteDao(fId); - return; - } - - DeleteDao(fileId); + { + TenantManager.SetCurrentTenant(TenantId); + + if (int.TryParse(fileId, out var fId)) + { + DeleteDao(fId); + return; + } + + DeleteDao(fileId); } public bool IsExists(string fileId) - { - TenantManager.SetCurrentTenant(TenantId); - if (int.TryParse(fileId, out var fId)) - { - return IsExistsDao(fId); - } - + { + TenantManager.SetCurrentTenant(TenantId); + if (int.TryParse(fileId, out var fId)) + { + return IsExistsDao(fId); + } + return IsExistsDao(fileId); } public string GetPublicLink(string fileId) { return string.Empty; - } - + } + private T Upload(T folderId, string localPath) - { - var folderDao = GetFolderDao(); - var fileDao = GetFileDao(); - - var folder = folderDao.GetFolder(folderId); - if (folder == null) - { - throw new FileNotFoundException("Folder not found."); - } - - using var source = File.OpenRead(localPath); - var newFile = ServiceProvider.GetService>(); - newFile.Title = Path.GetFileName(localPath); - newFile.FolderID = folder.ID; - newFile.ContentLength = source.Length; - - File file = null; - var buffer = new byte[SetupInfo.ChunkUploadSize]; - var chunkedUploadSession = fileDao.CreateUploadSession(newFile, source.Length); - chunkedUploadSession.CheckQuota = false; - - var bytesRead = 0; - - while ((bytesRead = source.Read(buffer, 0, (int)SetupInfo.ChunkUploadSize)) > 0) - { - using (var theMemStream = new MemoryStream()) - { - theMemStream.Write(buffer, 0, bytesRead); - theMemStream.Position = 0; - file = fileDao.UploadChunk(chunkedUploadSession, theMemStream, bytesRead); - } - } - - return file.ID; - } - + { + var folderDao = GetFolderDao(); + var fileDao = GetFileDao(); + + var folder = folderDao.GetFolder(folderId); + if (folder == null) + { + throw new FileNotFoundException("Folder not found."); + } + + using var source = File.OpenRead(localPath); + var newFile = ServiceProvider.GetService>(); + newFile.Title = Path.GetFileName(localPath); + newFile.FolderID = folder.ID; + newFile.ContentLength = source.Length; + + File file = null; + var buffer = new byte[SetupInfo.ChunkUploadSize]; + var chunkedUploadSession = fileDao.CreateUploadSession(newFile, source.Length); + chunkedUploadSession.CheckQuota = false; + + var bytesRead = 0; + + while ((bytesRead = source.Read(buffer, 0, (int)SetupInfo.ChunkUploadSize)) > 0) + { + using (var theMemStream = new MemoryStream()) + { + theMemStream.Write(buffer, 0, bytesRead); + theMemStream.Position = 0; + file = fileDao.UploadChunk(chunkedUploadSession, theMemStream, bytesRead); + } + } + + return file.ID; + } + private void DownloadDao(T fileId, string targetLocalPath) - { - TenantManager.SetCurrentTenant(TenantId); - var fileDao = GetFileDao(); - var file = fileDao.GetFile(fileId); - if (file == null) - { - throw new FileNotFoundException("File not found."); - } - - using var source = fileDao.GetFileStream(file); - using var destination = File.OpenWrite(targetLocalPath); - source.CopyTo(destination); - } - + { + TenantManager.SetCurrentTenant(TenantId); + var fileDao = GetFileDao(); + var file = fileDao.GetFile(fileId); + if (file == null) + { + throw new FileNotFoundException("File not found."); + } + + using var source = fileDao.GetFileStream(file); + using var destination = File.OpenWrite(targetLocalPath); + source.CopyTo(destination); + } + private void DeleteDao(T fileId) - { - var fileDao = GetFileDao(); - fileDao.DeleteFile(fileId); - } - + { + var fileDao = GetFileDao(); + fileDao.DeleteFile(fileId); + } + private bool IsExistsDao(T fileId) - { - var fileDao = GetFileDao(); - try - { - - var file = fileDao.GetFile(fileId); - return file != null && file.RootFolderType != FolderType.TRASH; - } - catch (Exception) - { - return false; - } - } - - private IFolderDao GetFolderDao() - { - return DaoFactory.GetFolderDao(); - } - - private IFileDao GetFileDao() - { - // hack: create storage using webConfigPath and put it into DataStoreCache - // FileDao will use this storage and will not try to create the new one from service config - StorageFactory.GetStorage(WebConfigPath, TenantId.ToString(), "files"); - return DaoFactory.GetFileDao(); - } + { + var fileDao = GetFileDao(); + try + { + + var file = fileDao.GetFile(fileId); + return file != null && file.RootFolderType != FolderType.TRASH; + } + catch (Exception) + { + return false; + } + } + + private IFolderDao GetFolderDao() + { + return DaoFactory.GetFolderDao(); + } + + private IFileDao GetFileDao() + { + // hack: create storage using webConfigPath and put it into DataStoreCache + // FileDao will use this storage and will not try to create the new one from service config + StorageFactory.GetStorage(WebConfigPath, TenantId.ToString(), "files"); + return DaoFactory.GetFileDao(); + } } } diff --git a/common/services/ASC.Data.Backup/Storage/IBackupRepository.cs b/common/services/ASC.Data.Backup/Core/Storage/IBackupRepository.cs similarity index 99% rename from common/services/ASC.Data.Backup/Storage/IBackupRepository.cs rename to common/services/ASC.Data.Backup/Core/Storage/IBackupRepository.cs index ed05643616..1a6fdbd8e5 100644 --- a/common/services/ASC.Data.Backup/Storage/IBackupRepository.cs +++ b/common/services/ASC.Data.Backup/Core/Storage/IBackupRepository.cs @@ -34,7 +34,7 @@ namespace ASC.Data.Backup.Storage public interface IBackupRepository { void SaveBackupRecord(BackupRecord backupRecord); - BackupRecord GetBackupRecord(Guid id); + BackupRecord GetBackupRecord(Guid id); BackupRecord GetBackupRecord(string hash, int tenant); List GetExpiredBackupRecords(); List GetScheduledBackupRecords(); diff --git a/common/services/ASC.Data.Backup/Storage/IBackupStorage.cs b/common/services/ASC.Data.Backup/Core/Storage/IBackupStorage.cs similarity index 100% rename from common/services/ASC.Data.Backup/Storage/IBackupStorage.cs rename to common/services/ASC.Data.Backup/Core/Storage/IBackupStorage.cs diff --git a/common/services/ASC.Data.Backup/Storage/LocalBackupStorage.cs b/common/services/ASC.Data.Backup/Core/Storage/LocalBackupStorage.cs similarity index 99% rename from common/services/ASC.Data.Backup/Storage/LocalBackupStorage.cs rename to common/services/ASC.Data.Backup/Core/Storage/LocalBackupStorage.cs index 37009952c5..1864eecb05 100644 --- a/common/services/ASC.Data.Backup/Storage/LocalBackupStorage.cs +++ b/common/services/ASC.Data.Backup/Core/Storage/LocalBackupStorage.cs @@ -28,10 +28,10 @@ using System; using System.IO; using ASC.Common; -using ASC.Common.Utils; - +using ASC.Common.Utils; + namespace ASC.Data.Backup.Storage -{ +{ [Scope] public class LocalBackupStorage : IBackupStorage { diff --git a/common/services/ASC.Data.Backup/Storage/S3BackupStorage.cs b/common/services/ASC.Data.Backup/Core/Storage/S3BackupStorage.cs similarity index 99% rename from common/services/ASC.Data.Backup/Storage/S3BackupStorage.cs rename to common/services/ASC.Data.Backup/Core/Storage/S3BackupStorage.cs index 6344e31c75..d4740de90c 100644 --- a/common/services/ASC.Data.Backup/Storage/S3BackupStorage.cs +++ b/common/services/ASC.Data.Backup/Core/Storage/S3BackupStorage.cs @@ -58,7 +58,7 @@ namespace ASC.Data.Backup.Storage public string Upload(string storageBasePath, string localPath, Guid userId) { - string key; + string key; if (string.IsNullOrEmpty(storageBasePath)) key = "backup/" + Path.GetFileName(localPath); diff --git a/common/services/ASC.Data.Backup/Tasks/BackupFileInfo.cs b/common/services/ASC.Data.Backup/Core/Tasks/BackupFileInfo.cs similarity index 100% rename from common/services/ASC.Data.Backup/Tasks/BackupFileInfo.cs rename to common/services/ASC.Data.Backup/Core/Tasks/BackupFileInfo.cs diff --git a/common/services/ASC.Data.Backup/Tasks/BackupPortalTask.cs b/common/services/ASC.Data.Backup/Core/Tasks/BackupPortalTask.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/BackupPortalTask.cs rename to common/services/ASC.Data.Backup/Core/Tasks/BackupPortalTask.cs index b3758e9e1d..2d89d272a1 100644 --- a/common/services/ASC.Data.Backup/Tasks/BackupPortalTask.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/BackupPortalTask.cs @@ -33,10 +33,10 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; - + using ASC.Common; using ASC.Common.Logging; -using ASC.Common.Utils; +using ASC.Common.Utils; using ASC.Core; using ASC.Core.Common.EF; using ASC.Data.Backup.EF.Context; @@ -45,24 +45,24 @@ using ASC.Data.Backup.Extensions; using ASC.Data.Backup.Tasks.Data; using ASC.Data.Backup.Tasks.Modules; using ASC.Data.Storage; - + using Microsoft.Extensions.Options; - + using Newtonsoft.Json; namespace ASC.Data.Backup.Tasks -{ +{ [Scope] public class BackupPortalTask : PortalTaskBase - { - private const int MaxLength = 250; + { + private const int MaxLength = 250; private const int BatchLimit = 5000; public string BackupFilePath { get; private set; } public int Limit { get; private set; } private bool Dump { get; set; } - private TenantManager TenantManager { get; set; } - private TempStream TempStream { get; } + private TenantManager TenantManager { get; set; } + private TempStream TempStream { get; } private Lazy LazyBackupsContext { get; } private BackupsContext BackupRecordContext { get => LazyBackupsContext.Value; } @@ -70,10 +70,10 @@ namespace ASC.Data.Backup.Tasks : base(dbFactory, options, storageFactory, storageFactoryConfig, moduleProvider) { Dump = coreBaseSettings.Standalone; - TenantManager = tenantManager; - TempStream = tempStream; + TenantManager = tenantManager; + TempStream = tempStream; LazyBackupsContext = new Lazy(() => dbContextManager.Get(DbFactory.ConnectionStringSettings.ConnectionString)); - } + } public void Init(int tenantId, string fromConfigPath, string toFilePath, int limit) { @@ -91,14 +91,14 @@ namespace ASC.Data.Backup.Tasks using (var writer = new ZipWriteOperator(TempStream, BackupFilePath)) - { + { if (Dump) { DoDump(writer); } else - { - + { + var modulesToProcess = GetModulesToProcess().ToList(); var fileGroups = GetFilesGroup(); @@ -119,10 +119,10 @@ namespace ASC.Data.Backup.Tasks } private void DoDump(IDataWriteOperator writer) - { - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(true.ToString()))) - { - writer.WriteEntry(KeyHelper.GetDumpKey(), stream); + { + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(true.ToString()))) + { + writer.WriteEntry(KeyHelper.GetDumpKey(), stream); } List tables; @@ -132,12 +132,12 @@ namespace ASC.Data.Backup.Tasks var command = connection.CreateCommand(); command.CommandText = "show tables"; tables = ExecuteList(command).Select(r => Convert.ToString(r[0])).ToList(); - } - /* using (var dbManager = new DbManager("default", 100000)) - { - tables = dbManager.ExecuteList("show tables;").Select(r => Convert.ToString(r[0])).ToList(); - }*/ - + } + /* using (var dbManager = new DbManager("default", 100000)) + { + tables = dbManager.ExecuteList("show tables;").Select(r => Convert.ToString(r[0])).ToList(); + }*/ + var stepscount = tables.Count * 4; // (schema + data) * (dump + zip) if (ProcessStorage) { @@ -208,8 +208,8 @@ namespace ASC.Data.Backup.Tasks private IEnumerable GetFiles(int tenantId) { var files = GetFilesToProcess(tenantId).ToList(); - var exclude = BackupRecordContext.Backups.Where(b => b.TenantId == tenantId && b.StorageType == 0 && b.StoragePath != null).ToList(); - files = files.Where(f => !exclude.Any(e => f.Path.Replace('\\', '/').Contains(string.Format("/file_{0}/", e.StoragePath)))).ToList(); + var exclude = BackupRecordContext.Backups.Where(b => b.TenantId == tenantId && b.StorageType == 0 && b.StoragePath != null).ToList(); + files = files.Where(f => !exclude.Any(e => f.Path.Replace('\\', '/').Contains(string.Format("/file_{0}/", e.StoragePath)))).ToList(); return files; } @@ -240,8 +240,8 @@ namespace ASC.Data.Backup.Tasks } SetStepCompleted(); - } - + } + Logger.DebugFormat("dump table scheme stop {0}", t); } catch (Exception e) @@ -256,13 +256,13 @@ namespace ASC.Data.Backup.Tasks { try { - using var connection = DbFactory.OpenConnection(); - using var analyzeCommand = connection.CreateCommand(); - analyzeCommand.CommandText = $"analyze table {t}"; - analyzeCommand.ExecuteNonQuery(); - using var command = connection.CreateCommand(); - command.CommandText = $"select TABLE_ROWS from INFORMATION_SCHEMA.TABLES where TABLE_NAME = '{t}' and TABLE_SCHEMA = '{connection.Database}'"; - return int.Parse(command.ExecuteScalar().ToString()); + using var connection = DbFactory.OpenConnection(); + using var analyzeCommand = connection.CreateCommand(); + analyzeCommand.CommandText = $"analyze table {t}"; + analyzeCommand.ExecuteNonQuery(); + using var command = connection.CreateCommand(); + command.CommandText = $"select TABLE_ROWS from INFORMATION_SCHEMA.TABLES where TABLE_NAME = '{t}' and TABLE_SCHEMA = '{connection.Database}'"; + return int.Parse(command.ExecuteScalar().ToString()); } catch (Exception e) { @@ -318,47 +318,47 @@ namespace ASC.Data.Backup.Tasks if (searchWithPrimary) { - using var connection = DbFactory.OpenConnection(); - var command = connection.CreateCommand(); - command.CommandText = string.Format("select max({1}), min({1}) from {0}", t, primaryIndex); - var minMax = ExecuteList(command).ConvertAll(r => new Tuple(Convert.ToInt32(r[0]), Convert.ToInt32(r[1]))).FirstOrDefault(); - primaryIndexStart = minMax.Item2; - primaryIndexStep = (minMax.Item1 - minMax.Item2) / count; - - if (primaryIndexStep < Limit) - { - primaryIndexStep = Limit; + using var connection = DbFactory.OpenConnection(); + var command = connection.CreateCommand(); + command.CommandText = string.Format("select max({1}), min({1}) from {0}", t, primaryIndex); + var minMax = ExecuteList(command).ConvertAll(r => new Tuple(Convert.ToInt32(r[0]), Convert.ToInt32(r[1]))).FirstOrDefault(); + primaryIndexStart = minMax.Item2; + primaryIndexStep = (minMax.Item1 - minMax.Item2) / count; + + if (primaryIndexStep < Limit) + { + primaryIndexStep = Limit; } } - - var path = CrossPlatform.PathCombine(dir, t); - - var offset = 0; - - do - { - List result; - - if (searchWithPrimary) - { - result = GetDataWithPrimary(t, columns, primaryIndex, primaryIndexStart, primaryIndexStep); - primaryIndexStart += primaryIndexStep; - } - else - { - result = GetData(t, columns, offset); - } - - offset += Limit; - - var resultCount = result.Count; - - if (resultCount == 0) break; - - SaveToFile(path, t, columns, result); - - if (resultCount < Limit) break; - + + var path = CrossPlatform.PathCombine(dir, t); + + var offset = 0; + + do + { + List result; + + if (searchWithPrimary) + { + result = GetDataWithPrimary(t, columns, primaryIndex, primaryIndexStart, primaryIndexStep); + primaryIndexStart += primaryIndexStep; + } + else + { + result = GetData(t, columns, offset); + } + + offset += Limit; + + var resultCount = result.Count; + + if (resultCount == 0) break; + + SaveToFile(path, t, columns, result); + + if (resultCount < Limit) break; + } while (true); @@ -374,27 +374,27 @@ namespace ASC.Data.Backup.Tasks private List GetData(string t, List columns, int offset) { - using var connection = DbFactory.OpenConnection(); - var command = connection.CreateCommand(); - var selects = string.Join(',', columns); - command.CommandText = $"select {selects} from {t} LIMIT {offset}, {Limit}"; + using var connection = DbFactory.OpenConnection(); + var command = connection.CreateCommand(); + var selects = string.Join(',', columns); + command.CommandText = $"select {selects} from {t} LIMIT {offset}, {Limit}"; return ExecuteList(command); } private List GetDataWithPrimary(string t, List columns, string primary, int start, int step) { - using var connection = DbFactory.OpenConnection(); - var command = connection.CreateCommand(); - var selects = string.Join(',', columns); - command.CommandText = $"select {selects} from {t} where {primary} BETWEEN {start} and {start + step} "; - return ExecuteList(command); - } - + using var connection = DbFactory.OpenConnection(); + var command = connection.CreateCommand(); + var selects = string.Join(',', columns); + command.CommandText = $"select {selects} from {t} where {primary} BETWEEN {start} and {start + step} "; + return ExecuteList(command); + } + private void SaveToFile(string path, string t, IReadOnlyCollection columns, List data) { Logger.DebugFormat("save to file {0}", t); List portion; while ((portion = data.Take(BatchLimit).ToList()).Any()) - { + { using (var sw = new StreamWriter(path, true)) using (var writer = new JsonTextWriter(sw)) { @@ -478,11 +478,11 @@ namespace ASC.Data.Backup.Tasks var tmpPath = CrossPlatform.PathCombine(subDir, KeyHelper.GetStorageRestoreInfoZipKey()); Directory.CreateDirectory(Path.GetDirectoryName(tmpPath)); - using (var tmpFile = new FileStream(tmpPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read, 4096, FileOptions.DeleteOnClose)) - { - restoreInfoXml.WriteTo(tmpFile); - writer.WriteEntry(KeyHelper.GetStorageRestoreInfoZipKey(), tmpFile); - } + using (var tmpFile = new FileStream(tmpPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read, 4096, FileOptions.DeleteOnClose)) + { + restoreInfoXml.WriteTo(tmpFile); + writer.WriteEntry(KeyHelper.GetStorageRestoreInfoZipKey(), tmpFile); + } SetStepCompleted(); @@ -502,12 +502,12 @@ namespace ASC.Data.Backup.Tasks if (!Directory.Exists(dirName) && !string.IsNullOrEmpty(dirName)) { Directory.CreateDirectory(dirName); - } - - if (!WorkContext.IsMono && filePath.Length > MaxLength) - { - filePath = @"\\?\" + filePath; - } + } + + if (!WorkContext.IsMono && filePath.Length > MaxLength) + { + filePath = @"\\?\" + filePath; + } using (var fileStream = storage.GetReadStream(file.Domain, file.Path)) using (var tmpFile = File.OpenWrite(filePath)) @@ -523,14 +523,14 @@ namespace ASC.Data.Backup.Tasks Logger.DebugFormat("archive dir start {0}", subDir); foreach (var enumerateFile in Directory.EnumerateFiles(subDir, "*", SearchOption.AllDirectories)) { - var f = enumerateFile; - if (!WorkContext.IsMono && enumerateFile.Length > MaxLength) - { - f = @"\\?\" + f; - } - using (var tmpFile = new FileStream(f, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read, 4096, FileOptions.DeleteOnClose)) - { - writer.WriteEntry(enumerateFile.Substring(subDir.Length), tmpFile); + var f = enumerateFile; + if (!WorkContext.IsMono && enumerateFile.Length > MaxLength) + { + f = @"\\?\" + f; + } + using (var tmpFile = new FileStream(f, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read, 4096, FileOptions.DeleteOnClose)) + { + writer.WriteEntry(enumerateFile.Substring(subDir.Length), tmpFile); } SetStepCompleted(); } @@ -593,12 +593,12 @@ namespace ASC.Data.Backup.Tasks Logger.DebugFormat("begin saving table {0}", table.Name); - using (var file = TempStream.Create()) - { - data.WriteXml(file, XmlWriteMode.WriteSchema); - data.Clear(); - - writer.WriteEntry(KeyHelper.GetTableZipKey(module, data.TableName), file); + using (var file = TempStream.Create()) + { + data.WriteXml(file, XmlWriteMode.WriteSchema); + data.Clear(); + + writer.WriteEntry(KeyHelper.GetTableZipKey(module, data.TableName), file); } Logger.DebugFormat("end saving table {0}", table.Name); @@ -626,7 +626,7 @@ namespace ASC.Data.Backup.Tasks ActionInvoker.Try(state => { var f = (BackupFileInfo)state; - using var fileStream = storage.GetReadStream(f.Domain, f.Path); + using var fileStream = storage.GetReadStream(f.Domain, f.Path); writer.WriteEntry(file1.GetZipKey(), fileStream); }, file, 5, error => Logger.WarnFormat("can't backup file ({0}:{1}): {2}", file1.Module, file1.Path, error)); @@ -640,10 +640,10 @@ namespace ASC.Data.Backup.Tasks .SelectMany(group => group.Select(file => (object)file.ToXElement())) .ToArray()); - using (var tmpFile = TempStream.Create()) - { - restoreInfoXml.WriteTo(tmpFile); - writer.WriteEntry(KeyHelper.GetStorageRestoreInfoZipKey(), tmpFile); + using (var tmpFile = TempStream.Create()) + { + restoreInfoXml.WriteTo(tmpFile); + writer.WriteEntry(KeyHelper.GetStorageRestoreInfoZipKey(), tmpFile); } Logger.Debug("end backup storage"); diff --git a/common/services/ASC.Data.Backup/Tasks/ColumnMapper.cs b/common/services/ASC.Data.Backup/Core/Tasks/ColumnMapper.cs similarity index 100% rename from common/services/ASC.Data.Backup/Tasks/ColumnMapper.cs rename to common/services/ASC.Data.Backup/Core/Tasks/ColumnMapper.cs diff --git a/common/services/ASC.Data.Backup/Tasks/DbFactory.cs b/common/services/ASC.Data.Backup/Core/Tasks/DbFactory.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/DbFactory.cs rename to common/services/ASC.Data.Backup/Core/Tasks/DbFactory.cs index cd8631a8f7..378e207f16 100644 --- a/common/services/ASC.Data.Backup/Tasks/DbFactory.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/DbFactory.cs @@ -37,7 +37,7 @@ using Microsoft.Extensions.Configuration; using MySql.Data.MySqlClient; namespace ASC.Data.Backup.Tasks -{ +{ [Scope] public class DbFactory { @@ -45,7 +45,7 @@ namespace ASC.Data.Backup.Tasks private DbProviderFactory dbProviderFactory; - private IConfiguration Configuration { get; set; } + private IConfiguration Configuration { get; set; } private ConfigurationExtension ConfigurationExtension { get; set; } private string ConnectionString { get; set; } private string Path { get; set; } @@ -82,8 +82,8 @@ namespace ASC.Data.Backup.Tasks public DbFactory(IConfiguration configuration, ConfigurationExtension configurationExtension) { - Configuration = configuration; - ConfigurationExtension = configurationExtension; + Configuration = configuration; + ConfigurationExtension = configurationExtension; } public DbConnection OpenConnection(string path = "default", string connectionString = DefaultConnectionStringName)//TODO diff --git a/common/services/ASC.Data.Backup/Tasks/DeletePortalTask.cs b/common/services/ASC.Data.Backup/Core/Tasks/DeletePortalTask.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/DeletePortalTask.cs rename to common/services/ASC.Data.Backup/Core/Tasks/DeletePortalTask.cs index 31d66e42a9..5cc0841441 100644 --- a/common/services/ASC.Data.Backup/Tasks/DeletePortalTask.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/DeletePortalTask.cs @@ -31,8 +31,8 @@ using ASC.Data.Backup.Exceptions; using ASC.Data.Backup.Extensions; using ASC.Data.Backup.Tasks.Data; using ASC.Data.Backup.Tasks.Modules; -using ASC.Data.Storage; - +using ASC.Data.Storage; + using Microsoft.Extensions.Options; namespace ASC.Data.Backup.Tasks diff --git a/common/services/ASC.Data.Backup/Tasks/KeyHelper.cs b/common/services/ASC.Data.Backup/Core/Tasks/KeyHelper.cs similarity index 100% rename from common/services/ASC.Data.Backup/Tasks/KeyHelper.cs rename to common/services/ASC.Data.Backup/Core/Tasks/KeyHelper.cs diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/AuditModuleSpecifics.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/AuditModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Tasks/Modules/AuditModuleSpecifics.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/AuditModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/CalendarModuleSpecifics.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/CalendarModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Tasks/Modules/CalendarModuleSpecifics.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/CalendarModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/CommunityModuleSpecifics.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/CommunityModuleSpecifics.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/Modules/CommunityModuleSpecifics.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/CommunityModuleSpecifics.cs index ccd44291a0..68d48d6923 100644 --- a/common/services/ASC.Data.Backup/Tasks/Modules/CommunityModuleSpecifics.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/Modules/CommunityModuleSpecifics.cs @@ -28,9 +28,9 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Linq; - + using ASC.Data.Backup.Tasks.Data; -using ASC.Data.Backup.Utils; +using ASC.Data.Backup.Utils; namespace ASC.Data.Backup.Tasks.Modules { @@ -70,7 +70,7 @@ namespace ASC.Data.Backup.Tasks.Modules DateColumns = new Dictionary {{"created_when", false}, {"LastModified", false}} }, new TableInfo("blogs_reviewposts", "Tenant") - { + { UserIDColumns = new[] {"reviewed_by"}, DateColumns = new Dictionary {{"timestamp", false}} }, @@ -160,7 +160,7 @@ namespace ASC.Data.Backup.Tasks.Modules new RelationInfo("bookmarking_bookmark", "ID", "bookmarking_bookmarktag", "BookmarkID"), new RelationInfo("bookmarking_tag", "TagID", "bookmarking_bookmarktag", "TagID"), new RelationInfo("bookmarking_bookmark", "ID", "bookmarking_comment", "BookmarkID"), - new RelationInfo("bookmarking_comment", "ID", "bookmarking_comment", "Parent"), + new RelationInfo("bookmarking_comment", "ID", "bookmarking_comment", "Parent"), new RelationInfo("bookmarking_bookmark", "ID", "bookmarking_userbookmark", "BookmarkID"), new RelationInfo("bookmarking_tag", "TagID", "bookmarking_userbookmarktag", "TagID"), new RelationInfo("bookmarking_userbookmark", "UserBookmarkID", "bookmarking_userbookmarktag", "UserBookmarkID"), @@ -171,7 +171,7 @@ namespace ASC.Data.Backup.Tasks.Modules new RelationInfo("blogs_posts", "id", "blogs_tags", "post_id"), new RelationInfo("events_feed", "Id", "events_comment", "Feed"), new RelationInfo("events_comment", "Id", "events_comment", "Parent"), - new RelationInfo("events_feed", "Id", "events_poll", "Id"), + new RelationInfo("events_feed", "Id", "events_poll", "Id"), new RelationInfo("events_pollvariant", "Id", "events_pollanswer", "Variant"), new RelationInfo("events_feed", "Id", "events_pollvariant", "Poll"), new RelationInfo("events_feed", "Id", "events_reader", "Feed"), @@ -180,7 +180,7 @@ namespace ASC.Data.Backup.Tasks.Modules new RelationInfo("forum_variant", "id", "forum_answer_variant", "variant_id"), new RelationInfo("forum_post", "id", "forum_attachment", "post_id"), new RelationInfo("forum_category", "id", "forum_attachment", "path"), - new RelationInfo("forum_thread", "id", "forum_attachment", "path"), + new RelationInfo("forum_thread", "id", "forum_attachment", "path"), new RelationInfo("forum_thread", "id", "forum_lastvisit", "thread_id"), new RelationInfo("forum_topic", "id", "forum_post", "topic_id"), new RelationInfo("forum_post", "id", "forum_post", "parent_post_id"), @@ -195,7 +195,7 @@ namespace ASC.Data.Backup.Tasks.Modules new RelationInfo("forum_topic", "id", "forum_topic_tag", "topic_id"), new RelationInfo("forum_tag", "id", "forum_topic_tag", "tag_id"), new RelationInfo("forum_question", "id", "forum_variant", "question_id"), - new RelationInfo("wiki_comments", "Id", "wiki_comments", "ParentId") + new RelationInfo("wiki_comments", "Id", "wiki_comments", "ParentId") }; public override ModuleName ModuleName diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/CoreModuleSpecifics.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/CoreModuleSpecifics.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/Modules/CoreModuleSpecifics.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/CoreModuleSpecifics.cs index fb592316b7..6a693b165c 100644 --- a/common/services/ASC.Data.Backup/Tasks/Modules/CoreModuleSpecifics.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/Modules/CoreModuleSpecifics.cs @@ -27,8 +27,8 @@ using System; using System.Collections.Generic; using System.Data.Common; -using System.Linq; - +using System.Linq; + using ASC.Core.Billing; using ASC.Data.Backup.Tasks.Data; @@ -53,9 +53,9 @@ namespace ASC.Data.Backup.Tasks.Modules private const string CrmCasesAclObjectStart = "ASC.CRM.Core.Entities.Cases|"; private const string CrmRelationshipEventAclObjectStart = "ASC.CRM.Core.Entities.RelationshipEvent|"; private const string CalendarCalendarAclObjectStart = "ASC.Api.Calendar.BusinessObjects.Calendar|"; - private const string CalendarEventAclObjectStart = "ASC.Api.Calendar.BusinessObjects.Event|"; - - + private const string CalendarEventAclObjectStart = "ASC.Api.Calendar.BusinessObjects.Event|"; + + private readonly TableInfo[] _tables = new[] { new TableInfo("core_acl", "tenant") {InsertMethod = InsertMethod.Ignore}, @@ -77,7 +77,7 @@ namespace ASC.Data.Backup.Tasks.Modules new TableInfo("feed_users") {InsertMethod = InsertMethod.None}, new TableInfo("backup_backup", "tenant_id", "id", IdType.Guid), new TableInfo("backup_schedule", "tenant_id"), - new TableInfo("core_settings", "tenant") + new TableInfo("core_settings", "tenant") }; private readonly RelationInfo[] _tableRelations; @@ -175,8 +175,8 @@ namespace ASC.Data.Backup.Tasks.Modules } protected override string GetSelectCommandConditionText(int tenantId, TableInfo table) - { - + { + if (table.Name == "feed_users") return "inner join core_user t1 on t1.id = t.user_id where t1.tenant = " + tenantId; diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/CrmModuleSpecifics.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/CrmModuleSpecifics.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/Modules/CrmModuleSpecifics.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/CrmModuleSpecifics.cs index a9302f3f3f..2cf6251a13 100644 --- a/common/services/ASC.Data.Backup/Tasks/Modules/CrmModuleSpecifics.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/Modules/CrmModuleSpecifics.cs @@ -28,10 +28,10 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Linq; -using System.Text.RegularExpressions; - -using ASC.Data.Backup.Tasks.Data; - +using System.Text.RegularExpressions; + +using ASC.Data.Backup.Tasks.Data; + using Newtonsoft.Json.Linq; namespace ASC.Data.Backup.Tasks.Modules @@ -97,10 +97,10 @@ namespace ASC.Data.Backup.Tasks.Modules { new RelationInfo("crm_contact", "id", "crm_contact", "company_id"), new RelationInfo("crm_list_item", "id", "crm_contact", "status_id"), - new RelationInfo("crm_list_item", "id", "crm_contact", "contact_type_id"), + new RelationInfo("crm_list_item", "id", "crm_contact", "contact_type_id"), new RelationInfo("crm_contact", "id", "crm_contact_info", "contact_id"), new RelationInfo("crm_deal_milestone", "id", "crm_deal", "deal_milestone_id"), - new RelationInfo("crm_contact", "id", "crm_deal", "contact_id"), + new RelationInfo("crm_contact", "id", "crm_deal", "contact_id"), new RelationInfo("projects_projects", "id", "crm_projects", "project_id", typeof(ProjectsModuleSpecifics)), new RelationInfo("crm_contact", "id", "crm_projects", "contact_id"), new RelationInfo("crm_contact", "id", "crm_task", "entity_id", x => ResolveRelation(x, 0, 4, 5)), @@ -200,7 +200,7 @@ namespace ASC.Data.Backup.Tasks.Modules new RelationInfo("crm_relationship_event", "id", "crm_field_value", "entity_id", typeof(CrmModuleSpecifics), x => ResolveRelation(x, 2)), new RelationInfo("crm_relationship_event", "id", "crm_entity_tag", "entity_id", typeof(CrmModuleSpecifics), x => ResolveRelation(x, 2)), new RelationInfo("crm_relationship_event", "id", "crm_entity_contact", "entity_id", typeof(CrmModuleSpecifics), x => ResolveRelation(x, 2)), - new RelationInfo("mail_mail", "id", "crm_relationship_event", "content", typeof(MailModuleSpecifics), x => Convert.ToInt32(x["category_id"]) == -3), + new RelationInfo("mail_mail", "id", "crm_relationship_event", "content", typeof(MailModuleSpecifics), x => Convert.ToInt32(x["category_id"]) == -3), }; public override string ConnectionStringName @@ -358,24 +358,24 @@ namespace ASC.Data.Backup.Tasks.Modules if (table.Name == "crm_invoice" && columnName == "json_data") { - var data = JObject.Parse((string)value); - + var data = JObject.Parse((string)value); + var oldValue = Convert.ToInt32(data["LogoBase64Id"]); if (oldValue != 0) { - data["LogoBase64Id"] = Convert.ToInt32(columnMapper.GetMapping("crm_organisation_logo", "id", oldValue)); + data["LogoBase64Id"] = Convert.ToInt32(columnMapper.GetMapping("crm_organisation_logo", "id", oldValue)); } oldValue = Convert.ToInt32(data["DeliveryAddressID"]); if (oldValue != 0) { - data["DeliveryAddressID"] = Convert.ToInt32(columnMapper.GetMapping("crm_contact_info", "id", oldValue)); + data["DeliveryAddressID"] = Convert.ToInt32(columnMapper.GetMapping("crm_contact_info", "id", oldValue)); } oldValue = Convert.ToInt32(data["BillingAddressID"]); if (oldValue != 0) { - data["BillingAddressID"] = Convert.ToInt32(columnMapper.GetMapping("crm_contact_info", "id", oldValue)); + data["BillingAddressID"] = Convert.ToInt32(columnMapper.GetMapping("crm_contact_info", "id", oldValue)); } value = data.ToString(); diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/FilesModuleSpecifics.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/FilesModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Tasks/Modules/FilesModuleSpecifics.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/FilesModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/Helpers.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/Helpers.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/Modules/Helpers.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/Helpers.cs index 637e334b48..a8cc1b6483 100644 --- a/common/services/ASC.Data.Backup/Tasks/Modules/Helpers.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/Modules/Helpers.cs @@ -25,17 +25,17 @@ using System; -using System.Linq; - +using System.Linq; + using ASC.Common; using ASC.Core; -using ASC.Security.Cryptography; - +using ASC.Security.Cryptography; + using ConfigurationConstants = ASC.Core.Configuration.Constants; using UserConstants = ASC.Core.Users.Constants; namespace ASC.Data.Backup.Tasks.Modules -{ +{ [Scope] public class Helpers { @@ -46,9 +46,9 @@ namespace ASC.Data.Backup.Tasks.Modules ConfigurationConstants.CoreSystem.ID, ConfigurationConstants.Guest.ID, UserConstants.LostUser.ID - }; - - + }; + + private readonly Guid[] SystemGroups = new[] { Guid.Empty, diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/IModuleSpecifics.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/IModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Tasks/Modules/IModuleSpecifics.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/IModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/MailModuleSpecifics.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/MailModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Tasks/Modules/MailModuleSpecifics.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/MailModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/ModuleProvider.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/ModuleProvider.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/Modules/ModuleProvider.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/ModuleProvider.cs index 51bebd615d..1bf2817cb7 100644 --- a/common/services/ASC.Data.Backup/Tasks/Modules/ModuleProvider.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/Modules/ModuleProvider.cs @@ -26,15 +26,15 @@ using System.Collections.Generic; using System.Linq; - + using ASC.Common; using ASC.Common.Logging; -using ASC.Core; - -using Microsoft.Extensions.Options; +using ASC.Core; + +using Microsoft.Extensions.Options; namespace ASC.Data.Backup.Tasks.Modules -{ +{ [Scope] public class ModuleProvider { @@ -62,15 +62,15 @@ namespace ASC.Data.Backup.Tasks.Modules } public IModuleSpecifics GetByStorageModule(string storageModuleName, string storageDomainName = null) { - return storageModuleName switch - { - "files" => AllModules.FirstOrDefault(m => m.ModuleName == ModuleName.Files), - "projects" => AllModules.FirstOrDefault(m => m.ModuleName == ModuleName.Projects), - "crm" => AllModules.FirstOrDefault(m => m.ModuleName == (storageDomainName == "mail_messages" ? ModuleName.Crm2 : ModuleName.Crm)), - "forum" => AllModules.FirstOrDefault(m => m.ModuleName == ModuleName.Community), - "mailaggregator" => AllModules.FirstOrDefault(m => m.ModuleName == ModuleName.Mail), - _ => null, - }; + return storageModuleName switch + { + "files" => AllModules.FirstOrDefault(m => m.ModuleName == ModuleName.Files), + "projects" => AllModules.FirstOrDefault(m => m.ModuleName == ModuleName.Projects), + "crm" => AllModules.FirstOrDefault(m => m.ModuleName == (storageDomainName == "mail_messages" ? ModuleName.Crm2 : ModuleName.Crm)), + "forum" => AllModules.FirstOrDefault(m => m.ModuleName == ModuleName.Community), + "mailaggregator" => AllModules.FirstOrDefault(m => m.ModuleName == ModuleName.Mail), + _ => null, + }; } } } diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/ModuleSpecificsBase.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/ModuleSpecificsBase.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/Modules/ModuleSpecificsBase.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/ModuleSpecificsBase.cs index ed470855a9..b4e9165231 100644 --- a/common/services/ASC.Data.Backup/Tasks/Modules/ModuleSpecificsBase.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/Modules/ModuleSpecificsBase.cs @@ -254,8 +254,8 @@ namespace ASC.Data.Backup.Tasks.Modules { value = mappedValue; return true; - } - + } + return value == null || Guid.TryParse(Convert.ToString(value), out _) || int.TryParse(Convert.ToString(value), out _); diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/ProjectsModuleSpecifics.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/ProjectsModuleSpecifics.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/Modules/ProjectsModuleSpecifics.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/ProjectsModuleSpecifics.cs index 13c9a2612c..d3b4749aa5 100644 --- a/common/services/ASC.Data.Backup/Tasks/Modules/ProjectsModuleSpecifics.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/Modules/ProjectsModuleSpecifics.cs @@ -28,9 +28,9 @@ using System; using System.Collections.Generic; using System.Data.Common; using System.Text.RegularExpressions; - + using ASC.Data.Backup.Tasks.Data; -using ASC.Data.Backup.Utils; +using ASC.Data.Backup.Utils; namespace ASC.Data.Backup.Tasks.Modules { @@ -87,7 +87,7 @@ namespace ASC.Data.Backup.Tasks.Modules private readonly RelationInfo[] _tableRelations = new[] { - new RelationInfo("projects_comments", "id", "projects_comments", "parent_id"), + new RelationInfo("projects_comments", "id", "projects_comments", "parent_id"), new RelationInfo("projects_messages", "id", "projects_comments", "target_uniq_id", x => Convert.ToString(x["target_uniq_id"]).StartsWith("Message_", StringComparison.InvariantCultureIgnoreCase)), new RelationInfo("projects_tasks", "id", "projects_comments", "target_uniq_id", x => Convert.ToString(x["target_uniq_id"]).StartsWith("Task_", StringComparison.InvariantCultureIgnoreCase)), new RelationInfo("projects_milestones", "id", "projects_comments", "target_uniq_id", x => Convert.ToString(x["target_uniq_id"]).StartsWith("Milestone_", StringComparison.InvariantCultureIgnoreCase)), @@ -107,7 +107,7 @@ namespace ASC.Data.Backup.Tasks.Modules new RelationInfo("projects_tasks", "id", "projects_tasks_links", "parent_id"), new RelationInfo("projects_projects", "id", "projects_tasks_order", "project_id"), new RelationInfo("projects_tasks", "id", "projects_tasks_order", "task_order"), - new RelationInfo("projects_milestones", "id", "projects_tasks_order", "task_order") + new RelationInfo("projects_milestones", "id", "projects_tasks_order", "task_order") }; public override ModuleName ModuleName diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/TenantsModuleSpecifics.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/TenantsModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Tasks/Modules/TenantsModuleSpecifics.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/TenantsModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Tasks/Modules/WebStudioModuleSpecifics.cs b/common/services/ASC.Data.Backup/Core/Tasks/Modules/WebStudioModuleSpecifics.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/Modules/WebStudioModuleSpecifics.cs rename to common/services/ASC.Data.Backup/Core/Tasks/Modules/WebStudioModuleSpecifics.cs index b1bf66b7ce..120efbeb15 100644 --- a/common/services/ASC.Data.Backup/Tasks/Modules/WebStudioModuleSpecifics.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/Modules/WebStudioModuleSpecifics.cs @@ -27,15 +27,15 @@ using System; using System.Collections.Generic; using System.Data.Common; -using System.Text.RegularExpressions; - +using System.Text.RegularExpressions; + using ASC.Data.Backup.Tasks.Data; namespace ASC.Data.Backup.Tasks.Modules { public class WebStudioModuleSpecifics : ModuleSpecificsBase { - public WebStudioModuleSpecifics(Helpers helpers) + public WebStudioModuleSpecifics(Helpers helpers) : base(helpers) { } private static readonly Guid CrmSettingsId = new Guid("fdf39b9a-ec96-4eb7-aeab-63f2c608eada"); diff --git a/common/services/ASC.Data.Backup/Tasks/PortalTaskBase.cs b/common/services/ASC.Data.Backup/Core/Tasks/PortalTaskBase.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/PortalTaskBase.cs rename to common/services/ASC.Data.Backup/Core/Tasks/PortalTaskBase.cs index dec1f90252..079bcdba69 100644 --- a/common/services/ASC.Data.Backup/Tasks/PortalTaskBase.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/PortalTaskBase.cs @@ -30,25 +30,25 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Text; -using System.Threading.Tasks; - +using System.Threading.Tasks; + using ASC.Common.Logging; using ASC.Data.Backup.Tasks.Modules; -using ASC.Data.Storage; - +using ASC.Data.Storage; + using Microsoft.Extensions.Options; namespace ASC.Data.Backup.Tasks { public class ProgressChangedEventArgs : EventArgs { - public int Progress { get; private set; } - - + public int Progress { get; private set; } + + public ProgressChangedEventArgs(int progress) { - Progress = progress; - + Progress = progress; + } } @@ -144,8 +144,8 @@ namespace ASC.Data.Backup.Tasks "fckuploaders", "talk", "mailaggregator", - "whitelabel", - "customnavigation", + "whitelabel", + "customnavigation", "userPhotos" }; @@ -281,39 +281,39 @@ namespace ASC.Data.Backup.Tasks } protected async Task RunMysqlFile(Stream stream, string delimiter = ";") - { - - if (stream == null) return; - - using var reader = new StreamReader(stream, Encoding.UTF8); - string commandText; - - while ((commandText = await reader.ReadLineAsync()) != null) - { - while (!commandText.EndsWith(delimiter)) - { - var newline = await reader.ReadLineAsync(); - if (newline == null) - { - break; - } - commandText += newline; - } - - try - { - - using var connection = DbFactory.OpenConnection(); - var command = connection.CreateCommand(); - command.CommandText = commandText; - await command.ExecuteNonQueryAsync(); - // await dbManager.ExecuteNonQueryAsync(commandText, null); - } - catch (Exception e) - { - Logger.Error("Restore", e); - } - } + { + + if (stream == null) return; + + using var reader = new StreamReader(stream, Encoding.UTF8); + string commandText; + + while ((commandText = await reader.ReadLineAsync()) != null) + { + while (!commandText.EndsWith(delimiter)) + { + var newline = await reader.ReadLineAsync(); + if (newline == null) + { + break; + } + commandText += newline; + } + + try + { + + using var connection = DbFactory.OpenConnection(); + var command = connection.CreateCommand(); + command.CommandText = commandText; + await command.ExecuteNonQueryAsync(); + // await dbManager.ExecuteNonQueryAsync(commandText, null); + } + catch (Exception e) + { + Logger.Error("Restore", e); + } + } } } } diff --git a/common/services/ASC.Data.Backup/Tasks/RestoreDbModuleTask.cs b/common/services/ASC.Data.Backup/Core/Tasks/RestoreDbModuleTask.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/RestoreDbModuleTask.cs rename to common/services/ASC.Data.Backup/Core/Tasks/RestoreDbModuleTask.cs index e4367b1ed3..419689d3cf 100644 --- a/common/services/ASC.Data.Backup/Tasks/RestoreDbModuleTask.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/RestoreDbModuleTask.cs @@ -35,8 +35,8 @@ using ASC.Data.Backup.Exceptions; using ASC.Data.Backup.Extensions; using ASC.Data.Backup.Tasks.Data; using ASC.Data.Backup.Tasks.Modules; -using ASC.Data.Storage; - +using ASC.Data.Storage; + using Microsoft.Extensions.Options; namespace ASC.Data.Backup.Tasks @@ -56,7 +56,7 @@ namespace ASC.Data.Backup.Tasks { Reader = reader ?? throw new ArgumentNullException("reader"); ColumnMapper = columnMapper ?? throw new ArgumentNullException("columnMapper"); - DbFactory = factory ?? throw new ArgumentNullException("factory"); + DbFactory = factory ?? throw new ArgumentNullException("factory"); Module = module; ReplaceDate = replaceDate; Dump = dump; @@ -95,111 +95,111 @@ namespace ASC.Data.Backup.Tasks { SetColumns(connection, tableInfo); - using var stream = Reader.GetEntry(KeyHelper.GetTableZipKey(Module, tableInfo.Name)); - var lowImportanceRelations = Module - .TableRelations - .Where( - r => - string.Equals(r.ParentTable, tableInfo.Name, StringComparison.InvariantCultureIgnoreCase)) - .Where(r => r.Importance == RelationImportance.Low && !r.IsSelfRelation()) - .Select(r => Tuple.Create(r, Module.Tables.Single(t => t.Name == r.ChildTable))) - .ToList(); - - foreach ( - var rows in - GetRows(tableInfo, stream) - .Skip(transactionsCommited * TransactionLength) - .MakeParts(TransactionLength)) - { - using var transaction = connection.BeginTransaction(); - var rowsSuccess = 0; - foreach (var row in rows) - { - if (ReplaceDate) - { - foreach (var column in tableInfo.DateColumns) - { - ColumnMapper.SetDateMapping(tableInfo.Name, column, row[column.Key]); - } - } - - object oldIdValue = null; - object newIdValue = null; - - if (tableInfo.HasIdColumn()) - { - oldIdValue = row[tableInfo.IdColumn]; - newIdValue = ColumnMapper.GetMapping(tableInfo.Name, tableInfo.IdColumn, oldIdValue); - if (newIdValue == null) - { - if (tableInfo.IdType == IdType.Guid) - { - newIdValue = Guid.NewGuid().ToString("D"); - } - else if (tableInfo.IdType == IdType.Integer) - { - var command = connection.CreateCommand(); - command.CommandText = string.Format("select max({0}) from {1};", tableInfo.IdColumn, tableInfo.Name); - newIdValue = (int)command.WithTimeout(120).ExecuteScalar() + 1; - } - } - if (newIdValue != null) - { - ColumnMapper.SetMapping(tableInfo.Name, tableInfo.IdColumn, oldIdValue, - newIdValue); - } - } - - var insertCommand = Module.CreateInsertCommand(Dump, connection, ColumnMapper, tableInfo, - row); - if (insertCommand == null) - { - Logger.WarnFormat("Can't create command to insert row to {0} with values [{1}]", tableInfo, - row); - ColumnMapper.Rollback(); - continue; - } - insertCommand.WithTimeout(120).ExecuteNonQuery(); - rowsSuccess++; - - if (tableInfo.HasIdColumn() && tableInfo.IdType == IdType.Autoincrement) - { - var lastIdCommand = DbFactory.CreateLastInsertIdCommand(); - lastIdCommand.Connection = connection; - newIdValue = Convert.ToInt32(lastIdCommand.ExecuteScalar()); - ColumnMapper.SetMapping(tableInfo.Name, tableInfo.IdColumn, oldIdValue, newIdValue); - } - - ColumnMapper.Commit(); - - foreach (var relation in lowImportanceRelations) - { - if (!relation.Item2.HasTenantColumn()) - { - Logger.WarnFormat( - "Table {0} does not contain tenant id column. Can't apply low importance relations on such tables.", - relation.Item2.Name); - continue; - } - - var oldValue = row[relation.Item1.ParentColumn]; - var newValue = ColumnMapper.GetMapping(relation.Item1.ParentTable, - relation.Item1.ParentColumn, oldValue); - var command = connection.CreateCommand(); - command.CommandText = string.Format("update {0} set {1} = {2} where {1} = {3} and {4} = {5}", - relation.Item1.ChildTable, - relation.Item1.ChildColumn, - newValue is string ? "'" + newValue + "'" : newValue, - oldValue is string ? "'" + oldValue + "'" : oldValue, - relation.Item2.TenantColumn, - ColumnMapper.GetTenantMapping()); - command.WithTimeout(120).ExecuteNonQuery(); - } - } - - transaction.Commit(); - transactionsCommited++; - rowsInserted += rowsSuccess; + using var stream = Reader.GetEntry(KeyHelper.GetTableZipKey(Module, tableInfo.Name)); + var lowImportanceRelations = Module + .TableRelations + .Where( + r => + string.Equals(r.ParentTable, tableInfo.Name, StringComparison.InvariantCultureIgnoreCase)) + .Where(r => r.Importance == RelationImportance.Low && !r.IsSelfRelation()) + .Select(r => Tuple.Create(r, Module.Tables.Single(t => t.Name == r.ChildTable))) + .ToList(); + + foreach ( + var rows in + GetRows(tableInfo, stream) + .Skip(transactionsCommited * TransactionLength) + .MakeParts(TransactionLength)) + { + using var transaction = connection.BeginTransaction(); + var rowsSuccess = 0; + foreach (var row in rows) + { + if (ReplaceDate) + { + foreach (var column in tableInfo.DateColumns) + { + ColumnMapper.SetDateMapping(tableInfo.Name, column, row[column.Key]); + } + } + + object oldIdValue = null; + object newIdValue = null; + + if (tableInfo.HasIdColumn()) + { + oldIdValue = row[tableInfo.IdColumn]; + newIdValue = ColumnMapper.GetMapping(tableInfo.Name, tableInfo.IdColumn, oldIdValue); + if (newIdValue == null) + { + if (tableInfo.IdType == IdType.Guid) + { + newIdValue = Guid.NewGuid().ToString("D"); + } + else if (tableInfo.IdType == IdType.Integer) + { + var command = connection.CreateCommand(); + command.CommandText = string.Format("select max({0}) from {1};", tableInfo.IdColumn, tableInfo.Name); + newIdValue = (int)command.WithTimeout(120).ExecuteScalar() + 1; + } + } + if (newIdValue != null) + { + ColumnMapper.SetMapping(tableInfo.Name, tableInfo.IdColumn, oldIdValue, + newIdValue); + } + } + + var insertCommand = Module.CreateInsertCommand(Dump, connection, ColumnMapper, tableInfo, + row); + if (insertCommand == null) + { + Logger.WarnFormat("Can't create command to insert row to {0} with values [{1}]", tableInfo, + row); + ColumnMapper.Rollback(); + continue; + } + insertCommand.WithTimeout(120).ExecuteNonQuery(); + rowsSuccess++; + + if (tableInfo.HasIdColumn() && tableInfo.IdType == IdType.Autoincrement) + { + var lastIdCommand = DbFactory.CreateLastInsertIdCommand(); + lastIdCommand.Connection = connection; + newIdValue = Convert.ToInt32(lastIdCommand.ExecuteScalar()); + ColumnMapper.SetMapping(tableInfo.Name, tableInfo.IdColumn, oldIdValue, newIdValue); + } + + ColumnMapper.Commit(); + + foreach (var relation in lowImportanceRelations) + { + if (!relation.Item2.HasTenantColumn()) + { + Logger.WarnFormat( + "Table {0} does not contain tenant id column. Can't apply low importance relations on such tables.", + relation.Item2.Name); + continue; + } + + var oldValue = row[relation.Item1.ParentColumn]; + var newValue = ColumnMapper.GetMapping(relation.Item1.ParentTable, + relation.Item1.ParentColumn, oldValue); + var command = connection.CreateCommand(); + command.CommandText = string.Format("update {0} set {1} = {2} where {1} = {3} and {4} = {5}", + relation.Item1.ChildTable, + relation.Item1.ChildColumn, + newValue is string ? "'" + newValue + "'" : newValue, + oldValue is string ? "'" + oldValue + "'" : oldValue, + relation.Item2.TenantColumn, + ColumnMapper.GetTenantMapping()); + command.WithTimeout(120).ExecuteNonQuery(); + } + } + + transaction.Commit(); + transactionsCommited++; + rowsInserted += rowsSuccess; } } diff --git a/common/services/ASC.Data.Backup/Tasks/RestorePortalTask.cs b/common/services/ASC.Data.Backup/Core/Tasks/RestorePortalTask.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/RestorePortalTask.cs rename to common/services/ASC.Data.Backup/Core/Tasks/RestorePortalTask.cs index 147393e0cb..95ad6c19c3 100644 --- a/common/services/ASC.Data.Backup/Tasks/RestorePortalTask.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/RestorePortalTask.cs @@ -34,18 +34,18 @@ using System.Xml.Linq; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; -using ASC.Common.Utils; +using ASC.Common.Utils; using ASC.Core; using ASC.Core.Billing; using ASC.Core.Tenants; using ASC.Data.Backup.Extensions; using ASC.Data.Backup.Tasks.Modules; -using ASC.Data.Storage; - +using ASC.Data.Storage; + using Microsoft.Extensions.Options; namespace ASC.Data.Backup.Tasks -{ +{ [Scope] public class RestorePortalTask : PortalTaskBase { @@ -57,29 +57,29 @@ namespace ASC.Data.Backup.Tasks public bool ReplaceDate { get; set; } public bool Dump { get; set; } private CoreBaseSettings CoreBaseSettings { get; set; } - private LicenseReader LicenseReader { get; set; } - public TenantManager TenantManager { get; } + private LicenseReader LicenseReader { get; set; } + public TenantManager TenantManager { get; } private AscCacheNotify AscCacheNotify { get; set; } private IOptionsMonitor Options { get; set; } - public RestorePortalTask( - DbFactory dbFactory, - IOptionsMonitor options, - StorageFactory storageFactory, - StorageFactoryConfig storageFactoryConfig, - CoreBaseSettings coreBaseSettings, - LicenseReader licenseReader, - TenantManager tenantManager, - AscCacheNotify ascCacheNotify, + public RestorePortalTask( + DbFactory dbFactory, + IOptionsMonitor options, + StorageFactory storageFactory, + StorageFactoryConfig storageFactoryConfig, + CoreBaseSettings coreBaseSettings, + LicenseReader licenseReader, + TenantManager tenantManager, + AscCacheNotify ascCacheNotify, ModuleProvider moduleProvider) : base(dbFactory, options, storageFactory, storageFactoryConfig, moduleProvider) { CoreBaseSettings = coreBaseSettings; - LicenseReader = licenseReader; - TenantManager = tenantManager; + LicenseReader = licenseReader; + TenantManager = tenantManager; AscCacheNotify = ascCacheNotify; Options = options; - } + } public void Init(string toConfigPath, string fromFilePath, int tenantId = -1, ColumnMapper columnMapper = null, string upgradesPath = null) { @@ -93,7 +93,7 @@ namespace ASC.Data.Backup.Tasks UpgradesPath = upgradesPath; ColumnMapper = columnMapper ?? new ColumnMapper(); Init(tenantId, toConfigPath); - } + } public override void RunJob() { @@ -132,12 +132,12 @@ namespace ASC.Data.Backup.Tasks Logger.Debug("end restore data"); if (ProcessStorage) - { - if (CoreBaseSettings.Standalone) - { - Logger.Debug("clear cache"); - AscCacheNotify.ClearCache(); - } + { + if (CoreBaseSettings.Standalone) + { + Logger.Debug("clear cache"); + AscCacheNotify.ClearCache(); + } DoRestoreStorage(dataReader); } @@ -179,23 +179,23 @@ namespace ASC.Data.Backup.Tasks var stepscount = keys.Count * 2 + upgrades.Count; - SetStepsCount(ProcessStorage ? stepscount + 1 : stepscount); - - if (ProcessStorage) - { - var storageModules = StorageFactoryConfig.GetModuleList(ConfigPath).Where(IsStorageModuleAllowed); - var tenants = TenantManager.GetTenants(false); - - stepscount += storageModules.Count() * tenants.Count; - - SetStepsCount(stepscount + 1); - - DoDeleteStorage(storageModules, tenants); - } - else - { - SetStepsCount(stepscount); - } + SetStepsCount(ProcessStorage ? stepscount + 1 : stepscount); + + if (ProcessStorage) + { + var storageModules = StorageFactoryConfig.GetModuleList(ConfigPath).Where(IsStorageModuleAllowed); + var tenants = TenantManager.GetTenants(false); + + stepscount += storageModules.Count() * tenants.Count; + + SetStepsCount(stepscount + 1); + + DoDeleteStorage(storageModules, tenants); + } + else + { + SetStepsCount(stepscount); + } for (var i = 0; i < keys.Count; i += TasksLimit) { @@ -289,14 +289,14 @@ namespace ASC.Data.Backup.Tasks { key = CrossPlatform.PathCombine(KeyHelper.GetStorage(), key); } - using var stream = dataReader.GetEntry(key); - try - { - storage.Save(file.Domain, adjustedPath, module != null ? module.PrepareData(key, stream, ColumnMapper) : stream); - } - catch (Exception error) - { - Logger.WarnFormat("can't restore file ({0}:{1}): {2}", file.Module, file.Path, error); + using var stream = dataReader.GetEntry(key); + try + { + storage.Save(file.Domain, adjustedPath, module != null ? module.PrepareData(key, stream, ColumnMapper) : stream); + } + catch (Exception error) + { + Logger.WarnFormat("can't restore file ({0}:{1}): {2}", file.Module, file.Path, error); } } } @@ -317,69 +317,69 @@ namespace ASC.Data.Backup.Tasks SetStepCompleted(); } Logger.Debug("end restore storage"); - } - - private void DoDeleteStorage(IEnumerable storageModules, IEnumerable tenants) - { - Logger.Debug("begin delete storage"); - - foreach (var tenant in tenants) - { - foreach (var module in storageModules) - { - var storage = StorageFactory.GetStorage(ConfigPath, tenant.TenantId.ToString(), module); - var domains = StorageFactoryConfig.GetDomainList(ConfigPath, module).ToList(); - - domains.Add(string.Empty); //instead storage.DeleteFiles("\\", "*.*", true); - - foreach (var domain in domains) - { - ActionInvoker.Try( - state => - { - if (storage.IsDirectory((string)state)) - { - storage.DeleteFiles((string)state, "\\", "*.*", true); - } - }, - domain, - 5, - onFailure: error => Logger.WarnFormat("Can't delete files for domain {0}: \r\n{1}", domain, error) - ); - } - - SetStepCompleted(); - } - } - - Logger.Debug("end delete storage"); + } + + private void DoDeleteStorage(IEnumerable storageModules, IEnumerable tenants) + { + Logger.Debug("begin delete storage"); + + foreach (var tenant in tenants) + { + foreach (var module in storageModules) + { + var storage = StorageFactory.GetStorage(ConfigPath, tenant.TenantId.ToString(), module); + var domains = StorageFactoryConfig.GetDomainList(ConfigPath, module).ToList(); + + domains.Add(string.Empty); //instead storage.DeleteFiles("\\", "*.*", true); + + foreach (var domain in domains) + { + ActionInvoker.Try( + state => + { + if (storage.IsDirectory((string)state)) + { + storage.DeleteFiles((string)state, "\\", "*.*", true); + } + }, + domain, + 5, + onFailure: error => Logger.WarnFormat("Can't delete files for domain {0}: \r\n{1}", domain, error) + ); + } + + SetStepCompleted(); + } + } + + Logger.Debug("end delete storage"); } private IEnumerable GetFilesToProcess(IDataReadOperator dataReader) { - using var stream = dataReader.GetEntry(KeyHelper.GetStorageRestoreInfoZipKey()); - if (stream == null) - { - return Enumerable.Empty(); - } - var restoreInfo = XElement.Load(new StreamReader(stream)); + using var stream = dataReader.GetEntry(KeyHelper.GetStorageRestoreInfoZipKey()); + if (stream == null) + { + return Enumerable.Empty(); + } + var restoreInfo = XElement.Load(new StreamReader(stream)); return restoreInfo.Elements("file").Select(BackupFileInfo.FromXElement).ToList(); } private void SetTenantActive(int tenantId) { - using var connection = DbFactory.OpenConnection(); - var commandText = string.Format( - "update tenants_tenants " + - "set " + - " status={0}, " + - " last_modified='{1}', " + - " statuschanged='{1}' " + - "where id = '{2}'", - (int)TenantStatus.Active, - DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"), - tenantId); - + using var connection = DbFactory.OpenConnection(); + var commandText = string.Format( + "update tenants_tenants " + + "set " + + " status={0}, " + + " last_modified='{1}', " + + " statuschanged='{1}' " + + "where id = '{2}'", + (int)TenantStatus.Active, + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"), + tenantId); + connection.CreateCommand().WithTimeout(120).ExecuteNonQuery(); } } diff --git a/common/services/ASC.Data.Backup/Tasks/TransferPortalTask.cs b/common/services/ASC.Data.Backup/Core/Tasks/TransferPortalTask.cs similarity index 99% rename from common/services/ASC.Data.Backup/Tasks/TransferPortalTask.cs rename to common/services/ASC.Data.Backup/Core/Tasks/TransferPortalTask.cs index 480aaa5b7c..bb1b900760 100644 --- a/common/services/ASC.Data.Backup/Tasks/TransferPortalTask.cs +++ b/common/services/ASC.Data.Backup/Core/Tasks/TransferPortalTask.cs @@ -31,7 +31,7 @@ using System.Linq; using ASC.Common; using ASC.Common.Logging; -using ASC.Common.Utils; +using ASC.Common.Utils; using ASC.Core.Tenants; using ASC.Data.Backup.Extensions; using ASC.Data.Backup.Tasks.Modules; @@ -41,7 +41,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; namespace ASC.Data.Backup.Tasks -{ +{ [Scope] public class TransferPortalTask : PortalTaskBase { @@ -53,30 +53,30 @@ namespace ASC.Data.Backup.Tasks public bool DeleteBackupFileAfterCompletion { get; set; } public bool BlockOldPortalAfterStart { get; set; } public bool DeleteOldPortalAfterCompletion { get; set; } - private IOptionsMonitor Options { get; set; } - private TempStream TempStream { get; } - private TempPath TempPath { get; } + private IOptionsMonitor Options { get; set; } + private TempStream TempStream { get; } + private TempPath TempPath { get; } private IServiceProvider ServiceProvider { get; set; } public int ToTenantId { get; private set; } public int Limit { get; private set; } - public TransferPortalTask( - DbFactory dbFactory, - IServiceProvider serviceProvider, - IOptionsMonitor options, - StorageFactory storageFactory, - StorageFactoryConfig storageFactoryConfig, - ModuleProvider moduleProvider, - TempStream tempStream, + public TransferPortalTask( + DbFactory dbFactory, + IServiceProvider serviceProvider, + IOptionsMonitor options, + StorageFactory storageFactory, + StorageFactoryConfig storageFactoryConfig, + ModuleProvider moduleProvider, + TempStream tempStream, TempPath tempPath) : base(dbFactory, options, storageFactory, storageFactoryConfig, moduleProvider) { DeleteBackupFileAfterCompletion = true; BlockOldPortalAfterStart = true; DeleteOldPortalAfterCompletion = true; - Options = options; - TempStream = tempStream; - TempPath = tempPath; + Options = options; + TempStream = tempStream; + TempPath = tempPath; ServiceProvider = serviceProvider; } @@ -145,8 +145,8 @@ namespace ASC.Data.Backup.Tasks else if (BlockOldPortalAfterStart) { SaveTenant(fromDbFactory, tenantAlias, TenantStatus.Active); - } - + } + ToTenantId = columnMapper.GetTenantMapping(); } catch diff --git a/common/services/ASC.Data.Backup/Utils/ConfigurationProvider.cs b/common/services/ASC.Data.Backup/Core/Utils/ConfigurationProvider.cs similarity index 100% rename from common/services/ASC.Data.Backup/Utils/ConfigurationProvider.cs rename to common/services/ASC.Data.Backup/Core/Utils/ConfigurationProvider.cs diff --git a/common/services/ASC.Data.Backup/Utils/FCKEditorPathUtility.cs b/common/services/ASC.Data.Backup/Core/Utils/FCKEditorPathUtility.cs similarity index 100% rename from common/services/ASC.Data.Backup/Utils/FCKEditorPathUtility.cs rename to common/services/ASC.Data.Backup/Core/Utils/FCKEditorPathUtility.cs diff --git a/common/services/ASC.Data.Backup/Utils/PathHelper.cs b/common/services/ASC.Data.Backup/Core/Utils/PathHelper.cs similarity index 100% rename from common/services/ASC.Data.Backup/Utils/PathHelper.cs rename to common/services/ASC.Data.Backup/Core/Utils/PathHelper.cs diff --git a/common/services/ASC.Data.Backup/protos/BackupProgress.proto b/common/services/ASC.Data.Backup/Core/protos/BackupProgress.proto similarity index 100% rename from common/services/ASC.Data.Backup/protos/BackupProgress.proto rename to common/services/ASC.Data.Backup/Core/protos/BackupProgress.proto diff --git a/common/services/ASC.Data.Backup/protos/DeleteSchedule.proto b/common/services/ASC.Data.Backup/Core/protos/DeleteSchedule.proto similarity index 100% rename from common/services/ASC.Data.Backup/protos/DeleteSchedule.proto rename to common/services/ASC.Data.Backup/Core/protos/DeleteSchedule.proto diff --git a/common/services/ASC.Data.Backup/Tasks/Data/DataRowInfo.cs b/common/services/ASC.Data.Backup/Tasks/Data/DataRowInfo.cs deleted file mode 100644 index c66df9a818..0000000000 --- a/common/services/ASC.Data.Backup/Tasks/Data/DataRowInfo.cs +++ /dev/null @@ -1,106 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2020 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using System.Collections.Generic; -using System.Text; - -namespace ASC.Data.Backup.Tasks.Data -{ - public class DataRowInfo - { - private readonly List _columnNames = new List(); - private readonly List _values = new List(); - - public string TableName { get; private set; } - - public IReadOnlyCollection ColumnNames - { - get { return _columnNames.AsReadOnly(); } - } - - public object this[int index] - { - get { return _values[index]; } - } - - public object this[string columnName] - { - get { return _values[GetIndex(columnName)]; } - } - - public DataRowInfo(string tableName) - { - TableName = tableName; - } - - public void SetValue(string columnName, object item) - { - var index = GetIndex(columnName); - if (index == -1) - { - _columnNames.Add(columnName); - _values.Add(item); - } - else - { - _values[index] = item; - } - } - - private int GetIndex(string columnName) - { - return _columnNames.FindIndex(name => name.Equals(columnName, StringComparison.OrdinalIgnoreCase)); - } - - public override string ToString() - { - const int maxStrLength = 150; - - var sb = new StringBuilder(maxStrLength); - - var i = 0; - while (i < _values.Count && sb.Length <= maxStrLength) - { - var strVal = Convert.ToString(_values[i]); - sb.AppendFormat("\"{0}\", ", strVal); - i++; - } - - if (sb.Length > maxStrLength + 2) - { - sb.Length = maxStrLength - 3; - sb.Append("..."); - } - else if (sb.Length > 0) - { - sb.Length -= 2; - } - - return sb.ToString(); - } - } -} diff --git a/common/services/ASC.Data.Backup/Tasks/Data/DataRowInfoReader.cs b/common/services/ASC.Data.Backup/Tasks/Data/DataRowInfoReader.cs deleted file mode 100644 index 4777884720..0000000000 --- a/common/services/ASC.Data.Backup/Tasks/Data/DataRowInfoReader.cs +++ /dev/null @@ -1,100 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2020 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Xml; -using System.Xml.Linq; - -using ASC.Data.Backup.Extensions; - -namespace ASC.Data.Backup.Tasks.Data -{ - internal static class DataRowInfoReader - { - private const string XmlSchemaNamespace = "http://www.w3.org/2001/XMLSchema"; - - public static IEnumerable ReadFromStream(Stream stream) - { - var readerSettings = new XmlReaderSettings - { - CheckCharacters = false, - CloseInput = false - }; - - using var xmlReader = XmlReader.Create(stream, readerSettings); - xmlReader.MoveToContent(); - xmlReader.ReadToFollowing("schema", XmlSchemaNamespace); - - var schema = new Dictionary(); - - if (XNode.ReadFrom(xmlReader) is XElement schemaElement) - { - foreach (var entry in schemaElement.Descendants(XName.Get("sequence", XmlSchemaNamespace)).Single().Elements(XName.Get("element", XmlSchemaNamespace))) - { - schema.Add(entry.Attribute("name").ValueOrDefault(), entry.Attribute("type").ValueOrDefault()); - } - } - - while (xmlReader.Read()) - { - if (xmlReader.NodeType == XmlNodeType.Element) - { - if (XNode.ReadFrom(xmlReader) is XElement el) - { - var dataRowInfo = new DataRowInfo(el.Name.LocalName); - foreach (var column in schema) - { - var value = ConvertToType(el.Element(column.Key).ValueOrDefault(), column.Value); - dataRowInfo.SetValue(column.Key, value); - } - - yield return dataRowInfo; - } - } - } - } - - private static object ConvertToType(string str, string schemaType) - { - if (str == null) - { - return null; - } - if (schemaType == "xs:boolean") - { - return Convert.ToBoolean(str); - } - if (schemaType == "xs:base64Binary") - { - return Convert.FromBase64String(str); - } - return str; - } - } -} diff --git a/common/services/ASC.Data.Backup/Tasks/Data/RelationInfo.cs b/common/services/ASC.Data.Backup/Tasks/Data/RelationInfo.cs deleted file mode 100644 index d4ecdaca15..0000000000 --- a/common/services/ASC.Data.Backup/Tasks/Data/RelationInfo.cs +++ /dev/null @@ -1,108 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2020 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using System.Diagnostics; - -namespace ASC.Data.Backup.Tasks.Data -{ - public enum RelationImportance - { - Low, - Normal - } - - [DebuggerDisplay("({ParentTable},{ParentColumn})->({ChildTable},{ChildColumn})")] - public class RelationInfo - { - public string ParentTable { get; private set; } - public string ParentColumn { get; private set; } - public string ChildTable { get; private set; } - public string ChildColumn { get; private set; } - - public Type ParentModule { get; private set; } - public RelationImportance Importance { get; private set; } - - public Func CollisionResolver { get; private set; } - - - public RelationInfo(string parentTable, string parentColumn, string childTable, string childColumn) - : this(parentTable, parentColumn, childTable, childColumn, null, null) - { - - } - - public RelationInfo(string parentTable, string parentColumn, string childTable, string childColumn, Func collisionResolver) - : this(parentTable, parentColumn, childTable, childColumn, null, collisionResolver) - { - - } - - public RelationInfo(string parentTable, string parentColumn, string childTable, string childColumn, Type parentModule) - : this(parentTable, parentColumn, childTable, childColumn, parentModule, null) - { - - } - - public RelationInfo(string parentTable, string parentColumn, string childTable, string childColumn, Type parentModule, Func collisionResolver) - : this(parentTable, parentColumn, childTable, childColumn, parentModule, collisionResolver, RelationImportance.Normal) - { - - } - - public RelationInfo(string parentTable, string parentColumn, string childTable, string childColumn, Type parentModule, Func collisionResolver, RelationImportance importance) - { - ParentTable = parentTable; - ParentColumn = parentColumn; - ChildTable = childTable; - ChildColumn = childColumn; - ParentModule = parentModule; - CollisionResolver = collisionResolver; - Importance = importance; - } - - - public bool FitsForTable(string tableName) - { - return string.Equals(tableName, ChildTable, StringComparison.InvariantCultureIgnoreCase); - } - - public bool FitsForRow(DataRowInfo row) - { - return FitsForTable(row.TableName) && (CollisionResolver == null || CollisionResolver(row)); - } - - public bool IsExternal() - { - return ParentModule != null; - } - - public bool IsSelfRelation() - { - return string.Equals(ParentTable, ChildTable, StringComparison.InvariantCultureIgnoreCase); - } - } -} \ No newline at end of file diff --git a/common/services/ASC.Data.Backup/Tasks/Data/TableInfo.cs b/common/services/ASC.Data.Backup/Tasks/Data/TableInfo.cs deleted file mode 100644 index a88f2c0b66..0000000000 --- a/common/services/ASC.Data.Backup/Tasks/Data/TableInfo.cs +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2020 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; - -namespace ASC.Data.Backup.Tasks.Data -{ - public enum InsertMethod - { - None, - Insert, - Replace, - Ignore - } - - public enum IdType - { - Autoincrement, - Guid, - Integer - } - - [DebuggerDisplay("{Name}")] - public class TableInfo - { - public string Name { get; private set; } - public string IdColumn { get; private set; } - public IdType IdType { get; private set; } - public string TenantColumn { get; private set; } - public string[] Columns { get; set; } - public string[] UserIDColumns { get; set; } - public Dictionary DateColumns { get; set; } - public InsertMethod InsertMethod { get; set; } - - public TableInfo(string name, string tenantColumn = null, string idColumn = null, IdType idType = IdType.Autoincrement) - { - Name = name; - IdColumn = idColumn; - IdType = idType; - TenantColumn = tenantColumn; - UserIDColumns = new string[0]; - DateColumns = new Dictionary(); - InsertMethod = InsertMethod.Insert; - } - - public bool HasIdColumn() - { - return !string.IsNullOrEmpty(IdColumn); - } - - public bool HasDateColumns() - { - return DateColumns.Any(); - } - - public bool HasTenantColumn() - { - return !string.IsNullOrEmpty(TenantColumn); - } - - public override string ToString() - { - return string.Format("{0} {1} [{2} ({3}), {4}]", InsertMethod, Name, IdColumn, IdType, TenantColumn); - } - } -} diff --git a/web/ASC.Web.Api/ASC.Web.Api.csproj b/web/ASC.Web.Api/ASC.Web.Api.csproj index b61ee81751..c97e4627ad 100644 --- a/web/ASC.Web.Api/ASC.Web.Api.csproj +++ b/web/ASC.Web.Api/ASC.Web.Api.csproj @@ -28,7 +28,7 @@ - + From 115d7525821a53675457405a9944f3d06f21f2c0 Mon Sep 17 00:00:00 2001 From: SuhorukovAnton Date: Tue, 31 Aug 2021 15:43:40 +0300 Subject: [PATCH 2/5] backup.core: fix --- .../Backup/ASC.Data.Backup.csproj | 30 ------- .../Backup/BackupResource.Designer.cs | 81 ------------------- .../Backup/BackupResource.resx | 67 --------------- .../Backup/Properties/launchSettings.json | 12 +-- .../ASC.Data.Backup/Backup/appsettings.json | 2 +- 5 files changed, 7 insertions(+), 185 deletions(-) delete mode 100644 common/services/ASC.Data.Backup/Backup/BackupResource.Designer.cs delete mode 100644 common/services/ASC.Data.Backup/Backup/BackupResource.resx diff --git a/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj b/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj index 9362e71336..37868998d4 100644 --- a/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj +++ b/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj @@ -12,37 +12,7 @@ none false - - - True - True - BackupResource.resx - - - - - ResXFileCodeGenerator - BackupResource.Designer.cs - - - - - - true - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - diff --git a/common/services/ASC.Data.Backup/Backup/BackupResource.Designer.cs b/common/services/ASC.Data.Backup/Backup/BackupResource.Designer.cs deleted file mode 100644 index 8ce0296779..0000000000 --- a/common/services/ASC.Data.Backup/Backup/BackupResource.Designer.cs +++ /dev/null @@ -1,81 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ASC.Data.Backup { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class BackupResource { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal BackupResource() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.Data.Backup.BackupResource", typeof(BackupResource).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to The backup file is invalid. Please, use a file created in ONLYOFFICE v11.5 or later.. - /// - internal static string BackupNotFound { - get { - return ResourceManager.GetString("BackupNotFound", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Set Password. - /// - internal static string ButtonSetPassword { - get { - return ResourceManager.GetString("ButtonSetPassword", resourceCulture); - } - } - } -} diff --git a/common/services/ASC.Data.Backup/Backup/BackupResource.resx b/common/services/ASC.Data.Backup/Backup/BackupResource.resx deleted file mode 100644 index 69c7f0c17e..0000000000 --- a/common/services/ASC.Data.Backup/Backup/BackupResource.resx +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - The backup file is invalid. Please, use a file created in ONLYOFFICE v11.5 or later. - - - Set Password - - \ No newline at end of file diff --git a/common/services/ASC.Data.Backup/Backup/Properties/launchSettings.json b/common/services/ASC.Data.Backup/Backup/Properties/launchSettings.json index 68d9288976..aa9d9d1439 100644 --- a/common/services/ASC.Data.Backup/Backup/Properties/launchSettings.json +++ b/common/services/ASC.Data.Backup/Backup/Properties/launchSettings.json @@ -5,10 +5,10 @@ "launchBrowser": false, "launchUrl": "http://localhost:5012/api/2.0/backup/backuptmp", "environmentVariables": { - "$STORAGE_ROOT": "../../../Data", + "$STORAGE_ROOT": "../../../../Data", "log__name": "backup", - "log__dir": "../../../Logs", - "core__products__folder": "../../../products", + "log__dir": "../../../../Logs", + "core__products__folder": "../../../../products", "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_URLS": "http://localhost:5012" } @@ -18,10 +18,10 @@ "launchBrowser": false, "launchUrl": "http://localhost:5012/api/2.0/backup/backuptmp", "environmentVariables": { - "$STORAGE_ROOT": "../../../Data", + "$STORAGE_ROOT": "../../../../Data", "log__name": "backup", - "log__dir": "../../../Logs", - "core__products__folder": "../../../products", + "log__dir": "../../../../Logs", + "core__products__folder": "../../../../products", "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_URLS": "http://localhost:5012" }, diff --git a/common/services/ASC.Data.Backup/Backup/appsettings.json b/common/services/ASC.Data.Backup/Backup/appsettings.json index 9bf702e310..22b605e6a5 100644 --- a/common/services/ASC.Data.Backup/Backup/appsettings.json +++ b/common/services/ASC.Data.Backup/Backup/appsettings.json @@ -1,3 +1,3 @@ { - "pathToConf": "..\\..\\..\\config" + "pathToConf": "..\\..\\..\\..\\config" } From d8654444c623d390626935af78b7de562cd7c950 Mon Sep 17 00:00:00 2001 From: SuhorukovAnton Date: Tue, 31 Aug 2021 16:59:32 +0300 Subject: [PATCH 3/5] backup.core: fix --- .../Core/Tasks/Data/DataRowInfo.cs | 106 +++++++++++++++++ .../Core/Tasks/Data/DataRowInfoReader.cs | 100 ++++++++++++++++ .../Core/Tasks/Data/RelationInfo.cs | 108 ++++++++++++++++++ .../Core/Tasks/Data/TableInfo.cs | 91 +++++++++++++++ 4 files changed, 405 insertions(+) create mode 100644 common/services/ASC.Data.Backup/Core/Tasks/Data/DataRowInfo.cs create mode 100644 common/services/ASC.Data.Backup/Core/Tasks/Data/DataRowInfoReader.cs create mode 100644 common/services/ASC.Data.Backup/Core/Tasks/Data/RelationInfo.cs create mode 100644 common/services/ASC.Data.Backup/Core/Tasks/Data/TableInfo.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Data/DataRowInfo.cs b/common/services/ASC.Data.Backup/Core/Tasks/Data/DataRowInfo.cs new file mode 100644 index 0000000000..445e94625f --- /dev/null +++ b/common/services/ASC.Data.Backup/Core/Tasks/Data/DataRowInfo.cs @@ -0,0 +1,106 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2020 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Text; + +namespace ASC.Data.Backup.Tasks.Data +{ + public class DataRowInfo + { + private readonly List _columnNames = new List(); + private readonly List _values = new List(); + + public string TableName { get; private set; } + + public IReadOnlyCollection ColumnNames + { + get { return _columnNames.AsReadOnly(); } + } + + public object this[int index] + { + get { return _values[index]; } + } + + public object this[string columnName] + { + get { return _values[GetIndex(columnName)]; } + } + + public DataRowInfo(string tableName) + { + TableName = tableName; + } + + public void SetValue(string columnName, object item) + { + var index = GetIndex(columnName); + if (index == -1) + { + _columnNames.Add(columnName); + _values.Add(item); + } + else + { + _values[index] = item; + } + } + + private int GetIndex(string columnName) + { + return _columnNames.FindIndex(name => name.Equals(columnName, StringComparison.OrdinalIgnoreCase)); + } + + public override string ToString() + { + const int maxStrLength = 150; + + var sb = new StringBuilder(maxStrLength); + + var i = 0; + while (i < _values.Count && sb.Length <= maxStrLength) + { + var strVal = Convert.ToString(_values[i]); + sb.AppendFormat("\"{0}\", ", strVal); + i++; + } + + if (sb.Length > maxStrLength + 2) + { + sb.Length = maxStrLength - 3; + sb.Append("..."); + } + else if (sb.Length > 0) + { + sb.Length -= 2; + } + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Data/DataRowInfoReader.cs b/common/services/ASC.Data.Backup/Core/Tasks/Data/DataRowInfoReader.cs new file mode 100644 index 0000000000..e1b89556c3 --- /dev/null +++ b/common/services/ASC.Data.Backup/Core/Tasks/Data/DataRowInfoReader.cs @@ -0,0 +1,100 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2020 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml; +using System.Xml.Linq; + +using ASC.Data.Backup.Extensions; + +namespace ASC.Data.Backup.Tasks.Data +{ + internal static class DataRowInfoReader + { + private const string XmlSchemaNamespace = "http://www.w3.org/2001/XMLSchema"; + + public static IEnumerable ReadFromStream(Stream stream) + { + var readerSettings = new XmlReaderSettings + { + CheckCharacters = false, + CloseInput = false + }; + + using var xmlReader = XmlReader.Create(stream, readerSettings); + xmlReader.MoveToContent(); + xmlReader.ReadToFollowing("schema", XmlSchemaNamespace); + + var schema = new Dictionary(); + + if (XNode.ReadFrom(xmlReader) is XElement schemaElement) + { + foreach (var entry in schemaElement.Descendants(XName.Get("sequence", XmlSchemaNamespace)).Single().Elements(XName.Get("element", XmlSchemaNamespace))) + { + schema.Add(entry.Attribute("name").ValueOrDefault(), entry.Attribute("type").ValueOrDefault()); + } + } + + while (xmlReader.Read()) + { + if (xmlReader.NodeType == XmlNodeType.Element) + { + if (XNode.ReadFrom(xmlReader) is XElement el) + { + var dataRowInfo = new DataRowInfo(el.Name.LocalName); + foreach (var column in schema) + { + var value = ConvertToType(el.Element(column.Key).ValueOrDefault(), column.Value); + dataRowInfo.SetValue(column.Key, value); + } + + yield return dataRowInfo; + } + } + } + } + + private static object ConvertToType(string str, string schemaType) + { + if (str == null) + { + return null; + } + if (schemaType == "xs:boolean") + { + return Convert.ToBoolean(str); + } + if (schemaType == "xs:base64Binary") + { + return Convert.FromBase64String(str); + } + return str; + } + } +} \ No newline at end of file diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Data/RelationInfo.cs b/common/services/ASC.Data.Backup/Core/Tasks/Data/RelationInfo.cs new file mode 100644 index 0000000000..3fd793804b --- /dev/null +++ b/common/services/ASC.Data.Backup/Core/Tasks/Data/RelationInfo.cs @@ -0,0 +1,108 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2020 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Diagnostics; + +namespace ASC.Data.Backup.Tasks.Data +{ + public enum RelationImportance + { + Low, + Normal + } + + [DebuggerDisplay("({ParentTable},{ParentColumn})->({ChildTable},{ChildColumn})")] + public class RelationInfo + { + public string ParentTable { get; private set; } + public string ParentColumn { get; private set; } + public string ChildTable { get; private set; } + public string ChildColumn { get; private set; } + + public Type ParentModule { get; private set; } + public RelationImportance Importance { get; private set; } + + public Func CollisionResolver { get; private set; } + + + public RelationInfo(string parentTable, string parentColumn, string childTable, string childColumn) + : this(parentTable, parentColumn, childTable, childColumn, null, null) + { + + } + + public RelationInfo(string parentTable, string parentColumn, string childTable, string childColumn, Func collisionResolver) + : this(parentTable, parentColumn, childTable, childColumn, null, collisionResolver) + { + + } + + public RelationInfo(string parentTable, string parentColumn, string childTable, string childColumn, Type parentModule) + : this(parentTable, parentColumn, childTable, childColumn, parentModule, null) + { + + } + + public RelationInfo(string parentTable, string parentColumn, string childTable, string childColumn, Type parentModule, Func collisionResolver) + : this(parentTable, parentColumn, childTable, childColumn, parentModule, collisionResolver, RelationImportance.Normal) + { + + } + + public RelationInfo(string parentTable, string parentColumn, string childTable, string childColumn, Type parentModule, Func collisionResolver, RelationImportance importance) + { + ParentTable = parentTable; + ParentColumn = parentColumn; + ChildTable = childTable; + ChildColumn = childColumn; + ParentModule = parentModule; + CollisionResolver = collisionResolver; + Importance = importance; + } + + + public bool FitsForTable(string tableName) + { + return string.Equals(tableName, ChildTable, StringComparison.InvariantCultureIgnoreCase); + } + + public bool FitsForRow(DataRowInfo row) + { + return FitsForTable(row.TableName) && (CollisionResolver == null || CollisionResolver(row)); + } + + public bool IsExternal() + { + return ParentModule != null; + } + + public bool IsSelfRelation() + { + return string.Equals(ParentTable, ChildTable, StringComparison.InvariantCultureIgnoreCase); + } + } +} \ No newline at end of file diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Data/TableInfo.cs b/common/services/ASC.Data.Backup/Core/Tasks/Data/TableInfo.cs new file mode 100644 index 0000000000..3eacb6f69f --- /dev/null +++ b/common/services/ASC.Data.Backup/Core/Tasks/Data/TableInfo.cs @@ -0,0 +1,91 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2020 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +namespace ASC.Data.Backup.Tasks.Data +{ + public enum InsertMethod + { + None, + Insert, + Replace, + Ignore + } + + public enum IdType + { + Autoincrement, + Guid, + Integer + } + + [DebuggerDisplay("{Name}")] + public class TableInfo + { + public string Name { get; private set; } + public string IdColumn { get; private set; } + public IdType IdType { get; private set; } + public string TenantColumn { get; private set; } + public string[] Columns { get; set; } + public string[] UserIDColumns { get; set; } + public Dictionary DateColumns { get; set; } + public InsertMethod InsertMethod { get; set; } + + public TableInfo(string name, string tenantColumn = null, string idColumn = null, IdType idType = IdType.Autoincrement) + { + Name = name; + IdColumn = idColumn; + IdType = idType; + TenantColumn = tenantColumn; + UserIDColumns = new string[0]; + DateColumns = new Dictionary(); + InsertMethod = InsertMethod.Insert; + } + + public bool HasIdColumn() + { + return !string.IsNullOrEmpty(IdColumn); + } + + public bool HasDateColumns() + { + return DateColumns.Any(); + } + + public bool HasTenantColumn() + { + return !string.IsNullOrEmpty(TenantColumn); + } + + public override string ToString() + { + return string.Format("{0} {1} [{2} ({3}), {4}]", InsertMethod, Name, IdColumn, IdType, TenantColumn); + } + } +} \ No newline at end of file From 81715639652e1b32f771ca0f0ceca8e08b4cd6a5 Mon Sep 17 00:00:00 2001 From: SuhorukovAnton Date: Thu, 2 Sep 2021 15:41:54 +0300 Subject: [PATCH 4/5] backup.core: move backup.core --- ASC.Web.sln | 20 +++++++------- .../ASC.Data.Backup.Core.csproj | 9 ++++--- .../ActionInvoker.cs | 0 .../BackupAjaxHandler.cs | 0 .../BackupFileUploadHandler.cs | 0 .../BackupResource.Designer.cs | 0 .../BackupResource.resx | 0 .../Contracts/BackupServiceModel.cs | 0 .../Contracts/IBackupService.cs | 0 .../Core/DbBackupProvider.cs | 0 .../Core/DbHelper.cs | 0 .../Core/FileBackupProvider.cs | 0 .../Core/IBackupProvider.cs | 0 .../Core/IDataOperator.cs | 0 .../Core/NotifyHelper.cs | 0 .../Core/Schedule.cs | 0 .../Core/ZipOperator.cs | 0 .../EF/BackupRecord.cs | 0 .../EF/BackupSchedule.cs | 0 .../EF/BackupsContext.cs | 0 .../Exceptions/DbBackupException.cs | 0 .../Exceptions/ThrowHelper.cs | 0 .../Extensions/DataExtensions.cs | 0 .../Extensions/EnumerableExtensions.cs | 0 .../Extensions/XmlExtensions.cs | 0 .../Listerners/BackupListener.cs | 0 .../Service/BackupService.cs | 0 .../Service/BackupSettings.cs | 0 .../Service/BackupWorker.cs | 0 .../Storage/BackupRepository.cs | 0 .../Storage/BackupStorageFactory.cs | 0 .../Storage/ConsumerBackupStorage.cs | 0 .../Storage/DataStoreBackupStorage.cs | 0 .../Storage/DocumentsBackupStorage.cs | 0 .../Storage/IBackupRepository.cs | 0 .../Storage/IBackupStorage.cs | 0 .../Storage/LocalBackupStorage.cs | 0 .../Storage/S3BackupStorage.cs | 0 .../Tasks/BackupFileInfo.cs | 0 .../Tasks/BackupPortalTask.cs | 0 .../Tasks/ColumnMapper.cs | 0 .../Tasks/Data/DataRowInfo.cs | 0 .../Tasks/Data/DataRowInfoReader.cs | 0 .../Tasks/Data/RelationInfo.cs | 0 .../Tasks/Data/TableInfo.cs | 0 .../Tasks/DbFactory.cs | 0 .../Tasks/DeletePortalTask.cs | 0 .../Tasks/KeyHelper.cs | 0 .../Tasks/Modules/AuditModuleSpecifics.cs | 0 .../Tasks/Modules/CalendarModuleSpecifics.cs | 0 .../Tasks/Modules/CommunityModuleSpecifics.cs | 0 .../Tasks/Modules/CoreModuleSpecifics.cs | 0 .../Tasks/Modules/CrmModuleSpecifics.cs | 0 .../Tasks/Modules/FilesModuleSpecifics.cs | 0 .../Tasks/Modules/Helpers.cs | 0 .../Tasks/Modules/IModuleSpecifics.cs | 0 .../Tasks/Modules/MailModuleSpecifics.cs | 0 .../Tasks/Modules/ModuleProvider.cs | 0 .../Tasks/Modules/ModuleSpecificsBase.cs | 0 .../Tasks/Modules/ProjectsModuleSpecifics.cs | 0 .../Tasks/Modules/TenantsModuleSpecifics.cs | 0 .../Tasks/Modules/WebStudioModuleSpecifics.cs | 0 .../Tasks/PortalTaskBase.cs | 0 .../Tasks/RestoreDbModuleTask.cs | 0 .../Tasks/RestorePortalTask.cs | 0 .../Tasks/TransferPortalTask.cs | 0 .../Utils/ConfigurationProvider.cs | 0 .../Utils/FCKEditorPathUtility.cs | 0 .../Utils/PathHelper.cs | 0 .../protos/BackupProgress.proto | 0 .../protos/DeleteSchedule.proto | 0 .../ASC.Data.Backup/ASC.Data.Backup.csproj | 27 +++++++++++++++++++ .../Backup/ASC.Data.Backup.csproj | 3 --- .../ASC.Data.Backup/Backup/appsettings.json | 3 --- .../{Backup => }/BackupCleanerService.cs | 0 .../{Backup => }/BackupSchedulerService.cs | 0 .../{Backup => }/BackupServiceLauncher.cs | 0 .../Controllers/BackupController.cs | 0 .../{Backup => }/ModelApi/Backup.cs | 0 .../{Backup => }/ModelApi/BackupRestore.cs | 0 .../{Backup => }/ModelApi/BackupSchedule.cs | 0 .../ASC.Data.Backup/{Backup => }/Program.cs | 0 .../Properties/launchSettings.json | 12 ++++----- .../ASC.Data.Backup/{Backup => }/Startup.cs | 0 .../services/ASC.Data.Backup/appsettings.json | 3 +++ web/ASC.Web.Api/ASC.Web.Api.csproj | 2 +- 86 files changed, 52 insertions(+), 27 deletions(-) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/ASC.Data.Backup.Core.csproj (91%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/ActionInvoker.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/BackupAjaxHandler.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/BackupFileUploadHandler.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/BackupResource.Designer.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/BackupResource.resx (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Contracts/BackupServiceModel.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Contracts/IBackupService.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Core/DbBackupProvider.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Core/DbHelper.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Core/FileBackupProvider.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Core/IBackupProvider.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Core/IDataOperator.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Core/NotifyHelper.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Core/Schedule.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Core/ZipOperator.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/EF/BackupRecord.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/EF/BackupSchedule.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/EF/BackupsContext.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Exceptions/DbBackupException.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Exceptions/ThrowHelper.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Extensions/DataExtensions.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Extensions/EnumerableExtensions.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Extensions/XmlExtensions.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Listerners/BackupListener.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Service/BackupService.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Service/BackupSettings.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Service/BackupWorker.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Storage/BackupRepository.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Storage/BackupStorageFactory.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Storage/ConsumerBackupStorage.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Storage/DataStoreBackupStorage.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Storage/DocumentsBackupStorage.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Storage/IBackupRepository.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Storage/IBackupStorage.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Storage/LocalBackupStorage.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Storage/S3BackupStorage.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/BackupFileInfo.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/BackupPortalTask.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/ColumnMapper.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Data/DataRowInfo.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Data/DataRowInfoReader.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Data/RelationInfo.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Data/TableInfo.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/DbFactory.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/DeletePortalTask.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/KeyHelper.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/AuditModuleSpecifics.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/CalendarModuleSpecifics.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/CommunityModuleSpecifics.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/CoreModuleSpecifics.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/CrmModuleSpecifics.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/FilesModuleSpecifics.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/Helpers.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/IModuleSpecifics.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/MailModuleSpecifics.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/ModuleProvider.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/ModuleSpecificsBase.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/ProjectsModuleSpecifics.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/TenantsModuleSpecifics.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/Modules/WebStudioModuleSpecifics.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/PortalTaskBase.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/RestoreDbModuleTask.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/RestorePortalTask.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Tasks/TransferPortalTask.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Utils/ConfigurationProvider.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Utils/FCKEditorPathUtility.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/Utils/PathHelper.cs (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/protos/BackupProgress.proto (100%) rename common/{services/ASC.Data.Backup/Core => ASC.Data.Backup.Core}/protos/DeleteSchedule.proto (100%) create mode 100644 common/services/ASC.Data.Backup/ASC.Data.Backup.csproj delete mode 100644 common/services/ASC.Data.Backup/Backup/appsettings.json rename common/services/ASC.Data.Backup/{Backup => }/BackupCleanerService.cs (100%) rename common/services/ASC.Data.Backup/{Backup => }/BackupSchedulerService.cs (100%) rename common/services/ASC.Data.Backup/{Backup => }/BackupServiceLauncher.cs (100%) rename common/services/ASC.Data.Backup/{Backup => }/Controllers/BackupController.cs (100%) rename common/services/ASC.Data.Backup/{Backup => }/ModelApi/Backup.cs (100%) rename common/services/ASC.Data.Backup/{Backup => }/ModelApi/BackupRestore.cs (100%) rename common/services/ASC.Data.Backup/{Backup => }/ModelApi/BackupSchedule.cs (100%) rename common/services/ASC.Data.Backup/{Backup => }/Program.cs (100%) rename common/services/ASC.Data.Backup/{Backup => }/Properties/launchSettings.json (72%) rename common/services/ASC.Data.Backup/{Backup => }/Startup.cs (100%) create mode 100644 common/services/ASC.Data.Backup/appsettings.json diff --git a/ASC.Web.sln b/ASC.Web.sln index 46323af2eb..cfbf50017b 100644 --- a/ASC.Web.sln +++ b/ASC.Web.sln @@ -93,9 +93,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.ClearEvents", "common\s EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.CRM.BackgroundTasks", "products\ASC.CRM\BackgroundTasks\ASC.CRM.BackgroundTasks.csproj", "{E52C0E35-A05C-437F-8FF2-3E0AC9F81433}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Backup", "common\services\ASC.Data.Backup\Backup\ASC.Data.Backup.csproj", "{F5CD54D4-E66F-461C-96E2-B617E3324E42}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Backup.Core", "common\ASC.Data.Backup.Core\ASC.Data.Backup.Core.csproj", "{F5D9DE01-06CD-4881-9F41-46882E9ED45C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Backup.Core", "common\services\ASC.Data.Backup\Core\ASC.Data.Backup.Core.csproj", "{45117C68-5197-4AFF-9FC1-1E86E718B727}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Backup", "common\services\ASC.Data.Backup\ASC.Data.Backup.csproj", "{027EEE53-7491-48F4-B467-6404D68798A7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -267,14 +267,14 @@ Global {E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Debug|Any CPU.Build.0 = Debug|Any CPU {E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Release|Any CPU.ActiveCfg = Release|Any CPU {E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Release|Any CPU.Build.0 = Release|Any CPU - {F5CD54D4-E66F-461C-96E2-B617E3324E42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F5CD54D4-E66F-461C-96E2-B617E3324E42}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F5CD54D4-E66F-461C-96E2-B617E3324E42}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F5CD54D4-E66F-461C-96E2-B617E3324E42}.Release|Any CPU.Build.0 = Release|Any CPU - {45117C68-5197-4AFF-9FC1-1E86E718B727}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {45117C68-5197-4AFF-9FC1-1E86E718B727}.Debug|Any CPU.Build.0 = Debug|Any CPU - {45117C68-5197-4AFF-9FC1-1E86E718B727}.Release|Any CPU.ActiveCfg = Release|Any CPU - {45117C68-5197-4AFF-9FC1-1E86E718B727}.Release|Any CPU.Build.0 = Release|Any CPU + {F5D9DE01-06CD-4881-9F41-46882E9ED45C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F5D9DE01-06CD-4881-9F41-46882E9ED45C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F5D9DE01-06CD-4881-9F41-46882E9ED45C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F5D9DE01-06CD-4881-9F41-46882E9ED45C}.Release|Any CPU.Build.0 = Release|Any CPU + {027EEE53-7491-48F4-B467-6404D68798A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {027EEE53-7491-48F4-B467-6404D68798A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {027EEE53-7491-48F4-B467-6404D68798A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {027EEE53-7491-48F4-B467-6404D68798A7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/common/services/ASC.Data.Backup/Core/ASC.Data.Backup.Core.csproj b/common/ASC.Data.Backup.Core/ASC.Data.Backup.Core.csproj similarity index 91% rename from common/services/ASC.Data.Backup/Core/ASC.Data.Backup.Core.csproj rename to common/ASC.Data.Backup.Core/ASC.Data.Backup.Core.csproj index cadb700249..10431c607f 100644 --- a/common/services/ASC.Data.Backup/Core/ASC.Data.Backup.Core.csproj +++ b/common/ASC.Data.Backup.Core/ASC.Data.Backup.Core.csproj @@ -11,10 +11,6 @@ - - - - @@ -32,6 +28,11 @@ + + + + + diff --git a/common/services/ASC.Data.Backup/Core/ActionInvoker.cs b/common/ASC.Data.Backup.Core/ActionInvoker.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/ActionInvoker.cs rename to common/ASC.Data.Backup.Core/ActionInvoker.cs diff --git a/common/services/ASC.Data.Backup/Core/BackupAjaxHandler.cs b/common/ASC.Data.Backup.Core/BackupAjaxHandler.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/BackupAjaxHandler.cs rename to common/ASC.Data.Backup.Core/BackupAjaxHandler.cs diff --git a/common/services/ASC.Data.Backup/Core/BackupFileUploadHandler.cs b/common/ASC.Data.Backup.Core/BackupFileUploadHandler.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/BackupFileUploadHandler.cs rename to common/ASC.Data.Backup.Core/BackupFileUploadHandler.cs diff --git a/common/services/ASC.Data.Backup/Core/BackupResource.Designer.cs b/common/ASC.Data.Backup.Core/BackupResource.Designer.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/BackupResource.Designer.cs rename to common/ASC.Data.Backup.Core/BackupResource.Designer.cs diff --git a/common/services/ASC.Data.Backup/Core/BackupResource.resx b/common/ASC.Data.Backup.Core/BackupResource.resx similarity index 100% rename from common/services/ASC.Data.Backup/Core/BackupResource.resx rename to common/ASC.Data.Backup.Core/BackupResource.resx diff --git a/common/services/ASC.Data.Backup/Core/Contracts/BackupServiceModel.cs b/common/ASC.Data.Backup.Core/Contracts/BackupServiceModel.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Contracts/BackupServiceModel.cs rename to common/ASC.Data.Backup.Core/Contracts/BackupServiceModel.cs diff --git a/common/services/ASC.Data.Backup/Core/Contracts/IBackupService.cs b/common/ASC.Data.Backup.Core/Contracts/IBackupService.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Contracts/IBackupService.cs rename to common/ASC.Data.Backup.Core/Contracts/IBackupService.cs diff --git a/common/services/ASC.Data.Backup/Core/Core/DbBackupProvider.cs b/common/ASC.Data.Backup.Core/Core/DbBackupProvider.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Core/DbBackupProvider.cs rename to common/ASC.Data.Backup.Core/Core/DbBackupProvider.cs diff --git a/common/services/ASC.Data.Backup/Core/Core/DbHelper.cs b/common/ASC.Data.Backup.Core/Core/DbHelper.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Core/DbHelper.cs rename to common/ASC.Data.Backup.Core/Core/DbHelper.cs diff --git a/common/services/ASC.Data.Backup/Core/Core/FileBackupProvider.cs b/common/ASC.Data.Backup.Core/Core/FileBackupProvider.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Core/FileBackupProvider.cs rename to common/ASC.Data.Backup.Core/Core/FileBackupProvider.cs diff --git a/common/services/ASC.Data.Backup/Core/Core/IBackupProvider.cs b/common/ASC.Data.Backup.Core/Core/IBackupProvider.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Core/IBackupProvider.cs rename to common/ASC.Data.Backup.Core/Core/IBackupProvider.cs diff --git a/common/services/ASC.Data.Backup/Core/Core/IDataOperator.cs b/common/ASC.Data.Backup.Core/Core/IDataOperator.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Core/IDataOperator.cs rename to common/ASC.Data.Backup.Core/Core/IDataOperator.cs diff --git a/common/services/ASC.Data.Backup/Core/Core/NotifyHelper.cs b/common/ASC.Data.Backup.Core/Core/NotifyHelper.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Core/NotifyHelper.cs rename to common/ASC.Data.Backup.Core/Core/NotifyHelper.cs diff --git a/common/services/ASC.Data.Backup/Core/Core/Schedule.cs b/common/ASC.Data.Backup.Core/Core/Schedule.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Core/Schedule.cs rename to common/ASC.Data.Backup.Core/Core/Schedule.cs diff --git a/common/services/ASC.Data.Backup/Core/Core/ZipOperator.cs b/common/ASC.Data.Backup.Core/Core/ZipOperator.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Core/ZipOperator.cs rename to common/ASC.Data.Backup.Core/Core/ZipOperator.cs diff --git a/common/services/ASC.Data.Backup/Core/EF/BackupRecord.cs b/common/ASC.Data.Backup.Core/EF/BackupRecord.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/EF/BackupRecord.cs rename to common/ASC.Data.Backup.Core/EF/BackupRecord.cs diff --git a/common/services/ASC.Data.Backup/Core/EF/BackupSchedule.cs b/common/ASC.Data.Backup.Core/EF/BackupSchedule.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/EF/BackupSchedule.cs rename to common/ASC.Data.Backup.Core/EF/BackupSchedule.cs diff --git a/common/services/ASC.Data.Backup/Core/EF/BackupsContext.cs b/common/ASC.Data.Backup.Core/EF/BackupsContext.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/EF/BackupsContext.cs rename to common/ASC.Data.Backup.Core/EF/BackupsContext.cs diff --git a/common/services/ASC.Data.Backup/Core/Exceptions/DbBackupException.cs b/common/ASC.Data.Backup.Core/Exceptions/DbBackupException.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Exceptions/DbBackupException.cs rename to common/ASC.Data.Backup.Core/Exceptions/DbBackupException.cs diff --git a/common/services/ASC.Data.Backup/Core/Exceptions/ThrowHelper.cs b/common/ASC.Data.Backup.Core/Exceptions/ThrowHelper.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Exceptions/ThrowHelper.cs rename to common/ASC.Data.Backup.Core/Exceptions/ThrowHelper.cs diff --git a/common/services/ASC.Data.Backup/Core/Extensions/DataExtensions.cs b/common/ASC.Data.Backup.Core/Extensions/DataExtensions.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Extensions/DataExtensions.cs rename to common/ASC.Data.Backup.Core/Extensions/DataExtensions.cs diff --git a/common/services/ASC.Data.Backup/Core/Extensions/EnumerableExtensions.cs b/common/ASC.Data.Backup.Core/Extensions/EnumerableExtensions.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Extensions/EnumerableExtensions.cs rename to common/ASC.Data.Backup.Core/Extensions/EnumerableExtensions.cs diff --git a/common/services/ASC.Data.Backup/Core/Extensions/XmlExtensions.cs b/common/ASC.Data.Backup.Core/Extensions/XmlExtensions.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Extensions/XmlExtensions.cs rename to common/ASC.Data.Backup.Core/Extensions/XmlExtensions.cs diff --git a/common/services/ASC.Data.Backup/Core/Listerners/BackupListener.cs b/common/ASC.Data.Backup.Core/Listerners/BackupListener.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Listerners/BackupListener.cs rename to common/ASC.Data.Backup.Core/Listerners/BackupListener.cs diff --git a/common/services/ASC.Data.Backup/Core/Service/BackupService.cs b/common/ASC.Data.Backup.Core/Service/BackupService.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Service/BackupService.cs rename to common/ASC.Data.Backup.Core/Service/BackupService.cs diff --git a/common/services/ASC.Data.Backup/Core/Service/BackupSettings.cs b/common/ASC.Data.Backup.Core/Service/BackupSettings.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Service/BackupSettings.cs rename to common/ASC.Data.Backup.Core/Service/BackupSettings.cs diff --git a/common/services/ASC.Data.Backup/Core/Service/BackupWorker.cs b/common/ASC.Data.Backup.Core/Service/BackupWorker.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Service/BackupWorker.cs rename to common/ASC.Data.Backup.Core/Service/BackupWorker.cs diff --git a/common/services/ASC.Data.Backup/Core/Storage/BackupRepository.cs b/common/ASC.Data.Backup.Core/Storage/BackupRepository.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Storage/BackupRepository.cs rename to common/ASC.Data.Backup.Core/Storage/BackupRepository.cs diff --git a/common/services/ASC.Data.Backup/Core/Storage/BackupStorageFactory.cs b/common/ASC.Data.Backup.Core/Storage/BackupStorageFactory.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Storage/BackupStorageFactory.cs rename to common/ASC.Data.Backup.Core/Storage/BackupStorageFactory.cs diff --git a/common/services/ASC.Data.Backup/Core/Storage/ConsumerBackupStorage.cs b/common/ASC.Data.Backup.Core/Storage/ConsumerBackupStorage.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Storage/ConsumerBackupStorage.cs rename to common/ASC.Data.Backup.Core/Storage/ConsumerBackupStorage.cs diff --git a/common/services/ASC.Data.Backup/Core/Storage/DataStoreBackupStorage.cs b/common/ASC.Data.Backup.Core/Storage/DataStoreBackupStorage.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Storage/DataStoreBackupStorage.cs rename to common/ASC.Data.Backup.Core/Storage/DataStoreBackupStorage.cs diff --git a/common/services/ASC.Data.Backup/Core/Storage/DocumentsBackupStorage.cs b/common/ASC.Data.Backup.Core/Storage/DocumentsBackupStorage.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Storage/DocumentsBackupStorage.cs rename to common/ASC.Data.Backup.Core/Storage/DocumentsBackupStorage.cs diff --git a/common/services/ASC.Data.Backup/Core/Storage/IBackupRepository.cs b/common/ASC.Data.Backup.Core/Storage/IBackupRepository.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Storage/IBackupRepository.cs rename to common/ASC.Data.Backup.Core/Storage/IBackupRepository.cs diff --git a/common/services/ASC.Data.Backup/Core/Storage/IBackupStorage.cs b/common/ASC.Data.Backup.Core/Storage/IBackupStorage.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Storage/IBackupStorage.cs rename to common/ASC.Data.Backup.Core/Storage/IBackupStorage.cs diff --git a/common/services/ASC.Data.Backup/Core/Storage/LocalBackupStorage.cs b/common/ASC.Data.Backup.Core/Storage/LocalBackupStorage.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Storage/LocalBackupStorage.cs rename to common/ASC.Data.Backup.Core/Storage/LocalBackupStorage.cs diff --git a/common/services/ASC.Data.Backup/Core/Storage/S3BackupStorage.cs b/common/ASC.Data.Backup.Core/Storage/S3BackupStorage.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Storage/S3BackupStorage.cs rename to common/ASC.Data.Backup.Core/Storage/S3BackupStorage.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/BackupFileInfo.cs b/common/ASC.Data.Backup.Core/Tasks/BackupFileInfo.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/BackupFileInfo.cs rename to common/ASC.Data.Backup.Core/Tasks/BackupFileInfo.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/BackupPortalTask.cs b/common/ASC.Data.Backup.Core/Tasks/BackupPortalTask.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/BackupPortalTask.cs rename to common/ASC.Data.Backup.Core/Tasks/BackupPortalTask.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/ColumnMapper.cs b/common/ASC.Data.Backup.Core/Tasks/ColumnMapper.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/ColumnMapper.cs rename to common/ASC.Data.Backup.Core/Tasks/ColumnMapper.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Data/DataRowInfo.cs b/common/ASC.Data.Backup.Core/Tasks/Data/DataRowInfo.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Data/DataRowInfo.cs rename to common/ASC.Data.Backup.Core/Tasks/Data/DataRowInfo.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Data/DataRowInfoReader.cs b/common/ASC.Data.Backup.Core/Tasks/Data/DataRowInfoReader.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Data/DataRowInfoReader.cs rename to common/ASC.Data.Backup.Core/Tasks/Data/DataRowInfoReader.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Data/RelationInfo.cs b/common/ASC.Data.Backup.Core/Tasks/Data/RelationInfo.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Data/RelationInfo.cs rename to common/ASC.Data.Backup.Core/Tasks/Data/RelationInfo.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Data/TableInfo.cs b/common/ASC.Data.Backup.Core/Tasks/Data/TableInfo.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Data/TableInfo.cs rename to common/ASC.Data.Backup.Core/Tasks/Data/TableInfo.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/DbFactory.cs b/common/ASC.Data.Backup.Core/Tasks/DbFactory.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/DbFactory.cs rename to common/ASC.Data.Backup.Core/Tasks/DbFactory.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/DeletePortalTask.cs b/common/ASC.Data.Backup.Core/Tasks/DeletePortalTask.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/DeletePortalTask.cs rename to common/ASC.Data.Backup.Core/Tasks/DeletePortalTask.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/KeyHelper.cs b/common/ASC.Data.Backup.Core/Tasks/KeyHelper.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/KeyHelper.cs rename to common/ASC.Data.Backup.Core/Tasks/KeyHelper.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/AuditModuleSpecifics.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/AuditModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/AuditModuleSpecifics.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/AuditModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/CalendarModuleSpecifics.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/CalendarModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/CalendarModuleSpecifics.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/CalendarModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/CommunityModuleSpecifics.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/CommunityModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/CommunityModuleSpecifics.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/CommunityModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/CoreModuleSpecifics.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/CoreModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/CoreModuleSpecifics.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/CoreModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/CrmModuleSpecifics.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/CrmModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/CrmModuleSpecifics.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/CrmModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/FilesModuleSpecifics.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/FilesModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/FilesModuleSpecifics.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/FilesModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/Helpers.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/Helpers.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/Helpers.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/Helpers.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/IModuleSpecifics.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/IModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/IModuleSpecifics.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/IModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/MailModuleSpecifics.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/MailModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/MailModuleSpecifics.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/MailModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/ModuleProvider.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/ModuleProvider.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/ModuleProvider.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/ModuleProvider.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/ModuleSpecificsBase.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/ModuleSpecificsBase.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/ModuleSpecificsBase.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/ModuleSpecificsBase.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/ProjectsModuleSpecifics.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/ProjectsModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/ProjectsModuleSpecifics.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/ProjectsModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/TenantsModuleSpecifics.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/TenantsModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/TenantsModuleSpecifics.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/TenantsModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/Modules/WebStudioModuleSpecifics.cs b/common/ASC.Data.Backup.Core/Tasks/Modules/WebStudioModuleSpecifics.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/Modules/WebStudioModuleSpecifics.cs rename to common/ASC.Data.Backup.Core/Tasks/Modules/WebStudioModuleSpecifics.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/PortalTaskBase.cs b/common/ASC.Data.Backup.Core/Tasks/PortalTaskBase.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/PortalTaskBase.cs rename to common/ASC.Data.Backup.Core/Tasks/PortalTaskBase.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/RestoreDbModuleTask.cs b/common/ASC.Data.Backup.Core/Tasks/RestoreDbModuleTask.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/RestoreDbModuleTask.cs rename to common/ASC.Data.Backup.Core/Tasks/RestoreDbModuleTask.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/RestorePortalTask.cs b/common/ASC.Data.Backup.Core/Tasks/RestorePortalTask.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/RestorePortalTask.cs rename to common/ASC.Data.Backup.Core/Tasks/RestorePortalTask.cs diff --git a/common/services/ASC.Data.Backup/Core/Tasks/TransferPortalTask.cs b/common/ASC.Data.Backup.Core/Tasks/TransferPortalTask.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Tasks/TransferPortalTask.cs rename to common/ASC.Data.Backup.Core/Tasks/TransferPortalTask.cs diff --git a/common/services/ASC.Data.Backup/Core/Utils/ConfigurationProvider.cs b/common/ASC.Data.Backup.Core/Utils/ConfigurationProvider.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Utils/ConfigurationProvider.cs rename to common/ASC.Data.Backup.Core/Utils/ConfigurationProvider.cs diff --git a/common/services/ASC.Data.Backup/Core/Utils/FCKEditorPathUtility.cs b/common/ASC.Data.Backup.Core/Utils/FCKEditorPathUtility.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Utils/FCKEditorPathUtility.cs rename to common/ASC.Data.Backup.Core/Utils/FCKEditorPathUtility.cs diff --git a/common/services/ASC.Data.Backup/Core/Utils/PathHelper.cs b/common/ASC.Data.Backup.Core/Utils/PathHelper.cs similarity index 100% rename from common/services/ASC.Data.Backup/Core/Utils/PathHelper.cs rename to common/ASC.Data.Backup.Core/Utils/PathHelper.cs diff --git a/common/services/ASC.Data.Backup/Core/protos/BackupProgress.proto b/common/ASC.Data.Backup.Core/protos/BackupProgress.proto similarity index 100% rename from common/services/ASC.Data.Backup/Core/protos/BackupProgress.proto rename to common/ASC.Data.Backup.Core/protos/BackupProgress.proto diff --git a/common/services/ASC.Data.Backup/Core/protos/DeleteSchedule.proto b/common/ASC.Data.Backup.Core/protos/DeleteSchedule.proto similarity index 100% rename from common/services/ASC.Data.Backup/Core/protos/DeleteSchedule.proto rename to common/ASC.Data.Backup.Core/protos/DeleteSchedule.proto diff --git a/common/services/ASC.Data.Backup/ASC.Data.Backup.csproj b/common/services/ASC.Data.Backup/ASC.Data.Backup.csproj new file mode 100644 index 0000000000..68e28a90b0 --- /dev/null +++ b/common/services/ASC.Data.Backup/ASC.Data.Backup.csproj @@ -0,0 +1,27 @@ + + + + net5.0 + + Exe + false + false + + + + none + false + + + + + MySqlConnectorAlias + + + + + + + + + diff --git a/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj b/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj index 37868998d4..2b343032cd 100644 --- a/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj +++ b/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj @@ -12,9 +12,6 @@ none false - - - diff --git a/common/services/ASC.Data.Backup/Backup/appsettings.json b/common/services/ASC.Data.Backup/Backup/appsettings.json deleted file mode 100644 index 22b605e6a5..0000000000 --- a/common/services/ASC.Data.Backup/Backup/appsettings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "pathToConf": "..\\..\\..\\..\\config" -} diff --git a/common/services/ASC.Data.Backup/Backup/BackupCleanerService.cs b/common/services/ASC.Data.Backup/BackupCleanerService.cs similarity index 100% rename from common/services/ASC.Data.Backup/Backup/BackupCleanerService.cs rename to common/services/ASC.Data.Backup/BackupCleanerService.cs diff --git a/common/services/ASC.Data.Backup/Backup/BackupSchedulerService.cs b/common/services/ASC.Data.Backup/BackupSchedulerService.cs similarity index 100% rename from common/services/ASC.Data.Backup/Backup/BackupSchedulerService.cs rename to common/services/ASC.Data.Backup/BackupSchedulerService.cs diff --git a/common/services/ASC.Data.Backup/Backup/BackupServiceLauncher.cs b/common/services/ASC.Data.Backup/BackupServiceLauncher.cs similarity index 100% rename from common/services/ASC.Data.Backup/Backup/BackupServiceLauncher.cs rename to common/services/ASC.Data.Backup/BackupServiceLauncher.cs diff --git a/common/services/ASC.Data.Backup/Backup/Controllers/BackupController.cs b/common/services/ASC.Data.Backup/Controllers/BackupController.cs similarity index 100% rename from common/services/ASC.Data.Backup/Backup/Controllers/BackupController.cs rename to common/services/ASC.Data.Backup/Controllers/BackupController.cs diff --git a/common/services/ASC.Data.Backup/Backup/ModelApi/Backup.cs b/common/services/ASC.Data.Backup/ModelApi/Backup.cs similarity index 100% rename from common/services/ASC.Data.Backup/Backup/ModelApi/Backup.cs rename to common/services/ASC.Data.Backup/ModelApi/Backup.cs diff --git a/common/services/ASC.Data.Backup/Backup/ModelApi/BackupRestore.cs b/common/services/ASC.Data.Backup/ModelApi/BackupRestore.cs similarity index 100% rename from common/services/ASC.Data.Backup/Backup/ModelApi/BackupRestore.cs rename to common/services/ASC.Data.Backup/ModelApi/BackupRestore.cs diff --git a/common/services/ASC.Data.Backup/Backup/ModelApi/BackupSchedule.cs b/common/services/ASC.Data.Backup/ModelApi/BackupSchedule.cs similarity index 100% rename from common/services/ASC.Data.Backup/Backup/ModelApi/BackupSchedule.cs rename to common/services/ASC.Data.Backup/ModelApi/BackupSchedule.cs diff --git a/common/services/ASC.Data.Backup/Backup/Program.cs b/common/services/ASC.Data.Backup/Program.cs similarity index 100% rename from common/services/ASC.Data.Backup/Backup/Program.cs rename to common/services/ASC.Data.Backup/Program.cs diff --git a/common/services/ASC.Data.Backup/Backup/Properties/launchSettings.json b/common/services/ASC.Data.Backup/Properties/launchSettings.json similarity index 72% rename from common/services/ASC.Data.Backup/Backup/Properties/launchSettings.json rename to common/services/ASC.Data.Backup/Properties/launchSettings.json index aa9d9d1439..68d9288976 100644 --- a/common/services/ASC.Data.Backup/Backup/Properties/launchSettings.json +++ b/common/services/ASC.Data.Backup/Properties/launchSettings.json @@ -5,10 +5,10 @@ "launchBrowser": false, "launchUrl": "http://localhost:5012/api/2.0/backup/backuptmp", "environmentVariables": { - "$STORAGE_ROOT": "../../../../Data", + "$STORAGE_ROOT": "../../../Data", "log__name": "backup", - "log__dir": "../../../../Logs", - "core__products__folder": "../../../../products", + "log__dir": "../../../Logs", + "core__products__folder": "../../../products", "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_URLS": "http://localhost:5012" } @@ -18,10 +18,10 @@ "launchBrowser": false, "launchUrl": "http://localhost:5012/api/2.0/backup/backuptmp", "environmentVariables": { - "$STORAGE_ROOT": "../../../../Data", + "$STORAGE_ROOT": "../../../Data", "log__name": "backup", - "log__dir": "../../../../Logs", - "core__products__folder": "../../../../products", + "log__dir": "../../../Logs", + "core__products__folder": "../../../products", "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_URLS": "http://localhost:5012" }, diff --git a/common/services/ASC.Data.Backup/Backup/Startup.cs b/common/services/ASC.Data.Backup/Startup.cs similarity index 100% rename from common/services/ASC.Data.Backup/Backup/Startup.cs rename to common/services/ASC.Data.Backup/Startup.cs diff --git a/common/services/ASC.Data.Backup/appsettings.json b/common/services/ASC.Data.Backup/appsettings.json new file mode 100644 index 0000000000..9bf702e310 --- /dev/null +++ b/common/services/ASC.Data.Backup/appsettings.json @@ -0,0 +1,3 @@ +{ + "pathToConf": "..\\..\\..\\config" +} diff --git a/web/ASC.Web.Api/ASC.Web.Api.csproj b/web/ASC.Web.Api/ASC.Web.Api.csproj index c97e4627ad..27667fc303 100644 --- a/web/ASC.Web.Api/ASC.Web.Api.csproj +++ b/web/ASC.Web.Api/ASC.Web.Api.csproj @@ -27,8 +27,8 @@ + - From c5b135afbe635513bb97e0ec57a33209cb0de946 Mon Sep 17 00:00:00 2001 From: SuhorukovAnton Date: Thu, 2 Sep 2021 16:11:41 +0300 Subject: [PATCH 5/5] backup.core: remove waste --- .../Backup/ASC.Data.Backup.csproj | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj diff --git a/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj b/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj deleted file mode 100644 index 2b343032cd..0000000000 --- a/common/services/ASC.Data.Backup/Backup/ASC.Data.Backup.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - net5.0 - - Exe - false - false - - - - none - false - - - - - MySqlConnectorAlias - - - - - -