diff --git a/ASC.Web.sln b/ASC.Web.sln
index 0d92015d0dd..cfbf50017bd 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.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", "common\services\ASC.Data.Backup\ASC.Data.Backup.csproj", "{027EEE53-7491-48F4-B467-6404D68798A7}"
+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
+ {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/ASC.Data.Backup.Core/ASC.Data.Backup.Core.csproj b/common/ASC.Data.Backup.Core/ASC.Data.Backup.Core.csproj
new file mode 100644
index 00000000000..10431c607f5
--- /dev/null
+++ b/common/ASC.Data.Backup.Core/ASC.Data.Backup.Core.csproj
@@ -0,0 +1,55 @@
+
+
+
+ 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/ASC.Data.Backup.Core/ActionInvoker.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/ActionInvoker.cs
rename to common/ASC.Data.Backup.Core/ActionInvoker.cs
index 95668a22f9b..e4ce1689632 100644
--- a/common/services/ASC.Data.Backup/ActionInvoker.cs
+++ b/common/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 @@ public static void Try(
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/ASC.Data.Backup.Core/BackupAjaxHandler.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/BackupAjaxHandler.cs
rename to common/ASC.Data.Backup.Core/BackupAjaxHandler.cs
index 03b91d59a62..5dd3db0376d 100644
--- a/common/services/ASC.Data.Backup/BackupAjaxHandler.cs
+++ b/common/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 @@ public class BackupAjaxHandler
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 @@ public BackupAjaxHandler(
SecurityContext = securityContext;
UserManager = userManager;
TenantExtra = tenantExtra;
- ConsumerFactory = consumerFactory;
- BackupFileUploadHandler = backupFileUploadHandler;
+ ConsumerFactory = consumerFactory;
+ BackupFileUploadHandler = backupFileUploadHandler;
BackupService = backupService;
}
@@ -71,7 +71,7 @@ public void StartBackup(BackupStorageType storageType, Dictionary 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/ASC.Data.Backup.Core/BackupFileUploadHandler.cs
similarity index 96%
rename from common/services/ASC.Data.Backup/BackupFileUploadHandler.cs
rename to common/ASC.Data.Backup.Core/BackupFileUploadHandler.cs
index a5a2d791169..c2dc6b9b04d 100644
--- a/common/services/ASC.Data.Backup/BackupFileUploadHandler.cs
+++ b/common/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/BackupResource.Designer.cs b/common/ASC.Data.Backup.Core/BackupResource.Designer.cs
similarity index 95%
rename from common/services/ASC.Data.Backup/BackupResource.Designer.cs
rename to common/ASC.Data.Backup.Core/BackupResource.Designer.cs
index e24a8985314..8bb976a9c1f 100644
--- a/common/services/ASC.Data.Backup/BackupResource.Designer.cs
+++ b/common/ASC.Data.Backup.Core/BackupResource.Designer.cs
@@ -8,7 +8,7 @@
//
//------------------------------------------------------------------------------
-namespace ASC.Data.Backup {
+namespace ASC.Data.Backup.Core {
using System;
@@ -39,7 +39,7 @@ internal BackupResource() {
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);
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.Data.Backup.Core.BackupResource", typeof(BackupResource).Assembly);
resourceMan = temp;
}
return resourceMan;
diff --git a/common/services/ASC.Data.Backup/BackupResource.resx b/common/ASC.Data.Backup.Core/BackupResource.resx
similarity index 97%
rename from common/services/ASC.Data.Backup/BackupResource.resx
rename to common/ASC.Data.Backup.Core/BackupResource.resx
index af666c13189..69c7f0c17ed 100644
--- a/common/services/ASC.Data.Backup/BackupResource.resx
+++ b/common/ASC.Data.Backup.Core/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/Contracts/BackupServiceModel.cs b/common/ASC.Data.Backup.Core/Contracts/BackupServiceModel.cs
similarity index 97%
rename from common/services/ASC.Data.Backup/Contracts/BackupServiceModel.cs
rename to common/ASC.Data.Backup.Core/Contracts/BackupServiceModel.cs
index 38cb1423379..03066dcf335 100644
--- a/common/services/ASC.Data.Backup/Contracts/BackupServiceModel.cs
+++ b/common/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 @@ public enum BackupStorageType
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 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 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 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 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 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/ASC.Data.Backup.Core/Contracts/IBackupService.cs
similarity index 100%
rename from common/services/ASC.Data.Backup/Contracts/IBackupService.cs
rename to common/ASC.Data.Backup.Core/Contracts/IBackupService.cs
diff --git a/common/services/ASC.Data.Backup/Core/DbBackupProvider.cs b/common/ASC.Data.Backup.Core/Core/DbBackupProvider.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Core/DbBackupProvider.cs
rename to common/ASC.Data.Backup.Core/Core/DbBackupProvider.cs
index 24603332efe..8b157647a2f 100644
--- a/common/services/ASC.Data.Backup/Core/DbBackupProvider.cs
+++ b/common/ASC.Data.Backup.Core/Core/DbBackupProvider.cs
@@ -31,20 +31,20 @@
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 @@ public string Name
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 @@ private Configuration GetConfiguration(string config)
{
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 @@ private List BackupDatabase(int tenant, ConnectionStringSettings conne
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 @@ private void RestoreDatabase(ConnectionStringSettings connectionString, IEnumera
processedTables.Add(table);
}
}
- }
+ }
}
}
diff --git a/common/services/ASC.Data.Backup/Core/DbHelper.cs b/common/ASC.Data.Backup.Core/Core/DbHelper.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Core/DbHelper.cs
rename to common/ASC.Data.Backup.Core/Core/DbHelper.cs
index 21a44745128..3df6f196eba 100644
--- a/common/services/ASC.Data.Backup/Core/DbHelper.cs
+++ b/common/ASC.Data.Backup.Core/Core/DbHelper.cs
@@ -11,14 +11,14 @@
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/ASC.Data.Backup.Core/Core/FileBackupProvider.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Core/FileBackupProvider.cs
rename to common/ASC.Data.Backup.Core/Core/FileBackupProvider.cs
index 54607383cdc..5494183ad23 100644
--- a/common/services/ASC.Data.Backup/Core/FileBackupProvider.cs
+++ b/common/ASC.Data.Backup.Core/Core/FileBackupProvider.cs
@@ -28,25 +28,25 @@
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 @@ public IEnumerable GetElements(int tenant, string[] configs, IDataWrit
{
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 @@ public bool Equals(FileBackupInfo other)
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/ASC.Data.Backup.Core/Core/IBackupProvider.cs
similarity index 100%
rename from common/services/ASC.Data.Backup/Core/IBackupProvider.cs
rename to common/ASC.Data.Backup.Core/Core/IBackupProvider.cs
diff --git a/common/services/ASC.Data.Backup/Core/IDataOperator.cs b/common/ASC.Data.Backup.Core/Core/IDataOperator.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Core/IDataOperator.cs
rename to common/ASC.Data.Backup.Core/Core/IDataOperator.cs
index 323a323d9d3..a2d6f46bb37 100644
--- a/common/services/ASC.Data.Backup/Core/IDataOperator.cs
+++ b/common/ASC.Data.Backup.Core/Core/IDataOperator.cs
@@ -37,7 +37,7 @@ public interface IDataWriteOperator : IDisposable
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/ASC.Data.Backup.Core/Core/NotifyHelper.cs
similarity index 98%
rename from common/services/ASC.Data.Backup/Core/NotifyHelper.cs
rename to common/ASC.Data.Backup.Core/Core/NotifyHelper.cs
index 818b8cb274b..db8968d5c6e 100644
--- a/common/services/ASC.Data.Backup/Core/NotifyHelper.cs
+++ b/common/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/ASC.Data.Backup.Core/Core/Schedule.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Core/Schedule.cs
rename to common/ASC.Data.Backup.Core/Core/Schedule.cs
index 6d034f5b40a..228be978c35 100644
--- a/common/services/ASC.Data.Backup/Core/Schedule.cs
+++ b/common/ASC.Data.Backup.Core/Core/Schedule.cs
@@ -11,7 +11,7 @@
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/ASC.Data.Backup.Core/Core/ZipOperator.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Core/ZipOperator.cs
rename to common/ASC.Data.Backup.Core/Core/ZipOperator.cs
index f578570b560..764080ab7ca 100644
--- a/common/services/ASC.Data.Backup/Core/ZipOperator.cs
+++ b/common/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/ASC.Data.Backup.Core/EF/BackupRecord.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/EF/BackupRecord.cs
rename to common/ASC.Data.Backup.Core/EF/BackupRecord.cs
index e10ada610da..062e447a044 100644
--- a/common/services/ASC.Data.Backup/EF/BackupRecord.cs
+++ b/common/ASC.Data.Backup.Core/EF/BackupRecord.cs
@@ -17,8 +17,8 @@ public class BackupRecord : BaseEntity
[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/ASC.Data.Backup.Core/EF/BackupSchedule.cs
similarity index 100%
rename from common/services/ASC.Data.Backup/EF/BackupSchedule.cs
rename to common/ASC.Data.Backup.Core/EF/BackupSchedule.cs
diff --git a/common/services/ASC.Data.Backup/EF/BackupsContext.cs b/common/ASC.Data.Backup.Core/EF/BackupsContext.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/EF/BackupsContext.cs
rename to common/ASC.Data.Backup.Core/EF/BackupsContext.cs
index d674c0e7d50..9723eed9686 100644
--- a/common/services/ASC.Data.Backup/EF/BackupsContext.cs
+++ b/common/ASC.Data.Backup.Core/EF/BackupsContext.cs
@@ -19,13 +19,13 @@ public BackupsContext() { }
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/ASC.Data.Backup.Core/Exceptions/DbBackupException.cs
similarity index 100%
rename from common/services/ASC.Data.Backup/Exceptions/DbBackupException.cs
rename to common/ASC.Data.Backup.Core/Exceptions/DbBackupException.cs
diff --git a/common/services/ASC.Data.Backup/Exceptions/ThrowHelper.cs b/common/ASC.Data.Backup.Core/Exceptions/ThrowHelper.cs
similarity index 100%
rename from common/services/ASC.Data.Backup/Exceptions/ThrowHelper.cs
rename to common/ASC.Data.Backup.Core/Exceptions/ThrowHelper.cs
diff --git a/common/services/ASC.Data.Backup/Extensions/DataExtensions.cs b/common/ASC.Data.Backup.Core/Extensions/DataExtensions.cs
similarity index 100%
rename from common/services/ASC.Data.Backup/Extensions/DataExtensions.cs
rename to common/ASC.Data.Backup.Core/Extensions/DataExtensions.cs
diff --git a/common/services/ASC.Data.Backup/Extensions/EnumerableExtensions.cs b/common/ASC.Data.Backup.Core/Extensions/EnumerableExtensions.cs
similarity index 100%
rename from common/services/ASC.Data.Backup/Extensions/EnumerableExtensions.cs
rename to common/ASC.Data.Backup.Core/Extensions/EnumerableExtensions.cs
diff --git a/common/services/ASC.Data.Backup/Extensions/XmlExtensions.cs b/common/ASC.Data.Backup.Core/Extensions/XmlExtensions.cs
similarity index 100%
rename from common/services/ASC.Data.Backup/Extensions/XmlExtensions.cs
rename to common/ASC.Data.Backup.Core/Extensions/XmlExtensions.cs
diff --git a/common/services/ASC.Data.Backup/Listerners/BackupListener.cs b/common/ASC.Data.Backup.Core/Listerners/BackupListener.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Listerners/BackupListener.cs
rename to common/ASC.Data.Backup.Core/Listerners/BackupListener.cs
index 2c174c584be..6828fd591c4 100644
--- a/common/services/ASC.Data.Backup/Listerners/BackupListener.cs
+++ b/common/ASC.Data.Backup.Core/Listerners/BackupListener.cs
@@ -9,7 +9,7 @@
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/ASC.Data.Backup.Core/Service/BackupService.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Service/BackupService.cs
rename to common/ASC.Data.Backup.Core/Service/BackupService.cs
index 0ba6c0cd9c5..6e2a4f43d72 100644
--- a/common/services/ASC.Data.Backup/Service/BackupService.cs
+++ b/common/ASC.Data.Backup.Core/Service/BackupService.cs
@@ -28,20 +28,20 @@
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 @@ public string GetTmpFolder()
}
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 @@ public void DeleteSchedule(int tenantId)
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/ASC.Data.Backup.Core/Service/BackupSettings.cs
similarity index 100%
rename from common/services/ASC.Data.Backup/Service/BackupSettings.cs
rename to common/ASC.Data.Backup.Core/Service/BackupSettings.cs
diff --git a/common/services/ASC.Data.Backup/Service/BackupWorker.cs b/common/ASC.Data.Backup.Core/Service/BackupWorker.cs
similarity index 97%
rename from common/services/ASC.Data.Backup/Service/BackupWorker.cs
rename to common/ASC.Data.Backup.Core/Service/BackupWorker.cs
index 290f5494f0e..634a54d7d38 100644
--- a/common/services/ASC.Data.Backup/Service/BackupWorker.cs
+++ b/common/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/ASC.Data.Backup.Core/Storage/BackupRepository.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Storage/BackupRepository.cs
rename to common/ASC.Data.Backup.Core/Storage/BackupRepository.cs
index 89dad1e9693..c442e973c1d 100644
--- a/common/services/ASC.Data.Backup/Storage/BackupRepository.cs
+++ b/common/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 @@ public BackupRepository(DbContextManager backupContext)
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 @@ public void DeleteBackupSchedule(int tenantId)
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/ASC.Data.Backup.Core/Storage/BackupStorageFactory.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Storage/BackupStorageFactory.cs
rename to common/ASC.Data.Backup.Core/Storage/BackupStorageFactory.cs
index 1baf5def6a7..1047310e08d 100644
--- a/common/services/ASC.Data.Backup/Storage/BackupStorageFactory.cs
+++ b/common/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/ASC.Data.Backup.Core/Storage/ConsumerBackupStorage.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Storage/ConsumerBackupStorage.cs
rename to common/ASC.Data.Backup.Core/Storage/ConsumerBackupStorage.cs
index 61c6fccd320..251c26539f6 100644
--- a/common/services/ASC.Data.Backup/Storage/ConsumerBackupStorage.cs
+++ b/common/ASC.Data.Backup.Core/Storage/ConsumerBackupStorage.cs
@@ -34,7 +34,7 @@
using ASC.Data.Storage.Configuration;
namespace ASC.Data.Backup.Storage
-{
+{
[Scope]
public class ConsumerBackupStorage : IBackupStorage
{
@@ -52,16 +52,16 @@ public void Init(IReadOnlyDictionary storageParams)
}
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/ASC.Data.Backup.Core/Storage/DataStoreBackupStorage.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Storage/DataStoreBackupStorage.cs
rename to common/ASC.Data.Backup.Core/Storage/DataStoreBackupStorage.cs
index 928f4ed684a..8ac44080bb0 100644
--- a/common/services/ASC.Data.Backup/Storage/DataStoreBackupStorage.cs
+++ b/common/ASC.Data.Backup.Core/Storage/DataStoreBackupStorage.cs
@@ -31,7 +31,7 @@
using ASC.Data.Storage;
namespace ASC.Data.Backup.Storage
-{
+{
[Scope]
public class DataStoreBackupStorage : IBackupStorage
{
@@ -50,16 +50,16 @@ public void Init(int tenant, string webConfigPath)
}
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 @@ public void Delete(string storagePath)
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/ASC.Data.Backup.Core/Storage/DocumentsBackupStorage.cs
similarity index 98%
rename from common/services/ASC.Data.Backup/Storage/DocumentsBackupStorage.cs
rename to common/ASC.Data.Backup.Core/Storage/DocumentsBackupStorage.cs
index e9403c6b95f..2ff9ef461cf 100644
--- a/common/services/ASC.Data.Backup/Storage/DocumentsBackupStorage.cs
+++ b/common/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/ASC.Data.Backup.Core/Storage/IBackupRepository.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Storage/IBackupRepository.cs
rename to common/ASC.Data.Backup.Core/Storage/IBackupRepository.cs
index ed05643616d..1a6fdbd8e53 100644
--- a/common/services/ASC.Data.Backup/Storage/IBackupRepository.cs
+++ b/common/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/ASC.Data.Backup.Core/Storage/IBackupStorage.cs
similarity index 100%
rename from common/services/ASC.Data.Backup/Storage/IBackupStorage.cs
rename to common/ASC.Data.Backup.Core/Storage/IBackupStorage.cs
diff --git a/common/services/ASC.Data.Backup/Storage/LocalBackupStorage.cs b/common/ASC.Data.Backup.Core/Storage/LocalBackupStorage.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Storage/LocalBackupStorage.cs
rename to common/ASC.Data.Backup.Core/Storage/LocalBackupStorage.cs
index 37009952c50..1864eecb054 100644
--- a/common/services/ASC.Data.Backup/Storage/LocalBackupStorage.cs
+++ b/common/ASC.Data.Backup.Core/Storage/LocalBackupStorage.cs
@@ -28,10 +28,10 @@
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/ASC.Data.Backup.Core/Storage/S3BackupStorage.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Storage/S3BackupStorage.cs
rename to common/ASC.Data.Backup.Core/Storage/S3BackupStorage.cs
index 6344e31c758..d4740de90c7 100644
--- a/common/services/ASC.Data.Backup/Storage/S3BackupStorage.cs
+++ b/common/ASC.Data.Backup.Core/Storage/S3BackupStorage.cs
@@ -58,7 +58,7 @@ public S3BackupStorage(IOptionsMonitor options, string accessKeyId, string
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/ASC.Data.Backup.Core/Tasks/BackupFileInfo.cs
similarity index 100%
rename from common/services/ASC.Data.Backup/Tasks/BackupFileInfo.cs
rename to common/ASC.Data.Backup.Core/Tasks/BackupFileInfo.cs
diff --git a/common/services/ASC.Data.Backup/Tasks/BackupPortalTask.cs b/common/ASC.Data.Backup.Core/Tasks/BackupPortalTask.cs
similarity index 99%
rename from common/services/ASC.Data.Backup/Tasks/BackupPortalTask.cs
rename to common/ASC.Data.Backup.Core/Tasks/BackupPortalTask.cs
index b3758e9e1df..2d89d272a1d 100644
--- a/common/services/ASC.Data.Backup/Tasks/BackupPortalTask.cs
+++ b/common/ASC.Data.Backup.Core/Tasks/BackupPortalTask.cs
@@ -33,10 +33,10 @@
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.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 @@ public BackupPortalTask(DbFactory dbFactory, DbContextManager db
: 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 @@ public override void RunJob()
using (var writer = new ZipWriteOperator(TempStream, BackupFilePath))
- {
+ {
if (Dump)
{
DoDump(writer);
}
else
- {
-
+ {
+
var modulesToProcess = GetModulesToProcess().ToList();
var fileGroups = GetFilesGroup();
@@ -119,10 +119,10 @@ public override void RunJob()
}
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 @@ private void DoDump(IDataWriteOperator writer)
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 @@ private void DoDump(IDataWriteOperator writer)
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 @@ private void DumpTableScheme(string t, string dir)
}
SetStepCompleted();
- }
-
+ }
+
Logger.DebugFormat("dump table scheme stop {0}", t);
}
catch (Exception e)
@@ -256,13 +256,13 @@ private int SelectCount(string t)
{
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 @@ private void DumpTableData(string t, string dir, int count)
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