DocSpace-client/common/ASC.Data.Storage/StorageUploader.cs

256 lines
10 KiB
C#
Raw Normal View History

2019-06-04 14:43:20 +00:00
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* 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.
*
*/
namespace ASC.Data.Storage
2020-10-19 15:53:15 +00:00
{
[Singletone]
2019-06-04 14:43:20 +00:00
public class StorageUploader
{
2020-09-29 13:02:47 +00:00
protected readonly DistributedTaskQueue Queue;
2019-06-04 14:43:20 +00:00
private static readonly object s_locker;
private readonly IServiceProvider _serviceProvider;
private readonly TempStream _tempStream;
private readonly ICacheNotify<MigrationProgress> _cacheMigrationNotify;
2019-11-06 15:03:09 +00:00
2019-06-04 14:43:20 +00:00
static StorageUploader()
{
s_locker = new object();
2019-06-04 14:43:20 +00:00
}
2019-11-06 15:03:09 +00:00
public StorageUploader(IServiceProvider serviceProvider, TempStream tempStream, ICacheNotify<MigrationProgress> cacheMigrationNotify, DistributedTaskQueueOptionsManager options)
2019-11-06 15:03:09 +00:00
{
_serviceProvider = serviceProvider;
_tempStream = tempStream;
_cacheMigrationNotify = cacheMigrationNotify;
2020-09-29 13:02:47 +00:00
Queue = options.Get(nameof(StorageUploader));
2019-11-06 15:03:09 +00:00
}
2019-06-04 14:43:20 +00:00
2019-09-13 11:18:27 +00:00
public void Start(int tenantId, StorageSettings newStorageSettings, StorageFactoryConfig storageFactoryConfig)
2019-06-04 14:43:20 +00:00
{
lock (s_locker)
2019-06-04 14:43:20 +00:00
{
2020-09-29 13:02:47 +00:00
var id = GetCacheKey(tenantId);
var migrateOperation = Queue.GetTask<MigrateOperation>(id);
2019-06-04 14:43:20 +00:00
if (migrateOperation != null) return;
migrateOperation = new MigrateOperation(_serviceProvider, _cacheMigrationNotify, id, tenantId, newStorageSettings, storageFactoryConfig, _tempStream);
2020-10-02 07:19:02 +00:00
Queue.QueueTask(migrateOperation);
2019-06-04 14:43:20 +00:00
}
}
2020-09-29 13:02:47 +00:00
public MigrateOperation GetProgress(int tenantId)
2019-06-04 14:43:20 +00:00
{
lock (s_locker)
2019-06-04 14:43:20 +00:00
{
2020-09-29 13:02:47 +00:00
return Queue.GetTask<MigrateOperation>(GetCacheKey(tenantId));
2019-06-04 14:43:20 +00:00
}
}
2020-09-30 10:54:49 +00:00
public void Stop()
2019-06-04 14:43:20 +00:00
{
2020-09-30 10:54:49 +00:00
foreach (var task in Queue.GetTasks<MigrateOperation>().Where(r => r.Status == DistributedTaskStatus.Running))
2019-06-04 14:43:20 +00:00
{
2020-09-30 10:54:49 +00:00
Queue.CancelTask(task.Id);
2019-06-04 14:43:20 +00:00
}
}
private static string GetCacheKey(int tenantId)
{
return typeof(MigrateOperation).FullName + tenantId;
}
}
2021-05-18 18:24:22 +00:00
[Transient]
2020-10-02 07:19:02 +00:00
public class MigrateOperation : DistributedTaskProgress
{
private static readonly string _configPath;
private readonly ILog _logger;
private readonly IEnumerable<string> _modules;
private readonly StorageSettings _settings;
private readonly int _tenantId;
private readonly IServiceProvider _serviceProvider;
private readonly StorageFactoryConfig _storageFactoryConfig;
private readonly TempStream _tempStream;
private readonly ICacheNotify<MigrationProgress> cacheMigrationNotify;
2019-06-04 14:43:20 +00:00
static MigrateOperation()
{
_configPath = string.Empty;
2019-06-04 14:43:20 +00:00
}
public MigrateOperation(
IServiceProvider serviceProvider,
ICacheNotify<MigrationProgress> cacheMigrationNotify,
string id,
int tenantId,
StorageSettings settings,
StorageFactoryConfig storageFactoryConfig,
2021-05-17 11:35:00 +00:00
TempStream tempStream)
2019-11-06 15:03:09 +00:00
{
2020-09-29 13:02:47 +00:00
Id = id;
Status = DistributedTaskStatus.Created;
_serviceProvider = serviceProvider;
this.cacheMigrationNotify = cacheMigrationNotify;
_tenantId = tenantId;
_settings = settings;
_storageFactoryConfig = storageFactoryConfig;
_tempStream = tempStream;
_modules = storageFactoryConfig.GetModuleList(_configPath, true);
StepCount = _modules.Count();
_logger = serviceProvider.GetService<IOptionsMonitor<ILog>>().CurrentValue;
2019-11-06 15:03:09 +00:00
}
2019-06-04 14:43:20 +00:00
protected override void DoJob()
{
try
{
_logger.DebugFormat("Tenant: {0}", _tenantId);
2020-09-29 13:02:47 +00:00
Status = DistributedTaskStatus.Running;
using var scope = _serviceProvider.CreateScope();
2021-05-21 13:26:42 +00:00
var tempPath = scope.ServiceProvider.GetService<TempPath>();
2020-08-31 08:18:07 +00:00
var scopeClass = scope.ServiceProvider.GetService<MigrateOperationScope>();
2020-09-07 12:01:15 +00:00
var (tenantManager, securityContext, storageFactory, options, storageSettingsHelper, settingsManager) = scopeClass;
var tenant = tenantManager.GetTenant(_tenantId);
2020-08-31 08:18:07 +00:00
tenantManager.SetCurrentTenant(tenant);
2019-11-06 15:03:09 +00:00
2021-08-18 14:04:16 +00:00
securityContext.AuthenticateMeWithoutCookie(tenant.OwnerId);
2019-06-04 14:43:20 +00:00
foreach (var module in _modules)
2019-06-04 14:43:20 +00:00
{
var oldStore = storageFactory.GetStorage(_configPath, _tenantId.ToString(), module);
var store = storageFactory.GetStorageFromConsumer(_configPath, _tenantId.ToString(), module, storageSettingsHelper.DataStoreConsumer(_settings));
var domains = _storageFactoryConfig.GetDomainList(_configPath, module).ToList();
2019-06-04 14:43:20 +00:00
var crossModuleTransferUtility = new CrossModuleTransferUtility(options, _tempStream, tempPath, oldStore, store);
2019-06-04 14:43:20 +00:00
string[] files;
foreach (var domain in domains)
{
2020-08-06 18:07:27 +00:00
//Status = module + domain;
_logger.DebugFormat("Domain: {0}", domain);
2019-06-04 14:43:20 +00:00
files = oldStore.ListFilesRelative(domain, "\\", "*.*", true);
foreach (var file in files)
{
_logger.DebugFormat("File: {0}", file);
2019-06-04 14:43:20 +00:00
crossModuleTransferUtility.CopyFile(domain, file, domain, file);
}
}
_logger.Debug("Domain:");
2019-06-04 14:43:20 +00:00
files = oldStore.ListFilesRelative(string.Empty, "\\", "*.*", true)
.Where(path => domains.All(domain => !path.Contains(domain + "/")))
.ToArray();
foreach (var file in files)
{
_logger.DebugFormat("File: {0}", file);
2019-06-04 14:43:20 +00:00
crossModuleTransferUtility.CopyFile("", file, "", file);
}
StepDone();
2020-08-28 08:31:46 +00:00
2020-08-28 11:58:20 +00:00
MigrationPublish();
2019-06-04 14:43:20 +00:00
}
settingsManager.Save(_settings);
2019-06-04 14:43:20 +00:00
tenant.SetStatus(TenantStatus.Active);
2020-10-12 19:39:23 +00:00
tenantManager.SaveTenant(tenant);
2020-10-02 07:19:02 +00:00
2020-09-29 13:02:47 +00:00
Status = DistributedTaskStatus.Completed;
2019-06-04 14:43:20 +00:00
}
catch (Exception e)
{
2020-09-29 13:02:47 +00:00
Status = DistributedTaskStatus.Failted;
2020-10-02 07:19:02 +00:00
Exception = e;
_logger.Error(e);
2019-06-04 14:43:20 +00:00
}
2020-08-27 14:01:37 +00:00
2020-08-28 11:58:20 +00:00
MigrationPublish();
}
2020-09-30 10:54:49 +00:00
public object Clone()
{
2020-09-30 10:54:49 +00:00
return MemberwiseClone();
}
2020-08-28 11:58:20 +00:00
private void MigrationPublish()
{
cacheMigrationNotify.Publish(new MigrationProgress
2020-08-27 14:01:37 +00:00
{
TenantId = _tenantId,
2020-08-28 11:26:06 +00:00
Progress = Percentage,
2020-10-02 07:19:02 +00:00
Error = Exception.ToString(),
2020-08-27 14:01:37 +00:00
IsCompleted = IsCompleted
},
2020-08-28 11:58:20 +00:00
CacheNotifyAction.Insert);
2020-08-24 18:41:06 +00:00
}
}
2020-08-31 08:18:07 +00:00
public class MigrateOperationScope
2020-08-24 18:41:06 +00:00
{
private readonly TenantManager _tenantManager;
private readonly SecurityContext _securityContext;
private readonly StorageFactory _storageFactory;
private readonly IOptionsMonitor<ILog> _options;
private readonly StorageSettingsHelper _storageSettingsHelper;
private readonly SettingsManager _settingsManager;
2020-07-29 21:57:58 +00:00
2020-08-31 08:18:07 +00:00
public MigrateOperationScope(TenantManager tenantManager,
SecurityContext securityContext,
2020-10-12 16:23:15 +00:00
StorageFactory storageFactory,
IOptionsMonitor<ILog> options,
2020-08-31 08:18:07 +00:00
StorageSettingsHelper storageSettingsHelper,
SettingsManager settingsManager)
2020-07-29 21:57:58 +00:00
{
_tenantManager = tenantManager;
_securityContext = securityContext;
_storageFactory = storageFactory;
_options = options;
_storageSettingsHelper = storageSettingsHelper;
_settingsManager = settingsManager;
2020-08-24 18:41:06 +00:00
}
2020-08-31 08:18:07 +00:00
public void Deconstruct(out TenantManager tenantManager,
out SecurityContext securityContext,
2020-10-12 16:23:15 +00:00
out StorageFactory storageFactory,
2020-08-31 08:18:07 +00:00
out IOptionsMonitor<ILog> options,
out StorageSettingsHelper storageSettingsHelper,
2020-10-12 16:23:15 +00:00
out SettingsManager settingsManager)
2020-08-31 08:18:07 +00:00
{
tenantManager = _tenantManager;
securityContext = _securityContext;
storageFactory = _storageFactory;
options = _options;
storageSettingsHelper = _storageSettingsHelper;
settingsManager = _settingsManager;
2020-08-31 08:18:07 +00:00
}
2019-06-04 14:43:20 +00:00
}
}