Merge branch 'master' into feature/files

This commit is contained in:
pavelbannov 2020-09-10 12:35:55 +03:00
commit 23b2a310a0
42 changed files with 1467 additions and 400 deletions

View File

@ -52,8 +52,8 @@ namespace ASC.Core.Configuration
public static void Synchronize()
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var coreBaseSettings = scope.ServiceProvider.GetService<CoreBaseSettings>();
var scopeClass = scope.ServiceProvider.GetService<AmiPublicDnsSyncServiceScope>();
var (tenantManager, coreBaseSettings) = scopeClass;
if (coreBaseSettings.Standalone)
{
var tenants = tenantManager.GetTenants(false).Where(t => MappedDomainNotSettedByUser(t.MappedDomain));
@ -95,4 +95,19 @@ namespace ASC.Core.Configuration
return null;
}
}
public class AmiPublicDnsSyncServiceScope
{
private TenantManager TenantManager { get; }
private CoreBaseSettings CoreBaseSettings { get; }
public AmiPublicDnsSyncServiceScope(TenantManager tenantManager, CoreBaseSettings coreBaseSettings)
{
TenantManager = tenantManager;
CoreBaseSettings = coreBaseSettings;
}
public void Deconstruct(out TenantManager tenantManager, out CoreBaseSettings coreBaseSettings) =>
(tenantManager, coreBaseSettings) = (TenantManager, CoreBaseSettings);
}
}

View File

@ -28,6 +28,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using ASC.Common;
using ASC.Common.Logging;
using ASC.Common.Utils;
using ASC.Core.Notify.Senders;
@ -94,9 +95,10 @@ namespace ASC.Core.Notify
CreationDate = DateTime.UtcNow.Ticks,
};
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var configuration = scope.ServiceProvider.GetService<CoreConfiguration>();
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<EmailSenderSinkScope>();
var (tenantManager, configuration, options) = scopeClass;
var tenant = tenantManager.GetCurrentTenant(false);
m.Tenant = tenant == null ? Tenant.DEFAULT_TENANT : tenant.TenantId;
@ -149,4 +151,30 @@ namespace ASC.Core.Notify
return m;
}
}
public class EmailSenderSinkScope
{
private TenantManager TenantManager { get; }
private CoreConfiguration CoreConfiguration { get; }
private IOptionsMonitor<ILog> Options { get; }
public EmailSenderSinkScope(TenantManager tenantManager, CoreConfiguration coreConfiguration, IOptionsMonitor<ILog> options)
{
TenantManager = tenantManager;
CoreConfiguration = coreConfiguration;
Options = options;
}
public void Deconstruct(out TenantManager tenantManager, out CoreConfiguration coreConfiguration, out IOptionsMonitor<ILog> optionsMonitor)
=> (tenantManager, coreConfiguration, optionsMonitor) = (TenantManager, CoreConfiguration, Options);
}
public static class EmailSenderSinkExtension
{
public static DIHelper AddEmailSenderSinkService(this DIHelper services)
{
services.TryAddScoped<EmailSenderSinkScope>();
return services;
}
}
}

View File

@ -26,6 +26,7 @@
using System;
using ASC.Common;
using ASC.Core.Notify.Senders;
using ASC.Core.Tenants;
using ASC.Notify.Messages;
@ -54,8 +55,8 @@ namespace ASC.Core.Notify
try
{
using var scope = ServiceProvider.CreateScope();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var scopeClass = scope.ServiceProvider.GetService<JabberSenderSinkScope>();
(var userManager, var tenantManager) = scopeClass;
var result = SendResult.OK;
var username = userManager.GetUsers(new Guid(message.Recipient.ID)).UserName;
if (string.IsNullOrEmpty(username))
@ -87,4 +88,28 @@ namespace ASC.Core.Notify
}
}
}
public class JabberSenderSinkScope
{
private UserManager UserManager { get; }
private TenantManager TenantManager { get; }
public JabberSenderSinkScope(UserManager userManager, TenantManager tenantManager)
{
TenantManager = tenantManager;
UserManager = userManager;
}
public void Deconstruct(out UserManager userManager, out TenantManager tenantManager)
=> (userManager, tenantManager) = (UserManager, TenantManager);
}
public static class JabberSenderSinkExtension
{
public static DIHelper AddJabberSenderSinkService(this DIHelper services)
{
services.TryAddScoped<JabberSenderSinkScope>();
return services;
}
}
}

View File

@ -71,7 +71,6 @@ namespace ASC.Core.Notify.Senders
lastRefresh = DateTime.UtcNow - refreshTimeout; //set to refresh on first send
}
public override NoticeSendResult Send(NotifyMessage m)
{
NoticeSendResult result;
@ -81,9 +80,9 @@ namespace ASC.Core.Notify.Senders
{
Log.DebugFormat("Tenant: {0}, To: {1}", m.Tenant, m.To);
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var scopeClass = scope.ServiceProvider.GetService<AWSSenderScope>();
var (tenantManager, configuration) = scopeClass;
tenantManager.SetCurrentTenant(m.Tenant);
var configuration = scope.ServiceProvider.GetService<CoreConfiguration>();
if (!configuration.SmtpSettings.IsDefaultSettings)
{
@ -228,7 +227,22 @@ namespace ASC.Core.Notify.Senders
private bool IsRefreshNeeded()
{
return quota == null || (DateTime.UtcNow - lastRefresh) > refreshTimeout;
}
}
}
public class AWSSenderScope
{
private TenantManager TenantManager { get; }
private CoreConfiguration CoreConfiguration { get; }
public AWSSenderScope(TenantManager tenantManager, CoreConfiguration coreConfiguration)
{
TenantManager = tenantManager;
CoreConfiguration = coreConfiguration;
}
public void Deconstruct(out TenantManager tenantManager, out CoreConfiguration coreConfiguration)
=> (tenantManager, coreConfiguration) = (TenantManager, CoreConfiguration);
}
public static class AWSSenderExtension
@ -236,6 +250,7 @@ namespace ASC.Core.Notify.Senders
public static DIHelper AddAWSSenderService(this DIHelper services)
{
services.TryAddSingleton<AWSSender>();
services.TryAddScoped<AWSSenderScope>();
return services
.AddTenantManagerService()
.AddCoreSettingsService();

View File

@ -61,11 +61,11 @@ namespace ASC.Core.Notify.Senders
protected IConfiguration Configuration { get; }
protected IServiceProvider ServiceProvider { get; }
private string _host;
private int _port;
private bool _ssl;
private ICredentials _credentials;
protected bool _useCoreSettings;
private string Host { get; set; }
private int Port { get; set; }
private bool Ssl { get; set; }
private ICredentials Credentials { get; set; }
protected bool _useCoreSettings { get; set; }
const int NETWORK_TIMEOUT = 30000;
public SmtpSender(
@ -85,12 +85,12 @@ namespace ASC.Core.Notify.Senders
}
else
{
_host = properties["host"];
_port = properties.ContainsKey("port") ? int.Parse(properties["port"]) : 25;
_ssl = properties.ContainsKey("enableSsl") && bool.Parse(properties["enableSsl"]);
Host = properties["host"];
Port = properties.ContainsKey("port") ? int.Parse(properties["port"]) : 25;
Ssl = properties.ContainsKey("enableSsl") && bool.Parse(properties["enableSsl"]);
if (properties.ContainsKey("userName"))
{
_credentials = new NetworkCredential(
Credentials = new NetworkCredential(
properties["userName"],
properties["password"]);
}
@ -101,10 +101,10 @@ namespace ASC.Core.Notify.Senders
{
var s = configuration.SmtpSettings;
_host = s.Host;
_port = s.Port;
_ssl = s.EnableSSL;
_credentials = !string.IsNullOrEmpty(s.CredentialsUserName)
Host = s.Host;
Port = s.Port;
Ssl = s.EnableSSL;
Credentials = !string.IsNullOrEmpty(s.CredentialsUserName)
? new NetworkCredential(s.CredentialsUserName, s.CredentialsUserPassword)
: null;
}
@ -112,9 +112,9 @@ namespace ASC.Core.Notify.Senders
public virtual NoticeSendResult Send(NotifyMessage m)
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var scopeClass = scope.ServiceProvider.GetService<SmtpSenderScope>();
var (tenantManager, configuration) = scopeClass;
tenantManager.SetCurrentTenant(m.Tenant);
var configuration = scope.ServiceProvider.GetService<CoreConfiguration>();
var smtpClient = GetSmtpClient();
var result = NoticeSendResult.TryOnceAgain;
@ -127,14 +127,14 @@ namespace ASC.Core.Notify.Senders
var mail = BuildMailMessage(m);
Log.DebugFormat("SmtpSender - host={0}; port={1}; enableSsl={2} enableAuth={3}", _host, _port, _ssl, _credentials != null);
Log.DebugFormat("SmtpSender - host={0}; port={1}; enableSsl={2} enableAuth={3}", Host, Port, Ssl, Credentials != null);
smtpClient.Connect(_host, _port,
_ssl ? SecureSocketOptions.Auto : SecureSocketOptions.None);
smtpClient.Connect(Host, Port,
Ssl ? SecureSocketOptions.Auto : SecureSocketOptions.None);
if (_credentials != null)
if (Credentials != null)
{
smtpClient.Authenticate(_credentials);
smtpClient.Authenticate(Credentials);
}
smtpClient.Send(mail);
@ -152,7 +152,7 @@ namespace ASC.Core.Notify.Senders
}
catch (InvalidOperationException)
{
result = string.IsNullOrEmpty(_host) || _port == 0
result = string.IsNullOrEmpty(Host) || Port == 0
? NoticeSendResult.SendingImpossible
: NoticeSendResult.TryOnceAgain;
}
@ -322,11 +322,27 @@ namespace ASC.Core.Notify.Senders
}
}
public class SmtpSenderScope
{
private TenantManager TenantManager { get; }
private CoreConfiguration CoreConfiguration { get; }
public SmtpSenderScope(TenantManager tenantManager, CoreConfiguration coreConfiguration)
{
TenantManager = tenantManager;
CoreConfiguration = coreConfiguration;
}
public void Deconstruct(out TenantManager tenantManager, out CoreConfiguration coreConfiguration)
=> (tenantManager, coreConfiguration) = (TenantManager, CoreConfiguration);
}
public static class SmtpSenderExtension
{
public static DIHelper AddSmtpSenderService(this DIHelper services)
{
services.TryAddSingleton<SmtpSender>();
services.TryAddScoped<SmtpSenderScope>();
return services
.AddTenantManagerService()
.AddCoreSettingsService();

View File

@ -60,10 +60,8 @@ namespace ASC.Core.Common.Tests
public void CreateProviders()
{
using var scope = serviceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var subscriptionManager = scope.ServiceProvider.GetService<SubscriptionManager>();
tenantManager.SetCurrentTenant(tenant);
var scopeClass = scope.ServiceProvider.GetService<TopSubscriptionProviderTestScope>();
var (tenantManager, subscriptionManager, recipientProviderImpl) = scopeClass;
tenant = new Tenants.Tenant(0, "teamlab");
sourceId = "6045b68c-2c2e-42db-9e53-c272e814c4ad";
actionId = "NewCommentForTask";
@ -72,7 +70,6 @@ namespace ASC.Core.Common.Tests
testRec = new DirectRecipient("ff0c4e13-1831-43c2-91ce-7b7beb56179b", null); //Oliver Khan
testRec2 = new DirectRecipient("0017794f-aeb7-49a5-8817-9e870e02bd3f", null); //Якутова Юлия
recProvider = scope.ServiceProvider.GetService<RecipientProviderImpl>();
var directSubProvider = new DirectSubscriptionProvider(sourceId, subscriptionManager, recProvider);
subProvider = new TopSubscriptionProvider(recProvider, directSubProvider);
}
@ -146,5 +143,26 @@ namespace ASC.Core.Common.Tests
}
}
}
public class TopSubscriptionProviderTestScope
{
private TenantManager TenantManager { get; }
private SubscriptionManager SubscriptionManager { get; }
private RecipientProviderImpl RecipientProviderImpl { get; }
public TopSubscriptionProviderTestScope(TenantManager tenantManager, SubscriptionManager subscriptionManager, RecipientProviderImpl recipientProviderImpl)
{
TenantManager = tenantManager;
SubscriptionManager = subscriptionManager;
RecipientProviderImpl = recipientProviderImpl;
}
public void Deconstruct(out TenantManager tenantManager, out SubscriptionManager subscriptionManager, out RecipientProviderImpl recipientProviderImpl)
{
tenantManager = TenantManager;
subscriptionManager = SubscriptionManager;
recipientProviderImpl = RecipientProviderImpl;
}
}
}
#endif

View File

@ -85,8 +85,8 @@ namespace ASC.Core.Common.Tests
public void DepartmentManagers()
{
using var scope = ServiceProvider.CreateScope();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var scopeClass = scope.ServiceProvider.GetService<UserManagerTestScope>();
var (userManager, tenantManager) = scopeClass;
var tenant = tenantManager.SetCurrentTenant(1024);
var deps = userManager.GetDepartments();
@ -114,8 +114,8 @@ namespace ASC.Core.Common.Tests
public void UserGroupsPerformanceTest()
{
using var scope = ServiceProvider.CreateScope();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var scopeClass = scope.ServiceProvider.GetService<UserManagerTestScope>();
(var userManager, var tenantManager) = scopeClass;
var tenant = tenantManager.SetCurrentTenant(0);
foreach (var u in userManager.GetUsers())
@ -149,5 +149,23 @@ namespace ASC.Core.Common.Tests
stopwatch.Stop();
}
}
public class UserManagerTestScope
{
private UserManager UserManager { get; }
private TenantManager TenantManager { get; }
public UserManagerTestScope(UserManager userManager, TenantManager tenantManager)
{
UserManager = userManager;
TenantManager = tenantManager;
}
public void Deconstruct(out UserManager userManager, out TenantManager tenantManager)
{
userManager = UserManager;
tenantManager = TenantManager;
}
}
}
#endif

View File

@ -97,11 +97,14 @@ namespace ASC.Web.Core.Users
{
public static DIHelper AddDisplayUserSettingsService(this DIHelper services)
{
services.TryAddScoped<DisplayUserSettingsHelper>();
if (services.TryAddScoped<DisplayUserSettingsHelper>())
{
return services
.AddUserFormatter()
.AddUserManagerService();
}
return services
.AddUserFormatter()
.AddUserManagerService();
return services;
}
}
}

View File

@ -99,22 +99,13 @@ namespace ASC.Data.Reassigns
}
public void RunJob()
{
var logger = ServiceProvider.GetService<IOptionsMonitor<ILog>>().Get("ASC.Web");
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
{
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<ReassignProgressItemScope>();
var (tenantManager, coreBaseSettings, messageService, studioNotifyService, securityContext, userManager, userPhotoManager, displayUserSettingsHelper, messageTarget, options) = scopeClass;
var logger = options.Get("ASC.Web");
var tenant = tenantManager.SetCurrentTenant(_tenantId);
var coreSettings = scope.ServiceProvider.GetService<CoreBaseSettings>();
var messageService = scope.ServiceProvider.GetService<MessageService>();
var studioNotifyService = scope.ServiceProvider.GetService<StudioNotifyService>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var userPhotoManager = scope.ServiceProvider.GetService<UserPhotoManager>();
var displayUserSettingsHelper = scope.ServiceProvider.GetService<DisplayUserSettingsHelper>();
var messageTarget = scope.ServiceProvider.GetService<MessageTarget>();
try
{
Percentage = 0;
@ -134,7 +125,7 @@ namespace ASC.Data.Reassigns
Percentage = 66;
//_projectsReassign.Reassign(_fromUserId, _toUserId);
if (!coreSettings.CustomMode)
if (!coreBaseSettings.CustomMode)
{
logger.Info("reassignment of data from crm");
@ -218,12 +209,73 @@ namespace ASC.Data.Reassigns
}
}
public class ReassignProgressItemScope
{
private TenantManager TenantManager { get; }
private CoreBaseSettings CoreBaseSettings { get; }
private MessageService MessageService { get; }
private StudioNotifyService StudioNotifyService { get; }
private SecurityContext SecurityContext { get; }
private UserManager UserManager { get; }
private UserPhotoManager UserPhotoManager { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
private MessageTarget MessageTarget { get; }
private IOptionsMonitor<ILog> Options { get; }
public ReassignProgressItemScope(TenantManager tenantManager,
CoreBaseSettings coreBaseSettings,
MessageService messageService,
StudioNotifyService studioNotifyService,
SecurityContext securityContext,
UserManager userManager,
UserPhotoManager userPhotoManager,
DisplayUserSettingsHelper displayUserSettingsHelper,
MessageTarget messageTarget,
IOptionsMonitor<ILog> options)
{
TenantManager = tenantManager;
CoreBaseSettings = coreBaseSettings;
MessageService = messageService;
StudioNotifyService = studioNotifyService;
SecurityContext = securityContext;
UserManager = userManager;
UserPhotoManager = userPhotoManager;
DisplayUserSettingsHelper = displayUserSettingsHelper;
MessageTarget = messageTarget;
Options = options;
}
public void Deconstruct(out TenantManager tenantManager,
out CoreBaseSettings coreBaseSettings,
out MessageService messageService,
out StudioNotifyService studioNotifyService,
out SecurityContext securityContext,
out UserManager userManager,
out UserPhotoManager userPhotoManager,
out DisplayUserSettingsHelper displayUserSettingsHelper,
out MessageTarget messageTarget,
out IOptionsMonitor<ILog> optionsMonitor )
{
tenantManager = TenantManager;
coreBaseSettings = CoreBaseSettings;
messageService = MessageService;
studioNotifyService = StudioNotifyService;
securityContext = SecurityContext;
userManager = UserManager;
userPhotoManager = UserPhotoManager;
displayUserSettingsHelper = DisplayUserSettingsHelper;
messageTarget = MessageTarget;
optionsMonitor = Options;
}
}
public static class ReassignProgressItemExtension
{
public static DIHelper AddReassignProgressItemService(this DIHelper services)
{
services.TryAddSingleton<ProgressQueueOptionsManager<ReassignProgressItem>>();
services.TryAddSingleton<ProgressQueue<ReassignProgressItem>>();
services.TryAddScoped<ReassignProgressItemScope>();
services.AddSingleton<IPostConfigureOptions<ProgressQueue<ReassignProgressItem>>, ConfigureProgressQueue<ReassignProgressItem>>();
return services;
}

View File

@ -96,19 +96,11 @@ namespace ASC.Data.Reassigns
public void RunJob()
{
using var scope = ServiceProvider.CreateScope();
var logger = ServiceProvider.GetService<IOptionsMonitor<ILog>>().Get("ASC.Web");
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<RemoveProgressItemScope>();
var (tenantManager, coreBaseSettings, messageService, studioNotifyService, securityContext, userManager, messageTarget, webItemManagerSecurity, storageFactory, userFormatter, options) = scopeClass;
var logger = options.Get("ASC.Web");
var tenant = tenantManager.SetCurrentTenant(_tenantId);
var messageService = scope.ServiceProvider.GetService<MessageService>();
var studioNotifyService = scope.ServiceProvider.GetService<StudioNotifyService>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var webItemManagerSecurity = scope.ServiceProvider.GetService<WebItemManagerSecurity>();
var storageFactory = scope.ServiceProvider.GetService<StorageFactory>();
var coreSettings = scope.ServiceProvider.GetService<CoreBaseSettings>();
var userFormatter = scope.ServiceProvider.GetService<UserFormatter>();
var messageTarget = scope.ServiceProvider.GetService<MessageTarget>();
var userName = userFormatter.GetUserName(User, DisplayUserNameFormat.Default);
try
@ -128,7 +120,7 @@ namespace ASC.Data.Reassigns
Percentage = 25;
//_docService.DeleteStorage(_userId);
if (!coreSettings.CustomMode)
if (!coreBaseSettings.CustomMode)
{
logger.Info("deleting of data from crm");
@ -254,6 +246,71 @@ namespace ASC.Data.Reassigns
}
}
public class RemoveProgressItemScope
{
private TenantManager TenantManager { get; }
private CoreBaseSettings CoreBaseSettings { get; }
private MessageService MessageService { get; }
private StudioNotifyService StudioNotifyService { get; }
private SecurityContext SecurityContext { get; }
private UserManager UserManager { get; }
private MessageTarget MessageTarget { get; }
private WebItemManagerSecurity WebItemManagerSecurity { get; }
private StorageFactory StorageFactory { get; }
private UserFormatter UserFormatter { get; }
private IOptionsMonitor<ILog> Options { get; }
public RemoveProgressItemScope(TenantManager tenantManager,
CoreBaseSettings coreBaseSettings,
MessageService messageService,
StudioNotifyService studioNotifyService,
SecurityContext securityContext,
UserManager userManager,
MessageTarget messageTarget,
WebItemManagerSecurity webItemManagerSecurity,
StorageFactory storageFactory,
UserFormatter userFormatter,
IOptionsMonitor<ILog> options)
{
TenantManager = tenantManager;
CoreBaseSettings = coreBaseSettings;
MessageService = messageService;
StudioNotifyService = studioNotifyService;
SecurityContext = securityContext;
UserManager = userManager;
MessageTarget = messageTarget;
WebItemManagerSecurity = webItemManagerSecurity;
StorageFactory = storageFactory;
UserFormatter = userFormatter;
Options = options;
}
public void Deconstruct(out TenantManager tenantManager,
out CoreBaseSettings coreBaseSettings,
out MessageService messageService,
out StudioNotifyService studioNotifyService,
out SecurityContext securityContext,
out UserManager userManager,
out MessageTarget messageTarget,
out WebItemManagerSecurity webItemManagerSecurity,
out StorageFactory storageFactory,
out UserFormatter userFormatter,
out IOptionsMonitor<ILog> optionsMonitor )
{
tenantManager = TenantManager;
coreBaseSettings = CoreBaseSettings;
messageService = MessageService;
studioNotifyService = StudioNotifyService;
securityContext = SecurityContext;
userManager = UserManager;
messageTarget = MessageTarget;
webItemManagerSecurity = WebItemManagerSecurity;
storageFactory = StorageFactory;
userFormatter = UserFormatter;
optionsMonitor = Options;
}
}
public static class RemoveProgressItemExtension
{
public static DIHelper AddRemoveProgressItemService(this DIHelper services)
@ -261,6 +318,7 @@ namespace ASC.Data.Reassigns
services.TryAddSingleton<ProgressQueueOptionsManager<RemoveProgressItem>>();
services.TryAddSingleton<ProgressQueue<RemoveProgressItem>>();
services.TryAddScoped<RemoveProgressItemScope>();
services.AddSingleton<IPostConfigureOptions<ProgressQueue<RemoveProgressItem>>, ConfigureProgressQueue<RemoveProgressItem>>();
return services;
}

View File

@ -50,16 +50,15 @@ namespace ASC.Data.Storage.Configuration
{
using var scope = ServiceProvider.CreateScope();
var storageSettingsHelper = scope.ServiceProvider.GetService<StorageSettingsHelper>();
var storageSettings = scope.ServiceProvider.GetService<SettingsManager>();
var settings = storageSettings.LoadForTenant<StorageSettings>(i.TenantId);
var scopeClass = scope.ServiceProvider.GetService<BaseStorageSettingsListenerScope>();
var (storageSettingsHelper, settingsManager, cdnStorageSettings) = scopeClass;
var settings = settingsManager.LoadForTenant<StorageSettings>(i.TenantId);
if (i.Name == settings.Module)
{
storageSettingsHelper.Clear(settings);
}
var cdnStorageSettings = scope.ServiceProvider.GetService<CdnStorageSettings>();
var cdnSettings = storageSettings.LoadForTenant<CdnStorageSettings>(i.TenantId);
var cdnSettings = settingsManager.LoadForTenant<CdnStorageSettings>(i.TenantId);
if (i.Name == cdnSettings.Module)
{
storageSettingsHelper.Clear(cdnSettings);
@ -211,13 +210,35 @@ namespace ASC.Data.Storage.Configuration
}
}
public class BaseStorageSettingsListenerScope
{
private StorageSettingsHelper StorageSettingsHelper { get; }
private SettingsManager SettingsManager { get; }
private CdnStorageSettings CdnStorageSettings { get; }
public BaseStorageSettingsListenerScope(StorageSettingsHelper storageSettingsHelper, SettingsManager settingsManager, CdnStorageSettings cdnStorageSettings)
{
StorageSettingsHelper = storageSettingsHelper;
SettingsManager = settingsManager;
CdnStorageSettings = cdnStorageSettings;
}
public void Deconstruct(out StorageSettingsHelper storageSettingsHelper, out SettingsManager settingsManager, out CdnStorageSettings cdnStorageSettings)
{
storageSettingsHelper = StorageSettingsHelper;
settingsManager = SettingsManager;
cdnStorageSettings = CdnStorageSettings;
}
}
public static class StorageSettingsExtension
{
public static DIHelper AddBaseStorageSettingsService(this DIHelper services)
{
services.TryAddSingleton(typeof(ICacheNotify<>), typeof(KafkaCache<>));
services.TryAddSingleton<BaseStorageSettingsListener>();
services.TryAddScoped<BaseStorageSettingsListenerScope>();
services.TryAddScoped<CdnStorageSettings>();
return services
.AddStorageFactoryConfigService()
.AddPathUtilsService()

View File

@ -112,9 +112,9 @@ namespace ASC.Data.Storage
var task = new Task<string>(() =>
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var scopeClass = scope.ServiceProvider.GetService<StaticUploaderScope>();
var(tenantManager, staticUploader, _, _, _) = scopeClass;
tenantManager.SetCurrentTenant(tenantId);
var staticUploader = scope.ServiceProvider.GetService<StaticUploader>();
return staticUploader.UploadFile(relativePath, mappedPath, onComplete);
}, TaskCreationOptions.LongRunning);
@ -208,16 +208,13 @@ namespace ASC.Data.Storage
try
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var scopeClass = scope.ServiceProvider.GetService<StaticUploaderScope>();
var (tenantManager, _, securityContext, settingsManager, storageSettingsHelper) = scopeClass;
var tenant = tenantManager.GetTenant(tenantId);
tenantManager.SetCurrentTenant(tenant);
securityContext.AuthenticateMe(tenant.OwnerId);
var SecurityContext = scope.ServiceProvider.GetService<SecurityContext>();
var SettingsManager = scope.ServiceProvider.GetService<SettingsManager>();
var StorageSettingsHelper = scope.ServiceProvider.GetService<StorageSettingsHelper>();
SecurityContext.AuthenticateMe(tenant.OwnerId);
var dataStore = StorageSettingsHelper.DataStore(SettingsManager.Load<CdnStorageSettings>());
var dataStore = storageSettingsHelper.DataStore(settingsManager.Load<CdnStorageSettings>());
if (File.Exists(mappedPath))
{
@ -287,12 +284,44 @@ namespace ASC.Data.Storage
}
}
public class StaticUploaderScope
{
private TenantManager TenantManager { get; }
private StaticUploader StaticUploader { get; }
private SecurityContext SecurityContext { get; }
private SettingsManager SettingsManager { get; }
private StorageSettingsHelper StorageSettingsHelper { get; }
public StaticUploaderScope(TenantManager tenantManager,
StaticUploader staticUploader,
SecurityContext securityContext,
SettingsManager settingsManager,
StorageSettingsHelper storageSettingsHelper)
{
TenantManager = tenantManager;
StaticUploader = staticUploader;
SecurityContext = securityContext;
SettingsManager = settingsManager;
StorageSettingsHelper = storageSettingsHelper;
}
public void Deconstruct(out TenantManager tenantManager, out StaticUploader staticUploader, out SecurityContext securityContext, out SettingsManager settingsManager, out StorageSettingsHelper storageSettingsHelper)
{
tenantManager = TenantManager;
staticUploader = StaticUploader;
securityContext = SecurityContext;
settingsManager = SettingsManager;
storageSettingsHelper = StorageSettingsHelper;
}
}
public static class StaticUploaderExtension
{
public static DIHelper AddStaticUploaderService(this DIHelper services)
{
if (services.TryAddScoped<StaticUploader>())
{
services.TryAddScoped<StaticUploaderScope>();
return services
.AddTenantManagerService()
.AddCdnStorageSettingsService();

View File

@ -66,10 +66,8 @@ namespace ASC.Data.Storage.DiscStorage
public async Task Invoke(HttpContext context)
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var storageFactory = scope.ServiceProvider.GetService<StorageFactory>();
var emailValidationKeyProvider = scope.ServiceProvider.GetService<EmailValidationKeyProvider>();
var scopeClass = scope.ServiceProvider.GetService<StorageHandlerScope>();
var (tenantManager, securityContext, storageFactory, emailValidationKeyProvider) = scopeClass;
if (_checkAuth && !securityContext.IsAuthenticated)
{
@ -148,6 +146,29 @@ namespace ASC.Data.Storage.DiscStorage
}
}
public class StorageHandlerScope
{
private TenantManager TenantManager { get; }
private SecurityContext SecurityContext { get; }
private StorageFactory StorageFactory { get; }
private EmailValidationKeyProvider EmailValidationKeyProvider { get; }
public StorageHandlerScope(TenantManager tenantManager, SecurityContext securityContext, StorageFactory storageFactory, EmailValidationKeyProvider emailValidationKeyProvider)
{
TenantManager = tenantManager;
SecurityContext = securityContext;
StorageFactory = storageFactory;
EmailValidationKeyProvider = emailValidationKeyProvider;
}
public void Deconstruct(out TenantManager tenantManager, out SecurityContext securityContext, out StorageFactory storageFactory, out EmailValidationKeyProvider emailValidationKeyProvider)
{
tenantManager = TenantManager;
securityContext = SecurityContext;
storageFactory = StorageFactory;
emailValidationKeyProvider = EmailValidationKeyProvider;
}
}
public static class StorageHandlerExtensions
{
public static IEndpointRouteBuilder RegisterStorageHandler(this IEndpointRouteBuilder builder, string module, string domain, bool publicRoute = false)
@ -175,6 +196,7 @@ namespace ASC.Data.Storage.DiscStorage
}
public static DIHelper AddStorageHandlerService(this DIHelper services)
{
services.TryAddScoped<StorageHandlerScope>();
return services
.AddTenantManagerService()
.AddSecurityContextService()

View File

@ -153,16 +153,11 @@ namespace ASC.Data.Storage
{
Log.DebugFormat("Tenant: {0}", tenantId);
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var scopeClass = scope.ServiceProvider.GetService<MigrateOperationScope>();
var (tenantManager, securityContext, storageFactory, options, storageSettingsHelper, settingsManager) = scopeClass;
var tenant = tenantManager.GetTenant(tenantId);
tenantManager.SetCurrentTenant(tenant);
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var storageFactory = scope.ServiceProvider.GetService<StorageFactory>();
var options = scope.ServiceProvider.GetService<IOptionsMonitor<ILog>>();
var storageSettingsHelper = scope.ServiceProvider.GetService<StorageSettingsHelper>();
var settingsManager = scope.ServiceProvider.GetService<SettingsManager>();
securityContext.AuthenticateMe(tenant.OwnerId);
foreach (var module in Modules)
@ -171,7 +166,7 @@ namespace ASC.Data.Storage
var store = storageFactory.GetStorageFromConsumer(ConfigPath, tenantId.ToString(), module, storageSettingsHelper.DataStoreConsumer(settings));
var domains = StorageFactoryConfig.GetDomainList(ConfigPath, module).ToList();
var crossModuleTransferUtility = new CrossModuleTransferUtility(options, oldStore, store);
var crossModuleTransferUtility = new CrossModuleTransferUtility (options, oldStore, store);
string[] files;
foreach (var domain in domains)
@ -229,4 +224,44 @@ namespace ASC.Data.Storage
CacheNotifyAction.Insert);
}
}
public class MigrateOperationScope
{
private TenantManager TenantManager { get; }
private SecurityContext SecurityContext { get; }
private StorageFactory StorageFactory { get; }
private IOptionsMonitor<ILog> Options { get; }
private StorageSettingsHelper StorageSettingsHelper { get; }
private SettingsManager SettingsManager { get; }
public MigrateOperationScope(TenantManager tenantManager,
SecurityContext securityContext,
StorageFactory storageFactory,
IOptionsMonitor<ILog> options,
StorageSettingsHelper storageSettingsHelper,
SettingsManager settingsManager)
{
TenantManager = tenantManager;
SecurityContext = securityContext;
StorageFactory = storageFactory;
Options = options;
StorageSettingsHelper = storageSettingsHelper;
SettingsManager = settingsManager;
}
public void Deconstruct(out TenantManager tenantManager,
out SecurityContext securityContext,
out StorageFactory storageFactory,
out IOptionsMonitor<ILog> options,
out StorageSettingsHelper storageSettingsHelper,
out SettingsManager settingsManager )
{
tenantManager = TenantManager;
securityContext = SecurityContext;
storageFactory = StorageFactory;
options = Options;
storageSettingsHelper = StorageSettingsHelper;
settingsManager = SettingsManager;
}
}
}

View File

@ -7,6 +7,7 @@ using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using ASC.Common;
using ASC.Common.Utils;
using CommandLine;
@ -22,7 +23,7 @@ namespace ASC.Resource.Manager
{
Parser.Default.ParseArguments<Options>(args).WithParsed(Export);
}
public static void Export(Options options)
{
var services = new ServiceCollection();
@ -30,7 +31,7 @@ namespace ASC.Resource.Manager
startup.ConfigureServices(services);
var serviceProvider = services.BuildServiceProvider();
using var scope = serviceProvider.CreateScope();
var ResourceData = scope.ServiceProvider.GetService<ResourceData>();
var scopeClass = scope.ServiceProvider.GetService<ProgramScope>();
var cultures = new List<string>();
var projects = new List<ResFile>();
@ -71,9 +72,9 @@ namespace ASC.Resource.Manager
return;
}
enabledSettings = serviceProvider.GetService<IConfiguration>().GetSetting<EnabledSettings>("enabled");
cultures = ResourceData.GetCultures().Where(r => r.Available).Select(r => r.Title).Intersect(enabledSettings.Langs).ToList();
projects = ResourceData.GetAllFiles();
enabledSettings = scopeClass.Configuration.GetSetting<EnabledSettings>("enabled");
cultures = scopeClass.ResourceData.GetCultures().Where(r => r.Available).Select(r => r.Title).Intersect(enabledSettings.Langs).ToList();
projects = scopeClass.ResourceData.GetAllFiles();
//key = CheckExist("FilesJSResource", "ASC.Files.Resources.FilesJSResource,ASC.Files");
ExportWithProject(project, module, filePath, culture, exportPath, key);
@ -189,4 +190,25 @@ namespace ASC.Resource.Manager
return string.Join(',', bag.ToArray());
}
}
public class ProgramScope
{
internal ResourceData ResourceData { get; }
internal IConfiguration Configuration { get; }
public ProgramScope(ResourceData resourceData, IConfiguration configuration)
{
ResourceData = resourceData;
Configuration = configuration;
}
}
public static class ProgramExtension
{
public static DIHelper AddProgramService(this DIHelper services)
{
services.TryAddScoped<ProgramScope>();
return services;
}
}
}

View File

@ -25,6 +25,7 @@ namespace ASC.Resource.Manager
var diHelper = new DIHelper(services);
services.AddLogging();
diHelper.TryAddScoped<ResourceData>();
diHelper.TryAddScoped<Program.Scope>();
diHelper.AddDbContextManagerService<ResourceDbContext>();
diHelper.AddLoggerService();

View File

@ -69,11 +69,9 @@ namespace ASC.Data.Backup
public void SendAboutBackupCompleted(Guid userId)
{
using var scope = ServiceProvider.CreateScope();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
var notifySource = scope.ServiceProvider.GetService<StudioNotifySource>();
var displayUserSettingsHelper = scope.ServiceProvider.GetService<DisplayUserSettingsHelper>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var scopeClass = scope.ServiceProvider.GetService<NotifyHelperScope>();
var (userManager, studioNotifyHelper, studioNotifySource, displayUserSettingsHelper) = scopeClass;
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope);
client.SendNoticeToAsync(
Actions.BackupCreated,
@ -85,11 +83,9 @@ namespace ASC.Data.Backup
public void SendAboutRestoreStarted(Tenant tenant, bool notifyAllUsers)
{
using var scope = ServiceProvider.CreateScope();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
var notifySource = scope.ServiceProvider.GetService<StudioNotifySource>();
var displayUserSettingsHelper = scope.ServiceProvider.GetService<DisplayUserSettingsHelper>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var scopeClass = scope.ServiceProvider.GetService<NotifyHelperScope>();
(var userManager, var studioNotifyHelper, var studioNotifySource, var displayUserSettingsHelper) = scopeClass;
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope);
var owner = userManager.GetUsers(tenant.OwnerId);
var users =
@ -106,11 +102,9 @@ namespace ASC.Data.Backup
public void SendAboutRestoreCompleted(Tenant tenant, bool notifyAllUsers)
{
using var scope = ServiceProvider.CreateScope();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
var notifySource = scope.ServiceProvider.GetService<StudioNotifySource>();
var displayUserSettingsHelper = scope.ServiceProvider.GetService<DisplayUserSettingsHelper>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var scopeClass = scope.ServiceProvider.GetService<NotifyHelperScope>();
var (userManager, studioNotifyHelper, studioNotifySource, displayUserSettingsHelper) = scopeClass;
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope);
var owner = userManager.GetUsers(tenant.OwnerId);
@ -129,10 +123,9 @@ namespace ASC.Data.Backup
private void MigrationNotify(Tenant tenant, INotifyAction action, string region, string url, bool notify)
{
using var scope = ServiceProvider.CreateScope();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
var notifySource = scope.ServiceProvider.GetService<StudioNotifySource>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var scopeClass = scope.ServiceProvider.GetService<NotifyHelperScope>();
var (userManager, studioNotifyHelper, studioNotifySource, _) = scopeClass;
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifySource, scope);
var users = userManager.GetUsers()
.Where(u => notify ? u.ActivationStatus.HasFlag(EmployeeActivationStatus.Activated) : u.IsOwner(tenant))
@ -150,11 +143,37 @@ namespace ASC.Data.Backup
}
}
}
public class NotifyHelperScope
{
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)
{
UserManager = userManager;
StudioNotifyHelper = studioNotifyHelper;
StudioNotifySource = studioNotifySource;
DisplayUserSettingsHelper = displayUserSettingsHelper;
}
public void Deconstruct(out UserManager userManager, out StudioNotifyHelper studioNotifyHelper, out StudioNotifySource studioNotifySource, out DisplayUserSettingsHelper displayUserSettingsHelper)
{
userManager = UserManager;
studioNotifyHelper = StudioNotifyHelper;
studioNotifySource = StudioNotifySource;
displayUserSettingsHelper = DisplayUserSettingsHelper;
}
}
public static class NotifyHelperExtension
{
public static DIHelper AddNotifyHelperService(this DIHelper services)
{
services.TryAddSingleton<NotifyHelper>();
services.TryAddScoped<NotifyHelperScope>();
return services
.AddNotifyConfiguration()

View File

@ -369,12 +369,8 @@ namespace ASC.Data.Backup.Service
}
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var backupStorageFactory = scope.ServiceProvider.GetService<BackupStorageFactory>();
var backupRepository = scope.ServiceProvider.GetService<BackupRepository>();
var notifyHelper = scope.ServiceProvider.GetService<NotifyHelper>();
var backupWorker = scope.ServiceProvider.GetService<BackupWorker>();
var scopeClass = scope.ServiceProvider.GetService<BackupWorkerScope>();
var (tenantManager, backupStorageFactory, notifyHelper, backupRepository, backupWorker, backupPortalTask, _, _) = scopeClass;
var tenant = tenantManager.GetTenant(TenantId);
var backupName = string.Format("{0}_{1:yyyy-MM-dd_HH-mm-ss}.{2}", tenant.TenantAlias, DateTime.UtcNow, ArchiveFormat);
@ -382,7 +378,7 @@ namespace ASC.Data.Backup.Service
var storagePath = tempFile;
try
{
var backupTask = scope.ServiceProvider.GetService<BackupPortalTask>();
var backupTask = backupPortalTask;
backupTask.Init(TenantId, ConfigPaths[CurrentRegion], tempFile, Limit);
if (!BackupMail)
@ -505,11 +501,8 @@ namespace ASC.Data.Backup.Service
public override void RunJob()
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var backupStorageFactory = scope.ServiceProvider.GetService<BackupStorageFactory>();
var notifyHelper = scope.ServiceProvider.GetService<NotifyHelper>();
var backupWorker = scope.ServiceProvider.GetService<BackupWorker>();
var scopeClass = scope.ServiceProvider.GetService<BackupWorkerScope>();
var (tenantManager, backupStorageFactory, notifyHelper, _, backupWorker, _, restorePortalTask, _) = scopeClass;
Tenant tenant = null;
var tempFile = PathHelper.GetTempFileName(TempFolder);
try
@ -528,7 +521,7 @@ namespace ASC.Data.Backup.Service
columnMapper.SetMapping("tenants_tenants", "alias", tenant.TenantAlias, ((Guid)Id).ToString("N"));
columnMapper.Commit();
var restoreTask = scope.ServiceProvider.GetService<RestorePortalTask>();
var restoreTask = restorePortalTask;
restoreTask.Init(ConfigPaths[CurrentRegion], tempFile, TenantId, columnMapper, UpgradesPath);
restoreTask.ProgressChanged += (sender, args) =>
{
@ -667,10 +660,8 @@ namespace ASC.Data.Backup.Service
public override void RunJob()
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var notifyHelper = scope.ServiceProvider.GetService<NotifyHelper>();
var backupWorker = scope.ServiceProvider.GetService<BackupWorker>();
var scopeClass = scope.ServiceProvider.GetService<BackupWorkerScope>();
var (tenantManager, _, notifyHelper, _, backupWorker, _, _, transferPortalTask) = scopeClass;
var tempFile = PathHelper.GetTempFileName(TempFolder);
var tenant = tenantManager.GetTenant(TenantId);
var alias = tenant.TenantAlias;
@ -678,7 +669,7 @@ namespace ASC.Data.Backup.Service
try
{
notifyHelper.SendAboutTransferStart(tenant, TargetRegion, Notify);
var transferProgressItem = scope.ServiceProvider.GetService<TransferPortalTask>();
var transferProgressItem = transferPortalTask;
transferProgressItem.Init(TenantId, ConfigPaths[CurrentRegion], ConfigPaths[TargetRegion], Limit, TempFolder);
transferProgressItem.ProgressChanged += (sender, args) =>
{
@ -735,11 +726,9 @@ namespace ASC.Data.Backup.Service
public class FactoryProgressItem
{
private IServiceProvider ServiceProvider { get; set; }
public IServiceProvider ServiceProvider { get; }
public FactoryProgressItem(
IServiceProvider serviceProvider
)
public FactoryProgressItem(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
@ -770,6 +759,7 @@ namespace ASC.Data.Backup.Service
item.Init(schedule, isScheduled, tempFolder, limit, currentRegion, configPaths);
return item;
}
public RestoreProgressItem CreateRestoreProgressItem(
StartRestoreRequest request,
string tempFolder,
@ -799,6 +789,57 @@ namespace ASC.Data.Backup.Service
return item;
}
}
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; }
public BackupWorkerScope(TenantManager tenantManager,
BackupStorageFactory backupStorageFactory,
NotifyHelper notifyHelper,
BackupRepository backupRepository,
BackupWorker backupWorker,
BackupPortalTask backupPortalTask,
RestorePortalTask restorePortalTask,
TransferPortalTask transferPortalTask)
{
TenantManager = tenantManager;
BackupStorageFactory = backupStorageFactory;
NotifyHelper = notifyHelper;
BackupRepository = backupRepository;
BackupWorker = backupWorker;
BackupPortalTask = backupPortalTask;
RestorePortalTask = restorePortalTask;
TransferPortalTask = transferPortalTask;
}
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)
{
tenantManager = TenantManager;
backupStorageFactory = BackupStorageFactory;
notifyHelper = NotifyHelper;
backupRepository = BackupRepository;
backupWorker = BackupWorker;
backupPortalTask = BackupPortalTask;
restorePortalTask = RestorePortalTask;
transferPortalTask = TransferPortalTask;
}
}
public static class BackupWorkerExtension
{
public static DIHelper AddBackupWorkerService(this DIHelper services)
@ -808,8 +849,7 @@ namespace ASC.Data.Backup.Service
services.TryAddTransient<BackupProgressItem>();
services.TryAddTransient<TransferProgressItem>();
services.TryAddTransient<RestoreProgressItem>();
services.TryAddScoped<BackupWorkerScope>();
services.TryAddSingleton<ProgressQueueOptionsManager<BaseBackupProgressItem>>();
services.TryAddSingleton<ProgressQueue<BaseBackupProgressItem>>();
services.AddSingleton<IPostConfigureOptions<ProgressQueue<BaseBackupProgressItem>>, ConfigureProgressQueue<BaseBackupProgressItem>>();
@ -823,7 +863,8 @@ namespace ASC.Data.Backup.Service
.AddNotifyHelperService()
.AddBackupPortalTaskService()
.AddDbFactoryService()
.AddRestorePortalTaskService();
.AddRestorePortalTaskService()
.AddTransferPortalTaskService();
}
}
}

View File

@ -29,6 +29,7 @@ using System.Data.Common;
using System.IO;
using System.Linq;
using ASC.Common;
using ASC.Common.Logging;
using ASC.Core.Tenants;
using ASC.Data.Backup.Extensions;
@ -250,5 +251,19 @@ namespace ASC.Data.Backup.Tasks
return Path.Combine(BackupDirectory ?? DefaultDirectoryName, tenantAlias + DateTime.UtcNow.ToString("(yyyy-MM-dd HH-mm-ss)") + ".backup");
}
}
public static class TransferPortalTaskExtension
{
public static DIHelper AddTransferPortalTaskService(this DIHelper services)
{
services.TryAddScoped<TransferPortalTask>();
return services
.AddStorageFactoryConfigService()
.AddBackupPortalTaskService()
.AddDbFactoryService()
.AddRestorePortalTaskService();
}
}
}

View File

@ -92,9 +92,8 @@ namespace ASC.ElasticSearch
var task = new Task(async () =>
{
using var scope = ServiceProvider.CreateScope();
var factoryIndexer = scope.ServiceProvider.GetService<FactoryIndexer>();
var service = scope.ServiceProvider.GetService<Service.Service>();
var scopeClass = scope.ServiceProvider.GetService<ServiceLauncherScope>();
var (factoryIndexer, service) = scopeClass;
while (!factoryIndexer.CheckState(false))
{
if (CancellationTokenSource.IsCancellationRequested)
@ -181,12 +180,32 @@ namespace ASC.ElasticSearch
}
}
public class ServiceLauncherScope
{
private FactoryIndexer FactoryIndexer { get; }
private Service.Service Service { get; }
public ServiceLauncherScope(FactoryIndexer factoryIndexer, Service.Service service)
{
FactoryIndexer = factoryIndexer;
Service = service;
}
public void Deconstruct(out FactoryIndexer factoryIndexer, out Service.Service service)
{
factoryIndexer = FactoryIndexer;
service = Service;
}
}
public static class ServiceLauncherExtension
{
public static DIHelper AddServiceLauncher(this DIHelper services)
{
services.TryAddSingleton<ServiceLauncher>();
services.TryAddScoped<ServiceLauncherScope>();
services.TryAddSingleton<Service.Service>();
services.TryAddScoped<ServiceScope>();
return services
.AddSettingsService()

View File

@ -87,14 +87,12 @@ namespace ASC.ElasticSearch.Service
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
tenantManager.SetCurrentTenant(tenant);
var settingsManager = scope.ServiceProvider.GetService<SettingsManager>();
var scopeClass = scope.ServiceProvider.GetService<ServiceScope>();
var (tenantManager, settingsManager) = scopeClass;
tenantManager.SetCurrentTenant(tenant);
settingsManager.ClearCache<SearchSettings>();
});
}
//public State GetState()
//{
// return new State
@ -104,4 +102,22 @@ namespace ASC.ElasticSearch.Service
// };
//}
}
public class ServiceScope
{
private TenantManager TenantManager { get; }
private SettingsManager SettingsManager { get; }
public ServiceScope(TenantManager tenantManager, SettingsManager settingsManager)
{
TenantManager = tenantManager;
SettingsManager = settingsManager;
}
public void Deconstruct(out TenantManager tenantManager, out SettingsManager settingsManager)
{
tenantManager = TenantManager;
settingsManager = SettingsManager;
}
}
}

View File

@ -121,11 +121,9 @@ namespace ASC.Feed.Aggregator
{
var cfg = FeedSettings.GetInstance(Configuration);
using var scope = ServiceProvider.CreateScope();
var commonLinkUtility = scope.ServiceProvider.GetService<BaseCommonLinkUtility>();
commonLinkUtility.Initialize(cfg.ServerRoot);
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var feedAggregateDataProvider = scope.ServiceProvider.GetService<FeedAggregateDataProvider>();
var scopeClass = scope.ServiceProvider.GetService<FeedAggregatorServiceScope>();
var (baseCommonLinkUtility, tenantManager, feedAggregateDataProvider, userManager, securityContext, authManager) = scopeClass;
baseCommonLinkUtility.Initialize(cfg.ServerRoot);
var start = DateTime.UtcNow;
Log.DebugFormat("Start of collecting feeds...");
@ -161,9 +159,6 @@ namespace ASC.Feed.Aggregator
}
tenantManager.SetCurrentTenant(tenant);
var userManager = scope.ServiceProvider.GetService<UserManager>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var authManager = scope.ServiceProvider.GetService<AuthManager>();
var users = userManager.GetUsers();
var feeds = Attempt(10, () => module.GetFeeds(new FeedFilter(fromTime, toTime) { Tenant = tenant }).Where(r => r.Item1 != null).ToList());
@ -293,11 +288,52 @@ namespace ASC.Feed.Aggregator
}
}
public class FeedAggregatorServiceScope
{
private BaseCommonLinkUtility BaseCommonLinkUtility { get; }
private TenantManager TenantManager { get; }
private FeedAggregateDataProvider FeedAggregateDataProvider { get; }
private UserManager UserManager { get; }
private SecurityContext SecurityContext { get; }
private AuthManager AuthManager { get; }
public FeedAggregatorServiceScope(BaseCommonLinkUtility baseCommonLinkUtility,
TenantManager tenantManager,
FeedAggregateDataProvider feedAggregateDataProvider,
UserManager userManager,
SecurityContext securityContext,
AuthManager authManager)
{
BaseCommonLinkUtility = baseCommonLinkUtility;
TenantManager = tenantManager;
FeedAggregateDataProvider = feedAggregateDataProvider;
UserManager = userManager;
SecurityContext = securityContext;
AuthManager = authManager;
}
public void Deconstruct(out BaseCommonLinkUtility baseCommonLinkUtility,
out TenantManager tenantManager,
out FeedAggregateDataProvider feedAggregateDataProvider,
out UserManager userManager,
out SecurityContext securityContext,
out AuthManager authManager)
{
baseCommonLinkUtility = BaseCommonLinkUtility;
tenantManager = TenantManager;
feedAggregateDataProvider = FeedAggregateDataProvider;
userManager = UserManager;
securityContext = SecurityContext;
authManager = AuthManager;
}
}
public static class FeedAggregatorServiceExtension
{
public static DIHelper AddFeedAggregatorService(this DIHelper services)
{
services.TryAddSingleton<FeedAggregatorService>();
services.TryAddScoped<FeedAggregatorServiceScope>();
return services
.AddBaseCommonLinkUtilityService()

View File

@ -79,6 +79,7 @@ namespace ASC.Notify
log.Error(e);
}
}
public void InvokeSendMethod(string service, string method, int tenant, params object[] parameters)
{
@ -98,9 +99,8 @@ namespace ASC.Notify
}
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var tenantWhiteLabelSettingsHelper = scope.ServiceProvider.GetService<TenantWhiteLabelSettingsHelper>();
var settingsManager = scope.ServiceProvider.GetService<SettingsManager>();
var scopeClass = scope.ServiceProvider.GetService<NotifyServiceScope>();
var (tenantManager, tenantWhiteLabelSettingsHelper, settingsManager) = scopeClass;
tenantManager.SetCurrentTenant(tenant);
tenantWhiteLabelSettingsHelper.Apply(settingsManager.Load<TenantWhiteLabelSettings>(), tenant);
methodInfo.Invoke(instance, parameters);
@ -112,11 +112,33 @@ namespace ASC.Notify
}
}
public class NotifyServiceScope
{
private TenantManager TenantManager { get; }
private TenantWhiteLabelSettingsHelper TenantWhiteLabelSettingsHelper { get; }
private SettingsManager SettingsManager { get; }
public NotifyServiceScope(TenantManager tenantManager, TenantWhiteLabelSettingsHelper tenantWhiteLabelSettingsHelper, SettingsManager settingsManager)
{
TenantManager = tenantManager;
TenantWhiteLabelSettingsHelper = tenantWhiteLabelSettingsHelper;
SettingsManager = settingsManager;
}
public void Deconstruct(out TenantManager tenantManager, out TenantWhiteLabelSettingsHelper tenantWhiteLabelSettingsHelper, out SettingsManager settingsManager)
{
tenantManager = TenantManager;
tenantWhiteLabelSettingsHelper = TenantWhiteLabelSettingsHelper;
settingsManager = SettingsManager;
}
}
public static class NotifyServiceExtension
{
public static DIHelper AddNotifyService(this DIHelper services)
{
services.TryAddSingleton<NotifyService>();
services.TryAddScoped<NotifyServiceScope>();
services.TryAddSingleton(typeof(ICacheNotify<>), typeof(KafkaCache<>));
return services

View File

@ -41,11 +41,11 @@
"type": "ASC.FederatedLogin.LoginProviders.BoxLoginProvider, ASC.FederatedLogin"
},
{
"key": "box",
"key": "Box",
"type": "ASC.Core.Common.Configuration.Consumer, ASC.Core.Common"
},
{
"key": "box",
"key": "Box",
"type": "ASC.FederatedLogin.LoginProviders.BoxLoginProvider, ASC.FederatedLogin"
}
],
@ -191,11 +191,11 @@
"type": "ASC.FederatedLogin.LoginProviders.FacebookLoginProvider, ASC.FederatedLogin"
},
{
"key": "facebook",
"key": "Facebook",
"type": "ASC.Core.Common.Configuration.Consumer, ASC.Core.Common"
},
{
"key": "facebook",
"key": "Facebook",
"type": "ASC.FederatedLogin.LoginProviders.FacebookLoginProvider, ASC.FederatedLogin"
}
],
@ -252,11 +252,11 @@
"type": "ASC.FederatedLogin.LoginProviders.GoogleLoginProvider, ASC.FederatedLogin"
},
{
"key": "google",
"key": "Google",
"type": "ASC.Core.Common.Configuration.Consumer, ASC.Core.Common"
},
{
"key": "google",
"key": "Google",
"type": "ASC.FederatedLogin.LoginProviders.GoogleLoginProvider, ASC.FederatedLogin"
}
],
@ -283,11 +283,11 @@
"type": "ASC.FederatedLogin.LoginProviders.LinkedInLoginProvider, ASC.FederatedLogin"
},
{
"key": "linkedin",
"key": "LinkedIn",
"type": "ASC.Core.Common.Configuration.Consumer, ASC.Core.Common"
},
{
"key": "linkedin",
"key": "LinkedIn",
"type": "ASC.FederatedLogin.LoginProviders.LinkedInLoginProvider, ASC.FederatedLogin"
}
],
@ -406,11 +406,11 @@
"type": "ASC.FederatedLogin.LoginProviders.TwitterLoginProvider, ASC.FederatedLogin"
},
{
"key": "twitter",
"key": "Twitter",
"type": "ASC.Core.Common.Configuration.Consumer, ASC.Core.Common"
},
{
"key": "twitter",
"key": "Twitter",
"type": "ASC.FederatedLogin.LoginProviders.TwitterLoginProvider, ASC.FederatedLogin"
}
],

View File

@ -124,12 +124,12 @@ namespace ASC.Files.Thirdparty.ProviderDao
fromFileId, fromSelector.GetFileDao(fromFileId), fromSelector.ConvertId,
toFolderId, toSelector.GetFileDao(toFolderId), toSelector.ConvertId,
deleteSourceFile);
}
}
protected File<int> PerformCrossDaoFileCopy(string fromFileId, int toFolderId, bool deleteSourceFile)
{
var fromSelector = GetSelector(fromFileId);
using var scope = ServiceProvider.CreateScope();
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
tenantManager.SetCurrentTenant(TenantID);
@ -153,7 +153,7 @@ namespace ASC.Files.Thirdparty.ProviderDao
protected Folder<int> PerformCrossDaoFolderCopy(string fromFolderId, int toRootFolderId, bool deleteSourceFolder, CancellationToken? cancellationToken)
{
var fromSelector = GetSelector(fromFolderId);
using var scope = ServiceProvider.CreateScope();
using var scope = ServiceProvider.CreateScope();
return CrossDao.PerformCrossDaoFolderCopy(
fromFolderId, fromSelector.GetFolderDao(fromFolderId), fromSelector.GetFileDao(fromFolderId), fromSelector.ConvertId,

View File

@ -150,19 +150,16 @@ namespace ASC.Web.Files.Services.DocumentService
};
}
public void GenerateReport(DistributedTask task, CancellationToken cancellationToken)
{
using var scope = ServiceProvider.CreateScope();
var logger = scope.ServiceProvider.GetService<IOptionsMonitor<ILog>>().CurrentValue;
var scopeClass = scope.ServiceProvider.GetService<ReportStateScope>();
var (options, tenantManager, authContext, securityContext, documentServiceConnector) = scopeClass;
var logger = options.CurrentValue;
try
{
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
tenantManager.SetCurrentTenant(TenantId);
var authContext = scope.ServiceProvider.GetService<AuthContext>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var documentServiceConnector = scope.ServiceProvider.GetService<DocumentServiceConnector>();
Status = ReportStatus.Started;
PublishTaskInfo(logger);
@ -361,4 +358,40 @@ namespace ASC.Web.Files.Services.DocumentService
public void Terminate(ReportOrigin origin) => DocbuilderReportsUtility.Terminate(origin, TenantId, UserId);
public ReportState Status(ReportOrigin origin) => DocbuilderReportsUtility.Status(origin, HttpContextAccessor, TenantId, UserId);
}
public class ReportStateScope
{
private IOptionsMonitor<ILog> Options { get; }
private TenantManager TenantManager { get; }
private AuthContext AuthContext { get; }
private SecurityContext SecurityContext { get; }
private DocumentServiceConnector DocumentServiceConnector { get; }
public ReportStateScope(
IOptionsMonitor<ILog> options,
TenantManager tenantManager,
AuthContext authContext,
SecurityContext securityContext,
DocumentServiceConnector documentServiceConnector)
{
Options = options;
TenantManager = tenantManager;
AuthContext = authContext;
SecurityContext = securityContext;
DocumentServiceConnector = documentServiceConnector;
}
public void Deconstruct(out IOptionsMonitor<ILog> optionsMonitor,
out TenantManager tenantManager,
out AuthContext authContext,
out SecurityContext securityContext,
out DocumentServiceConnector documentServiceConnector)
{
optionsMonitor = Options;
tenantManager = TenantManager;
authContext = AuthContext;
securityContext = SecurityContext;
documentServiceConnector = DocumentServiceConnector;
}
}
}

View File

@ -150,7 +150,7 @@ namespace ASC.Files.Core.Services.NotifyService {
/// &lt;subject resource=&quot;|subject_DocuSignComplete|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core&quot; /&gt;
/// &lt;body styler=&quot;ASC.Notify.Textile.TextileStyler,ASC.Notify.Textile&quot; resource=&quot;|pattern_DocuSignComplete|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core&quot; /&gt;
/// &lt;/pattern&gt;
/// &lt;pattern id=&quot;DocuSignComplete&quot; se [rest of string was truncated]&quot;;.
/// &lt;pattern id=&quot;DocuSignComplete&quot; [rest of string was truncated]&quot;;.
/// </summary>
public static string patterns {
get {

View File

@ -51,17 +51,13 @@ namespace ASC.Files.Core.Services.NotifyService
{
ServiceProvider = serviceProvider;
}
public void SendDocuSignComplete<T>(File<T> file, string sourceTitle)
{
using var scope = ServiceProvider.CreateScope();
var notifySource = scope.ServiceProvider.GetService<NotifySource>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var filesLinkUtility = scope.ServiceProvider.GetService<FilesLinkUtility>();
var fileUtility = scope.ServiceProvider.GetService<FileUtility>();
var baseCommonLinkUtility = scope.ServiceProvider.GetService<BaseCommonLinkUtility>();
var scopeClass = scope.ServiceProvider.GetService<NotifyClientScope>();
var (notifySource, securityContext, filesLinkUtility, fileUtility, baseCommonLinkUtility, _, _, _, _) = scopeClass;
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var recipient = notifySource.GetRecipientsProvider().GetRecipient(securityContext.CurrentAccount.ID.ToString());
client.SendNoticeAsync(
@ -78,8 +74,8 @@ namespace ASC.Files.Core.Services.NotifyService
public void SendDocuSignStatus(string subject, string status)
{
using var scope = ServiceProvider.CreateScope();
var notifySource = scope.ServiceProvider.GetService<NotifySource>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var scopeClass = scope.ServiceProvider.GetService<NotifyClientScope>();
var (notifySource, securityContext, _, _, _, _, _, _, _) = scopeClass;
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var recipient = notifySource.GetRecipientsProvider().GetRecipient(securityContext.CurrentAccount.ID.ToString());
@ -117,14 +113,8 @@ namespace ASC.Files.Core.Services.NotifyService
if (fileEntry == null || recipients.Count == 0) return;
using var scope = ServiceProvider.CreateScope();
var notifySource = scope.ServiceProvider.GetService<NotifySource>();
var daoFactory = scope.ServiceProvider.GetService<IDaoFactory>();
var filesLinkUtility = scope.ServiceProvider.GetService<FilesLinkUtility>();
var fileUtility = scope.ServiceProvider.GetService<FileUtility>();
var pathProvider = scope.ServiceProvider.GetService<PathProvider>();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var baseCommonLinkUtility = scope.ServiceProvider.GetService<BaseCommonLinkUtility>();
var scopeClass = scope.ServiceProvider.GetService<NotifyClientScope>();
var (notifySource, _, filesLinkUtility, fileUtility, baseCommonLinkUtility, daoFactory, pathProvider, userManager, tenantManager) = scopeClass;
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var folderDao = daoFactory.GetFolderDao<T>();
@ -165,9 +155,8 @@ namespace ASC.Files.Core.Services.NotifyService
if (file == null || recipientIds.Count == 0) return;
using var scope = ServiceProvider.CreateScope();
var notifySource = scope.ServiceProvider.GetService<NotifySource>();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var baseCommonLinkUtility = scope.ServiceProvider.GetService<BaseCommonLinkUtility>();
var scopeClass = scope.ServiceProvider.GetService<NotifyClientScope>();
var (notifySource, _, _, _, baseCommonLinkUtility, _, _, userManager, _) = scopeClass;
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var recipientsProvider = notifySource.GetRecipientsProvider();
@ -210,13 +199,68 @@ namespace ASC.Files.Core.Services.NotifyService
}
}
public class NotifyClientScope
{
private NotifySource NotifySource { get; }
private SecurityContext SecurityContext { get; }
private FilesLinkUtility FilesLinkUtility { get; }
private FileUtility FileUtility { get; }
private BaseCommonLinkUtility BaseCommonLinkUtility { get; }
private IDaoFactory DaoFactory { get; }
private PathProvider PathProvider { get; }
private UserManager UserManager { get; }
private TenantManager TenantManager { get; }
public NotifyClientScope(NotifySource notifySource,
SecurityContext securityContext,
FilesLinkUtility filesLinkUtility,
FileUtility fileUtility,
BaseCommonLinkUtility baseCommonLinkUtility,
IDaoFactory daoFactory,
PathProvider pathProvider,
UserManager userManager,
TenantManager tenantManager)
{
NotifySource = notifySource;
SecurityContext = securityContext;
FilesLinkUtility = filesLinkUtility;
FileUtility = fileUtility;
BaseCommonLinkUtility = baseCommonLinkUtility;
DaoFactory = daoFactory;
PathProvider = pathProvider;
UserManager = userManager;
TenantManager = tenantManager;
}
public void Deconstruct(out NotifySource notifySource,
out SecurityContext securityContext,
out FilesLinkUtility filesLinkUtility,
out FileUtility fileUtility,
out BaseCommonLinkUtility baseCommonLinkUtility,
out IDaoFactory daoFactory,
out PathProvider pathProvider,
out UserManager userManager,
out TenantManager tenantManager )
{
notifySource = NotifySource;
securityContext = SecurityContext;
filesLinkUtility = FilesLinkUtility;
fileUtility = FileUtility;
baseCommonLinkUtility = BaseCommonLinkUtility;
daoFactory = DaoFactory;
pathProvider = PathProvider;
userManager = UserManager;
tenantManager = TenantManager;
}
}
public static class NotifyClientExtension
{
public static DIHelper AddNotifyClientService(this DIHelper services)
{
if (services.TryAddScoped<NotifyClient>())
{
services.TryAddScoped<NotifyClientScope>();
return services
.AddFilesNotifySourceService()
.AddBaseCommonLinkUtilityService()

View File

@ -120,12 +120,11 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
DeleteFiles(Files, scope);
DeleteFolders(Folders, scope);
}
private void DeleteFolders(IEnumerable<T> folderIds, IServiceScope scope)
{
var fileMarker = scope.ServiceProvider.GetService<FileMarker>();
var filesMessageService = scope.ServiceProvider.GetService<FilesMessageService>();
var scopeClass = scope.ServiceProvider.GetService<FileDeleteOperationScope>();
var (fileMarker, filesMessageService) = scopeClass;
foreach (var folderId in folderIds)
{
CancellationToken.ThrowIfCancellationRequested();
@ -208,9 +207,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
private void DeleteFiles(IEnumerable<T> fileIds, IServiceScope scope)
{
var fileMarker = scope.ServiceProvider.GetService<FileMarker>();
var filesMessageService = scope.ServiceProvider.GetService<FilesMessageService>();
var scopeClass = scope.ServiceProvider.GetService<FileDeleteOperationScope>();
var (fileMarker, filesMessageService) = scopeClass;
foreach (var fileId in fileIds)
{
CancellationToken.ThrowIfCancellationRequested();
@ -277,4 +275,22 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
return false;
}
}
public class FileDeleteOperationScope
{
private FileMarker FileMarker { get; }
private FilesMessageService FilesMessageService { get; }
public FileDeleteOperationScope(FileMarker fileMarker, FilesMessageService filesMessageService)
{
FileMarker = fileMarker;
FilesMessageService = filesMessageService;
}
public void Deconstruct(out FileMarker fileMarker, out FilesMessageService filesMessageService)
{
fileMarker = FileMarker;
filesMessageService = FilesMessageService;
}
}
}

View File

@ -81,9 +81,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
base.RunJob(_, cancellationToken);
using var scope = ThirdPartyOperation.CreateScope();
var globalStore = scope.ServiceProvider.GetService<GlobalStore>();
var filesLinkUtility = scope.ServiceProvider.GetService<FilesLinkUtility>();
var scopeClass = scope.ServiceProvider.GetService<FileDownloadOperationScope>();
var (globalStore, filesLinkUtility, _, _, _) = scopeClass;
using var stream = TempStream.Create();
using (var zip = new ZipOutputStream(stream, true)
{
@ -135,7 +134,6 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
Compress = compress;
}
protected override void Do(IServiceScope scope)
{
if (!Compress && !Files.Any() && !Folders.Any()) return;
@ -151,9 +149,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
throw new DirectoryNotFoundException(FilesCommonResource.ErrorMassage_FolderNotFound);
}
var globalStore = scope.ServiceProvider.GetService<GlobalStore>();
var filesLinkUtility = scope.ServiceProvider.GetService<FilesLinkUtility>();
var scopeClass = scope.ServiceProvider.GetService<FileDownloadOperationScope>();
var (globalStore, filesLinkUtility, _, _, _) = scopeClass;
ReplaceLongPath(entriesPathId);
if (Compress)
@ -265,9 +262,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
internal void CompressToZip(ZipOutputStream zip, Stream stream, IServiceScope scope)
{
if (entriesPathId == null) return;
var setupInfo = scope.ServiceProvider.GetService<SetupInfo>();
var fileConverter = scope.ServiceProvider.GetService<FileConverter>();
var filesMessageService = scope.ServiceProvider.GetService<FilesMessageService>();
var scopeClass = scope.ServiceProvider.GetService<FileDownloadOperationScope>();
var (_, _, setupInfo, fileConverter, filesMessageService) = scopeClass;
var FileDao = scope.ServiceProvider.GetService<IFileDao<T>>();
foreach (var path in entriesPathId.AllKeys)
@ -439,4 +435,32 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
dic.Remove(name);
}
}
public class FileDownloadOperationScope
{
private GlobalStore GlobalStore { get; }
private FilesLinkUtility FilesLinkUtility { get; }
private SetupInfo SetupInfo { get; }
private FileConverter FileConverter { get; }
private FilesMessageService FilesMessageService { get; }
public FileDownloadOperationScope(GlobalStore globalStore, FilesLinkUtility filesLinkUtility, SetupInfo setupInfo, FileConverter fileConverter, FilesMessageService filesMessageService)
{
GlobalStore = globalStore;
FilesLinkUtility = filesLinkUtility;
SetupInfo = setupInfo;
FileConverter = fileConverter;
FilesMessageService = filesMessageService;
}
public void Deconstruct(out GlobalStore globalStore, out FilesLinkUtility filesLinkUtility, out SetupInfo setupInfo, out FileConverter fileConverter, out FilesMessageService filesMessageService)
{
globalStore = GlobalStore;
filesLinkUtility = FilesLinkUtility;
setupInfo = SetupInfo;
fileConverter = FileConverter;
filesMessageService = FilesMessageService;
}
}
}

View File

@ -84,7 +84,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
protected override void Do(IServiceScope scope)
{
var fileMarker = scope.ServiceProvider.GetService<FileMarker>();
var scopeClass = scope.ServiceProvider.GetService<FileMarkAsReadOperationScope>();
var (fileMarker, globalFolder, daoFactory) = scopeClass;
var entries = new List<FileEntry<T>>();
if (Folders.Any())
{
@ -111,8 +112,6 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
ProgressStep();
});
var globalFolder = scope.ServiceProvider.GetService<GlobalFolder>();
var daoFactory = scope.ServiceProvider.GetService<IDaoFactory>();
var rootIds = new List<int>
{
globalFolder.GetFolderMy(fileMarker, daoFactory),
@ -128,4 +127,25 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
Status += string.Join(SPLIT_CHAR, newrootfolder.ToArray());
}
}
public class FileMarkAsReadOperationScope
{
private FileMarker FileMarker { get; }
private GlobalFolder GlobalFolder { get; }
private IDaoFactory DaoFactory { get; }
public FileMarkAsReadOperationScope(FileMarker fileMarker, GlobalFolder globalFolder, IDaoFactory daoFactory)
{
FileMarker = fileMarker;
GlobalFolder = globalFolder;
DaoFactory = daoFactory;
}
public void Deconstruct(out FileMarker fileMarker, out GlobalFolder globalFolder, out IDaoFactory daoFactory)
{
fileMarker = FileMarker;
globalFolder = GlobalFolder;
daoFactory = DaoFactory;
}
}
}

View File

@ -129,8 +129,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
{
Do(scope, ThirdpartyFolderId);
}
}
}
private void Do<TTo>(IServiceScope scope, TTo tto)
{
var fileMarker = scope.ServiceProvider.GetService<FileMarker>();
@ -164,16 +164,16 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
needToMark.AddRange(MoveOrCopyFiles(scope, Files, toFolder, _copy));
needToMark.Distinct().ToList().ForEach(x => fileMarker.MarkAsNew(x));
}
}
private List<FileEntry<TTo>> MoveOrCopyFolders<TTo>(IServiceScope scope, List<T> folderIds, Folder<TTo> toFolder, bool copy)
{
var needToMark = new List<FileEntry<TTo>>();
if (folderIds.Count == 0) return needToMark;
var filesMessageService = scope.ServiceProvider.GetService<FilesMessageService>();
var fileMarker = scope.ServiceProvider.GetService<FileMarker>();
var scopeClass = scope.ServiceProvider.GetService<FileMoveCopyOperationScope>();
var (filesMessageService, fileMarker, _, _, _) = scopeClass;
var folderDao = scope.ServiceProvider.GetService<IFolderDao<TTo>>();
var toFolderId = toFolder.ID;
@ -354,11 +354,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
if (fileIds.Count == 0) return needToMark;
var filesMessageService = scope.ServiceProvider.GetService<FilesMessageService>();
var fileMarker = scope.ServiceProvider.GetService<FileMarker>();
var fileUtility = scope.ServiceProvider.GetService<FileUtility>();
var global = scope.ServiceProvider.GetService<Global>();
var entryManager = scope.ServiceProvider.GetService<EntryManager>();
var scopeClass = scope.ServiceProvider.GetService<FileMoveCopyOperationScope>();
var (filesMessageService, fileMarker, fileUtility, global, entryManager) = scopeClass;
var fileDao = scope.ServiceProvider.GetService<IFileDao<TTo>>();
var toFolderId = toFolder.ID;
@ -574,4 +571,31 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
return false;
}
}
public class FileMoveCopyOperationScope
{
private FilesMessageService FilesMessageService { get; }
private FileMarker FileMarker { get; }
private FileUtility FileUtility { get; }
private Global Global { get; }
private EntryManager EntryManager { get; }
public FileMoveCopyOperationScope(FilesMessageService filesMessageService, FileMarker fileMarker, FileUtility fileUtility, Global global, EntryManager entryManager)
{
FilesMessageService = filesMessageService;
FileMarker = fileMarker;
FileUtility = fileUtility;
Global = global;
EntryManager = entryManager;
}
public void Deconstruct(out FilesMessageService filesMessageService, out FileMarker fileMarker, out FileUtility fileUtility, out Global global, out EntryManager entryManager)
{
filesMessageService = FilesMessageService;
fileMarker = FileMarker;
fileUtility = FileUtility;
global = Global;
entryManager = EntryManager;
}
}
}

View File

@ -108,6 +108,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
public abstract void RunJob(DistributedTask _, CancellationToken cancellationToken);
protected abstract void Do(IServiceScope serviceScope);
}
internal class ComposeFileOperation<T1, T2> : FileOperation
@ -274,7 +275,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
Total = InitTotalProgressSteps();
Source = string.Join(SPLIT_CHAR, Folders.Select(f => "folder_" + f).Concat(Files.Select(f => "file_" + f)).ToArray());
}
public override void RunJob(DistributedTask _, CancellationToken cancellationToken)
{
try
@ -283,11 +284,9 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
CancellationToken = cancellationToken;
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var scopeClass = scope.ServiceProvider.GetService<FileOperationScope>();
var (tenantManager, daoFactory, fileSecurity, options) = scopeClass;
tenantManager.SetCurrentTenant(CurrentTenant);
var daoFactory = scope.ServiceProvider.GetService<IDaoFactory>();
var fileSecurity = scope.ServiceProvider.GetService<FileSecurity>();
var logger = scope.ServiceProvider.GetService<IOptionsMonitor<ILog>>().CurrentValue;
Thread.CurrentPrincipal = principal;
@ -300,7 +299,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
ProviderDao = daoFactory.ProviderDao;
FilesSecurity = fileSecurity;
Logger = logger;
Logger = options.CurrentValue;
Do(scope);
}
@ -392,4 +391,28 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
TaskInfo.PublishChanges();
}
}
public class FileOperationScope
{
private TenantManager TenantManager { get; }
private IDaoFactory DaoFactory { get; }
private FileSecurity FileSecurity { get; }
private IOptionsMonitor<ILog> Options { get; }
public FileOperationScope(TenantManager tenantManager, IDaoFactory daoFactory, FileSecurity fileSecurity, IOptionsMonitor<ILog> options)
{
TenantManager = tenantManager;
DaoFactory = daoFactory;
FileSecurity = fileSecurity;
Options = options;
}
public void Deconstruct(out TenantManager tenantManager, out IDaoFactory daoFactory, out FileSecurity fileSecurity, out IOptionsMonitor<ILog> optionsMonitor )
{
tenantManager = TenantManager;
daoFactory = DaoFactory;
fileSecurity = FileSecurity;
optionsMonitor = Options;
}
}
}

View File

@ -239,6 +239,11 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
{
services.TryAddSingleton<DistributedTaskCacheNotify>();
services.TryAddSingleton<FileOperationsManager>();
services.TryAddScoped<FileDeleteOperationScope>();
services.TryAddScoped<FileMarkAsReadOperationScope>();
services.TryAddScoped<FileMoveCopyOperationScope>();
services.TryAddScoped<FileOperationScope>();
services.TryAddScoped<FileDownloadOperationScope>();
return services
.AddAuthContextService()

View File

@ -138,25 +138,15 @@ namespace ASC.Web.Files.Utils
var result = cache.Get<ConvertFileOperationResult>(GetKey(file));
return result != null && result.Progress != 100 && string.IsNullOrEmpty(result.Error);
}
private void CheckConvertFilesStatus(object _)
{
if (Monitor.TryEnter(singleThread))
{
using var scope = ServiceProvider.CreateScope();
var logger = scope.ServiceProvider.GetService<IOptionsMonitor<ILog>>().CurrentValue;
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
UserManager userManager;
SecurityContext securityContext;
IDaoFactory daoFactory;
FileSecurity fileSecurity;
PathProvider pathProvider;
SetupInfo setupInfo;
FileUtility fileUtility;
DocumentServiceHelper documentServiceHelper;
DocumentServiceConnector documentServiceConnector;
EntryManager entryManager;
FileConverter fileConverter;
var scopeClass = scope.ServiceProvider.GetService<FileConverterQueueScope>();
var (options, tenantManager, userManager, securityContext, daoFactory, fileSecurity, pathProvider, setupInfo, fileUtility, documentServiceHelper, documentServiceConnector, entryManager, fileConverter) = scopeClass;
var logger = options.CurrentValue;
try
{
@ -224,18 +214,6 @@ namespace ASC.Web.Files.Utils
tenantManager.SetCurrentTenant(tenantId);
userManager = scope.ServiceProvider.GetService<UserManager>();
securityContext = scope.ServiceProvider.GetService<SecurityContext>();
daoFactory = scope.ServiceProvider.GetService<IDaoFactory>();
fileSecurity = scope.ServiceProvider.GetService<FileSecurity>();
pathProvider = scope.ServiceProvider.GetService<PathProvider>();
setupInfo = scope.ServiceProvider.GetService<SetupInfo>();
fileUtility = scope.ServiceProvider.GetService<FileUtility>();
documentServiceHelper = scope.ServiceProvider.GetService<DocumentServiceHelper>();
documentServiceConnector = scope.ServiceProvider.GetService<DocumentServiceConnector>();
entryManager = scope.ServiceProvider.GetService<EntryManager>();
fileConverter = scope.ServiceProvider.GetService<FileConverter>();
securityContext.AuthenticateMe(account);
var user = userManager.GetUsers(account.ID);
@ -421,6 +399,83 @@ namespace ASC.Web.Files.Utils
FileJson = JsonSerializer.Serialize(file, options)
}, options);
}
class FileConverterQueueScope
{
private IOptionsMonitor<ILog> Options { get; }
private TenantManager TenantManager { get; }
private UserManager UserManager { get; }
private SecurityContext SecurityContext { get; }
private IDaoFactory DaoFactory { get; }
private FileSecurity FileSecurity { get; }
private PathProvider PathProvider { get; }
private SetupInfo SetupInfo { get; }
private FileUtility FileUtility { get; }
private DocumentServiceHelper DocumentServiceHelper { get; }
private DocumentServiceConnector DocumentServiceConnector { get; }
private EntryManager EntryManager { get; }
private FileConverter FileConverter { get; }
public FileConverterQueueScope(IOptionsMonitor<ILog> options,
TenantManager tenantManager,
UserManager userManager,
SecurityContext securityContext,
IDaoFactory daoFactory,
FileSecurity fileSecurity,
PathProvider pathProvider,
SetupInfo setupInfo,
FileUtility fileUtility,
DocumentServiceHelper documentServiceHelper,
DocumentServiceConnector documentServiceConnector,
EntryManager entryManager,
FileConverter fileConverter)
{
Options = options;
TenantManager = tenantManager;
UserManager = userManager;
SecurityContext = securityContext;
DaoFactory = daoFactory;
FileSecurity = fileSecurity;
PathProvider = pathProvider;
SetupInfo = setupInfo;
FileUtility = fileUtility;
DocumentServiceHelper = documentServiceHelper;
DocumentServiceConnector = documentServiceConnector;
EntryManager = entryManager;
FileConverter = fileConverter;
}
public void Deconstruct(out IOptionsMonitor<ILog> optionsMonitor,
out TenantManager tenantManager,
out UserManager userManager,
out SecurityContext securityContext,
out IDaoFactory daoFactory,
out FileSecurity fileSecurity,
out PathProvider pathProvider,
out SetupInfo setupInfo,
out FileUtility fileUtility,
out DocumentServiceHelper documentServiceHelper,
out DocumentServiceConnector documentServiceConnector,
out EntryManager entryManager,
out FileConverter fileConverter)
{
optionsMonitor = Options;
tenantManager = TenantManager;
userManager = UserManager;
securityContext = SecurityContext;
daoFactory = DaoFactory;
fileSecurity = FileSecurity;
pathProvider = PathProvider;
setupInfo = SetupInfo;
fileUtility = FileUtility;
documentServiceHelper = DocumentServiceHelper;
documentServiceConnector = DocumentServiceConnector;
entryManager = EntryManager;
fileConverter = FileConverter;
}
}
}
public class FileJsonSerializerData<T>
@ -758,6 +813,7 @@ namespace ASC.Web.Files.Utils
}
private FileConverterQueue<T> GetFileConverter<T>() => ServiceProvider.GetService<FileConverterQueue<T>>();
}
internal class FileComparer<T> : IEqualityComparer<File<T>>

View File

@ -80,7 +80,6 @@ namespace ASC.Web.Studio.Core.Notify
}
}
private static void NotifyClientRegisterCallback(Context context, INotifyClient client)
{
#region url correction
@ -131,12 +130,10 @@ namespace ASC.Web.Studio.Core.Notify
InterceptorLifetime.Global,
(r, p, scope) =>
{
var scopeClass = scope.ServiceProvider.GetService<NotifyConfigurationScope>();
var (tenantManager, webItemSecurity, userManager, options, _, _, _, _, _, _, _, _, _, _, _) = scopeClass;
try
{
//fix
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var webItemSecurity = scope.ServiceProvider.GetService<WebItemSecurity>();
var userManager = scope.ServiceProvider.GetService<UserManager>();
// culture
var u = Constants.LostUser;
var tenant = tenantManager.GetCurrentTenant();
@ -201,7 +198,7 @@ namespace ASC.Web.Studio.Core.Notify
}
catch (Exception error)
{
scope.ServiceProvider.GetService<IOptionsMonitor<ILog>>().CurrentValue.Error(error);
options.CurrentValue.Error(error);
}
return false;
});
@ -241,7 +238,6 @@ namespace ASC.Web.Studio.Core.Notify
#endregion
}
private static void BeforeTransferRequest(NotifyEngine sender, NotifyRequest request, IServiceScope scope)
{
var aid = Guid.Empty;
@ -262,17 +258,9 @@ namespace ASC.Web.Studio.Core.Notify
.Replace("<", "&#60");
}
}
var tenantExtra = scope.ServiceProvider.GetService<TenantExtra>();
var webItemManager = scope.ServiceProvider.GetService<WebItemManager>();
var configuration = scope.ServiceProvider.GetService<IConfiguration>();
var tenantLogoManager = scope.ServiceProvider.GetService<TenantLogoManager>();
var additionalWhiteLabelSettingsHelper = scope.ServiceProvider.GetService<AdditionalWhiteLabelSettingsHelper>();
var tenantUtil = scope.ServiceProvider.GetService<TenantUtil>();
var coreBaseSettings = scope.ServiceProvider.GetService<CoreBaseSettings>();
var commonLinkUtility = scope.ServiceProvider.GetService<CommonLinkUtility>();
var settingsManager = scope.ServiceProvider.GetService<SettingsManager>();
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
var log = scope.ServiceProvider.GetService<IOptionsMonitor<ILog>>().CurrentValue;
var scopeClass = scope.ServiceProvider.GetService<NotifyConfigurationScope>();
var (_, _, _, options, tenantExtra, _, webItemManager, configuration, tenantLogoManager, additionalWhiteLabelSettingsHelper, tenantUtil, coreBaseSettings, commonLinkUtility, settingsManager, studioNotifyHelper) = scopeClass;
var log = options.CurrentValue;
commonLinkUtility.GetLocationByRequest(out var product, out var module);
if (product == null && CallContext.GetData("asc.web.product_id") != null)
@ -368,28 +356,120 @@ namespace ASC.Web.Studio.Core.Notify
}
}
public class NotifyConfigurationScope
{
private TenantManager TenantManager { get; }
private WebItemSecurity WebItemSecurity { get; }
private UserManager UserManager { get; }
private IOptionsMonitor<ILog> Options { get; }
private TenantExtra TenantExtra { get; }
private WebItemManagerSecurity WebItemManagerSecurity { get; }
private WebItemManager WebItemManager { get; }
private IConfiguration Configuration { get; }
private TenantLogoManager TenantLogoManager { get; }
private AdditionalWhiteLabelSettingsHelper AdditionalWhiteLabelSettingsHelper { get; }
private TenantUtil TenantUtil { get; }
private CoreBaseSettings CoreBaseSettings { get; }
private CommonLinkUtility CommonLinkUtility { get; }
private SettingsManager SettingsManager { get; }
private StudioNotifyHelper StudioNotifyHelper { get; }
public NotifyConfigurationScope(TenantManager tenantManager,
WebItemSecurity webItemSecurity,
UserManager userManager,
IOptionsMonitor<ILog> options,
TenantExtra tenantExtra,
WebItemManagerSecurity webItemManagerSecurity,
WebItemManager webItemManager,
IConfiguration configuration,
TenantLogoManager tenantLogoManager,
AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper,
TenantUtil tenantUtil,
CoreBaseSettings coreBaseSettings,
CommonLinkUtility commonLinkUtility,
SettingsManager settingsManager,
StudioNotifyHelper studioNotifyHelper
)
{
TenantManager = tenantManager;
WebItemSecurity = webItemSecurity;
UserManager = userManager;
Options = options;
TenantExtra = tenantExtra;
WebItemManagerSecurity = webItemManagerSecurity;
WebItemManager = webItemManager;
Configuration = configuration;
TenantLogoManager = tenantLogoManager;
AdditionalWhiteLabelSettingsHelper = additionalWhiteLabelSettingsHelper;
TenantUtil = tenantUtil;
CoreBaseSettings = coreBaseSettings;
CommonLinkUtility = commonLinkUtility;
SettingsManager = settingsManager;
StudioNotifyHelper = studioNotifyHelper;
}
public void Deconstruct(out TenantManager tenantManager,
out WebItemSecurity webItemSecurity,
out UserManager userManager,
out IOptionsMonitor<ILog> optionsMonitor,
out TenantExtra tenantExtra,
out WebItemManagerSecurity webItemManagerSecurity,
out WebItemManager webItemManager,
out IConfiguration configuration,
out TenantLogoManager tenantLogoManager,
out AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper,
out TenantUtil tenantUtil,
out CoreBaseSettings coreBaseSettings,
out CommonLinkUtility commonLinkUtility,
out SettingsManager settingsManager,
out StudioNotifyHelper studioNotifyHelper)
{
tenantManager = TenantManager;
webItemSecurity = WebItemSecurity;
userManager = UserManager;
optionsMonitor = Options;
tenantExtra = TenantExtra;
webItemManagerSecurity = WebItemManagerSecurity;
webItemManager = WebItemManager;
configuration = Configuration;
tenantLogoManager = TenantLogoManager;
additionalWhiteLabelSettingsHelper = AdditionalWhiteLabelSettingsHelper;
tenantUtil = TenantUtil;
coreBaseSettings = CoreBaseSettings;
commonLinkUtility = CommonLinkUtility;
settingsManager = SettingsManager;
studioNotifyHelper = StudioNotifyHelper;
}
}
public static class NotifyConfigurationExtension
{
public static DIHelper AddNotifyConfiguration(this DIHelper services)
{
return services
.AddJabberStylerService()
.AddTextileStylerService()
.AddPushStylerService()
.AddTenantManagerService()
.AddAuthContextService()
.AddUserManagerService()
.AddDisplayUserSettingsService()
.AddTenantExtraService()
.AddWebItemManagerSecurity()
.AddWebItemManager()
.AddTenantLogoManagerService()
.AddTenantUtilService()
.AddCoreBaseSettingsService()
.AddAdditionalWhiteLabelSettingsService()
.AddCommonLinkUtilityService()
.AddMailWhiteLabelSettingsService()
.AddStudioNotifyHelperService();
if (services.TryAddScoped<NotifyConfigurationScope>())
{
return services
.AddJabberStylerService()
.AddTextileStylerService()
.AddPushStylerService()
.AddTenantManagerService()
.AddAuthContextService()
.AddUserManagerService()
.AddDisplayUserSettingsService()
.AddTenantExtraService()
.AddWebItemManagerSecurity()
.AddWebItemManager()
.AddTenantLogoManagerService()
.AddTenantUtilService()
.AddCoreBaseSettingsService()
.AddAdditionalWhiteLabelSettingsService()
.AddCommonLinkUtilityService()
.AddMailWhiteLabelSettingsService()
.AddStudioNotifyHelperService();
}
return services;
}
}
}

View File

@ -828,10 +828,9 @@ namespace ASC.Web.Studio.Core.Notify
try
{
var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
TenantManager.SetCurrentTenant(tenant);
var client = scope.ServiceProvider.GetService<StudioNotifyServiceHelper>();
var scopeClass = scope.ServiceProvider.GetService<StudioNotifyServiceScope>();
var (tenantManager, studioNotifyServiceHelper) = scopeClass;
tenantManager.SetCurrentTenant(tenant);
foreach (var u in users)
{
@ -839,7 +838,7 @@ namespace ASC.Web.Studio.Core.Notify
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
client.SendNoticeToAsync(
studioNotifyServiceHelper.SendNoticeToAsync(
Actions.PortalRename,
new[] { StudioNotifyHelper.ToRecipient(u.ID) },
new[] { EMailSenderName },
@ -880,17 +879,34 @@ namespace ASC.Web.Studio.Core.Notify
return confirmUrl + $"&firstname={HttpUtility.UrlEncode(user.FirstName)}&lastname={HttpUtility.UrlEncode(user.LastName)}";
}
#endregion
}
public class StudioNotifyServiceScope
{
private TenantManager TenantManager { get; }
private StudioNotifyServiceHelper StudioNotifyServiceHelper { get; }
public StudioNotifyServiceScope(TenantManager tenantManager, StudioNotifyServiceHelper studioNotifyServiceHelper)
{
TenantManager = tenantManager;
StudioNotifyServiceHelper = studioNotifyServiceHelper;
}
public void Deconstruct(out TenantManager tenantManager, out StudioNotifyServiceHelper studioNotifyServiceHelper)
{
tenantManager = TenantManager;
studioNotifyServiceHelper = StudioNotifyServiceHelper;
}
}
public static class StudioNotifyServiceExtension
{
public static DIHelper AddStudioNotifyServiceService(this DIHelper services)
{
if (services.TryAddScoped<StudioNotifyService>())
{
services.TryAddScoped<StudioNotifyServiceScope>();
return services
.AddDisplayUserSettingsService()
.AddMailWhiteLabelSettingsService()

View File

@ -103,7 +103,10 @@ namespace ASC.Web.Core.Notify
item.SenderNames.AddRange(senderNames);
}
item.Tags.AddRange(args.Select(r => new Tag { Tag_ = r.Tag, Value = r.Value.ToString() }));
if (args != null)
{
item.Tags.AddRange(args.Select(r => new Tag { Tag_ = r.Tag, Value = r.Value.ToString() }));
}
Cache.Publish(item, CacheNotifyAction.Any);
}

View File

@ -57,17 +57,12 @@ namespace ASC.Web.Studio.Core.Notify
ServiceProvider = serviceProvider;
Configuration = configuration;
}
public void OnMessage(NotifyItem item)
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var authContext = scope.ServiceProvider.GetService<AuthContext>();
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
var displayUserSettings = scope.ServiceProvider.GetService<DisplayUserSettings>();
var scopeClass = scope.ServiceProvider.GetService<StudioNotifyServiceSenderScope>();
var (tenantManager, userManager, securityContext, studioNotifyHelper, _, _) = scopeClass;
tenantManager.SetCurrentTenant(item.TenantId);
CultureInfo culture = null;
@ -113,9 +108,8 @@ namespace ASC.Web.Studio.Core.Notify
var cron = Configuration["core:notify:cron"] ?? "0 0 5 ? * *"; // 5am every day
using var scope = ServiceProvider.CreateScope();
var tenantExtra = scope.ServiceProvider.GetService<TenantExtra>();
var coreBaseSettings = scope.ServiceProvider.GetService<CoreBaseSettings>();
var scopeClass = scope.ServiceProvider.GetService<StudioNotifyServiceSenderScope>();
var (_, _, _, _, tenantExtra, coreBaseSettings) = scopeClass;
if (Configuration["core:notify:tariff"] != "false")
{
if (tenantExtra.Enterprise)
@ -177,11 +171,52 @@ namespace ASC.Web.Studio.Core.Notify
}
}
public class StudioNotifyServiceSenderScope
{
private TenantManager TenantManager { get; }
private UserManager UserManager { get; }
private SecurityContext SecurityContext { get; }
private StudioNotifyHelper StudioNotifyHelper { get; }
private TenantExtra TenantExtra { get; }
private CoreBaseSettings CoreBaseSettings { get; }
public StudioNotifyServiceSenderScope(TenantManager tenantManager,
UserManager userManager,
SecurityContext securityContext,
StudioNotifyHelper studioNotifyHelper,
TenantExtra tenantExtra,
CoreBaseSettings coreBaseSettings)
{
TenantManager = tenantManager;
UserManager = userManager;
SecurityContext = securityContext;
StudioNotifyHelper = studioNotifyHelper;
TenantExtra = tenantExtra;
CoreBaseSettings = coreBaseSettings;
}
public void Deconstruct(out TenantManager tenantManager,
out UserManager userManager,
out SecurityContext securityContext,
out StudioNotifyHelper studioNotifyHelper,
out TenantExtra tenantExtra,
out CoreBaseSettings coreBaseSettings)
{
tenantManager = TenantManager;
userManager = UserManager;
securityContext = SecurityContext;
studioNotifyHelper = StudioNotifyHelper;
tenantExtra = TenantExtra;
coreBaseSettings = CoreBaseSettings;
}
}
public static class ServiceLauncherExtension
{
public static DIHelper AddStudioNotifyServiceSender(this DIHelper services)
{
services.TryAddSingleton<StudioNotifyServiceSender>();
services.TryAddScoped<StudioNotifyServiceSenderScope>();
return services
.AddStudioPeriodicNotify()
@ -193,8 +228,7 @@ namespace ASC.Web.Studio.Core.Notify
.AddStudioNotifyHelperService()
.AddDisplayUserSettingsService()
.AddTenantExtraService()
.AddCoreBaseSettingsService()
;
.AddCoreBaseSettingsService();
}
}
}

View File

@ -88,26 +88,14 @@ namespace ASC.Web.Studio.Core.Notify
}
}
foreach (var tenant in activeTenants)
{
try
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var scopeClass = scope.ServiceProvider.GetService<StudioPeriodicNotifyScope>();
var (tenantManager, userManager, studioNotifyHelper, paymentManager, tenantExtra, authContext, commonLinkUtility, apiSystemHelper, setupInfo, dbContextManager, couponManager, _, _, _, _, _, _) = scopeClass;
tenantManager.SetCurrentTenant(tenant.TenantId);
var userManager = scope.ServiceProvider.GetService<UserManager>();
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
var paymentManager = scope.ServiceProvider.GetService<PaymentManager>();
var tenantExtra = scope.ServiceProvider.GetService<TenantExtra>();
var authContext = scope.ServiceProvider.GetService<AuthContext>();
var commonLinkUtility = scope.ServiceProvider.GetService<CommonLinkUtility>();
var apiSystemHelper = scope.ServiceProvider.GetService<ApiSystemHelper>();
var setupInfo = scope.ServiceProvider.GetService<SetupInfo>();
var context = scope.ServiceProvider.GetService<DbContextManager<FeedDbContext>>();
var couponManager = scope.ServiceProvider.GetService<CouponManager>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
var tariff = paymentManager.GetTariff(tenant.TenantId);
@ -207,7 +195,7 @@ namespace ASC.Web.Studio.Core.Notify
List<DateTime> datesWithActivity;
datesWithActivity =
context.Get(dbid).FeedAggregates
dbContextManager.Get(dbid).FeedAggregates
.Where(r => r.Tenant == tenantManager.GetCurrentTenant().TenantId)
.Where(r => r.CreatedDate <= nowDate.AddDays(-1))
.GroupBy(r => r.CreatedDate.Date)
@ -525,8 +513,8 @@ namespace ASC.Web.Studio.Core.Notify
}
Log.Info("End SendSaasTariffLetters");
}
}
public void SendEnterpriseLetters(string senderName, DateTime scheduleDate)
{
var nowDate = scheduleDate.Date;
@ -554,19 +542,10 @@ namespace ASC.Web.Studio.Core.Notify
try
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var configuration = scope.ServiceProvider.GetService<IConfiguration>();
var settingsManager = scope.ServiceProvider.GetService<SettingsManager>();
var scopeClass = scope.ServiceProvider.GetService<StudioPeriodicNotifyScope>();
var (tenantManager, userManager, studioNotifyHelper, paymentManager, tenantExtra, _, commonLinkUtility, _, _, dbContextManager, _, configuration, settingsManager, coreBaseSettings, _, _, _) = scopeClass;
var defaultRebranding = MailWhiteLabelSettings.IsDefault(settingsManager, configuration);
tenantManager.SetCurrentTenant(tenant.TenantId);
var userManager = scope.ServiceProvider.GetService<UserManager>();
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
var paymentManager = scope.ServiceProvider.GetService<PaymentManager>();
var tenantExtra = scope.ServiceProvider.GetService<TenantExtra>();
var coreBaseSettings = scope.ServiceProvider.GetService<CoreBaseSettings>();
var commonLinkUtility = scope.ServiceProvider.GetService<CommonLinkUtility>();
var context = scope.ServiceProvider.GetService<DbContextManager<FeedDbContext>>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
var tariff = paymentManager.GetTariff(tenant.TenantId);
@ -697,7 +676,7 @@ namespace ASC.Web.Studio.Core.Notify
List<DateTime> datesWithActivity;
datesWithActivity =
context.Get(dbid).FeedAggregates
dbContextManager.Get(dbid).FeedAggregates
.Where(r => r.Tenant == tenantManager.GetCurrentTenant().TenantId)
.Where(r => r.CreatedDate <= nowDate.AddDays(-1))
.GroupBy(r => r.CreatedDate.Date)
@ -950,13 +929,9 @@ namespace ASC.Web.Studio.Core.Notify
try
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var scopeClass = scope.ServiceProvider.GetService<StudioPeriodicNotifyScope>();
var (tenantManager, _, studioNotifyHelper, _, _, _, _, _, _, _, _, _, _, _, displayUserSettingsHelper, _, _) = scopeClass;
tenantManager.SetCurrentTenant(tenant.TenantId);
var userManager = scope.ServiceProvider.GetService<UserManager>();
var displayUserSettingsHelper = scope.ServiceProvider.GetService<DisplayUserSettingsHelper>();
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
var createdDate = tenant.CreatedDateTime.Date;
@ -1137,15 +1112,10 @@ namespace ASC.Web.Studio.Core.Notify
var sendCount = 0;
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var scopeClass = scope.ServiceProvider.GetService<StudioPeriodicNotifyScope>();
var (tenantManager, userManager, studioNotifyHelper, _, _, _, _, _, _, _, _, _, _, coreBaseSettings, _, authManager, securityContext) = scopeClass;
tenantManager.SetCurrentTenant(tenant.TenantId);
var userManager = scope.ServiceProvider.GetService<UserManager>();
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var authentication = scope.ServiceProvider.GetService<AuthManager>();
var coreBaseSettings = scope.ServiceProvider.GetService<CoreBaseSettings>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
Log.InfoFormat("Current tenant: {0}", tenant.TenantId);
@ -1156,7 +1126,7 @@ namespace ASC.Web.Studio.Core.Notify
{
INotifyAction action;
securityContext.AuthenticateMe(authentication.GetAccountByID(tenant.TenantId, user.ID));
securityContext.AuthenticateMe(authManager.GetAccountByID(tenant.TenantId, user.ID));
var culture = tenant.GetCulture();
if (!string.IsNullOrEmpty(user.CultureName))
@ -1252,12 +1222,109 @@ namespace ASC.Web.Studio.Core.Notify
return !isSubscribe;
}
}
public class StudioPeriodicNotifyScope
{
private TenantManager TenantManager { get; }
private UserManager UserManager { get; }
private StudioNotifyHelper StudioNotifyHelper { get; }
private PaymentManager PaymentManager { get; }
private TenantExtra TenantExtra { get; }
private AuthContext AuthContext { get; }
private CommonLinkUtility CommonLinkUtility { get; }
private ApiSystemHelper ApiSystemHelper { get; }
private SetupInfo SetupInfo { get; }
private DbContextManager<FeedDbContext> DbContextManager { get; }
private CouponManager CouponManager { get; }
private IConfiguration Configuration { get; }
private SettingsManager SettingsManager { get; }
private CoreBaseSettings CoreBaseSettings { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
private AuthManager AuthManager { get; }
private SecurityContext SecurityContext { get; }
public StudioPeriodicNotifyScope(TenantManager tenantManager,
UserManager userManager,
StudioNotifyHelper studioNotifyHelper,
PaymentManager paymentManager,
TenantExtra tenantExtra,
AuthContext authContext,
CommonLinkUtility commonLinkUtility,
ApiSystemHelper apiSystemHelper,
SetupInfo setupInfo,
DbContextManager<FeedDbContext> dbContextManager,
CouponManager couponManager,
IConfiguration configuration,
SettingsManager settingsManager,
CoreBaseSettings coreBaseSettings,
DisplayUserSettingsHelper displayUserSettingsHelper,
AuthManager authManager,
SecurityContext securityContext)
{
TenantManager = tenantManager;
UserManager = userManager;
StudioNotifyHelper = studioNotifyHelper;
PaymentManager = paymentManager;
TenantExtra = tenantExtra;
AuthContext = authContext;
CommonLinkUtility = commonLinkUtility;
ApiSystemHelper = apiSystemHelper;
SetupInfo = setupInfo;
DbContextManager = dbContextManager;
CouponManager = couponManager;
Configuration = configuration;
SettingsManager = settingsManager;
CoreBaseSettings = coreBaseSettings;
DisplayUserSettingsHelper = displayUserSettingsHelper;
AuthManager = authManager;
SecurityContext = securityContext;
}
public void Deconstruct(out TenantManager tenantManager,
out UserManager userManager,
out StudioNotifyHelper studioNotifyHelper,
out PaymentManager paymentManager,
out TenantExtra tenantExtra,
out AuthContext authContext,
out CommonLinkUtility commonLinkUtility,
out ApiSystemHelper apiSystemHelper,
out SetupInfo setupInfo,
out DbContextManager<FeedDbContext> dbContextManager,
out CouponManager couponManager,
out IConfiguration configuration,
out SettingsManager settingsManager,
out CoreBaseSettings coreBaseSettings,
out DisplayUserSettingsHelper displayUserSettingsHelper,
out AuthManager authManager,
out SecurityContext securityContext)
{
tenantManager = TenantManager;
userManager = UserManager;
studioNotifyHelper = StudioNotifyHelper;
paymentManager = PaymentManager;
tenantExtra = TenantExtra;
authContext = AuthContext;
commonLinkUtility = CommonLinkUtility;
apiSystemHelper = ApiSystemHelper;
setupInfo = SetupInfo;
dbContextManager = DbContextManager;
couponManager = CouponManager;
configuration = Configuration;
settingsManager = SettingsManager;
coreBaseSettings = CoreBaseSettings;
displayUserSettingsHelper = DisplayUserSettingsHelper;
authManager = AuthManager;
securityContext = SecurityContext;
}
}
public static class StudioPeriodicNotifyExtension
{
public static DIHelper AddStudioPeriodicNotify(this DIHelper services)
{
services.TryAddSingleton<StudioPeriodicNotify>();
services.TryAddSingleton<CouponManager>();
services.TryAddSingleton<CouponManager>();
services.TryAddScoped<StudioPeriodicNotifyScope>();
return services
.AddApiSystemHelper()

View File

@ -61,7 +61,7 @@ namespace ASC.Web.Studio.Core.Notify
ServiceProvider = serviceProvider;
Confuguration = confuguration;
}
public void SendMsgWhatsNew(DateTime scheduleDate)
{
var log = ServiceProvider.GetService<IOptionsMonitor<ILog>>().Get("ASC.Notify");
@ -82,10 +82,8 @@ namespace ASC.Web.Studio.Core.Notify
try
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var paymentManager = scope.ServiceProvider.GetService<PaymentManager>();
var tenantUtil = scope.ServiceProvider.GetService<TenantUtil>();
var scopeClass = scope.ServiceProvider.GetService<StudioWhatsNewNotifyScope>();
var (tenantManager, paymentManager, tenantUtil, studioNotifyHelper, userManager, securityContext, authContext, authManager, commonLinkUtility, displayUserSettingsHelper, feedAggregateDataProvider, coreSettings) = scopeClass;
var tenant = tenantManager.GetTenant(tenantid);
if (tenant == null ||
tenant.Status != TenantStatus.Active ||
@ -96,16 +94,6 @@ namespace ASC.Web.Studio.Core.Notify
}
tenantManager.SetCurrentTenant(tenant);
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
var userManager = scope.ServiceProvider.GetService<UserManager>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var authContext = scope.ServiceProvider.GetService<AuthContext>();
var authentication = scope.ServiceProvider.GetService<AuthManager>();
var commonLinkUtility = scope.ServiceProvider.GetService<CommonLinkUtility>();
var displayUserSettingsHelper = scope.ServiceProvider.GetService<DisplayUserSettingsHelper>();
var feedAggregateDataProvider = scope.ServiceProvider.GetService<FeedAggregateDataProvider>();
var coreSettings = scope.ServiceProvider.GetService<CoreSettings>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
log.InfoFormat("Start send whats new in {0} ({1}).", tenant.GetTenantDomain(coreSettings), tenantid);
@ -116,7 +104,7 @@ namespace ASC.Web.Studio.Core.Notify
continue;
}
securityContext.AuthenticateMe(authentication.GetAccountByID(tenant.TenantId, user.ID));
securityContext.AuthenticateMe(authManager.GetAccountByID(tenant.TenantId, user.ID));
var culture = string.IsNullOrEmpty(user.CultureName) ? tenant.GetCulture() : user.GetCulture();
@ -305,12 +293,82 @@ namespace ASC.Web.Studio.Core.Notify
}
}
public class StudioWhatsNewNotifyScope
{
private TenantManager TenantManager { get; }
private PaymentManager PaymentManager { get; }
private TenantUtil TenantUtil { get; }
private StudioNotifyHelper StudioNotifyHelper { get; }
private UserManager UserManager { get; }
private SecurityContext SecurityContext { get; }
private AuthContext AuthContext { get; }
private AuthManager AuthManager { get; }
private CommonLinkUtility CommonLinkUtility { get; }
private DisplayUserSettingsHelper DisplayUserSettingsHelper { get; }
private FeedAggregateDataProvider FeedAggregateDataProvider { get; }
private CoreSettings CoreSettings { get; }
public StudioWhatsNewNotifyScope(TenantManager tenantManager,
PaymentManager paymentManager,
TenantUtil tenantUtil,
StudioNotifyHelper studioNotifyHelper,
UserManager userManager,
SecurityContext securityContext,
AuthContext authContext,
AuthManager authManager,
CommonLinkUtility commonLinkUtility,
DisplayUserSettingsHelper displayUserSettingsHelper,
FeedAggregateDataProvider feedAggregateDataProvider,
CoreSettings coreSettings)
{
TenantManager = tenantManager;
PaymentManager = paymentManager;
TenantUtil = tenantUtil;
StudioNotifyHelper = studioNotifyHelper;
UserManager = userManager;
SecurityContext = securityContext;
AuthContext = authContext;
AuthManager = authManager;
CommonLinkUtility = commonLinkUtility;
DisplayUserSettingsHelper = displayUserSettingsHelper;
FeedAggregateDataProvider = feedAggregateDataProvider;
CoreSettings = coreSettings;
}
public void Deconstruct(out TenantManager tenantManager,
out PaymentManager paymentManager,
out TenantUtil tenantUtil,
out StudioNotifyHelper studioNotifyHelper,
out UserManager userManager,
out SecurityContext securityContext,
out AuthContext authContext,
out AuthManager authManager,
out CommonLinkUtility commonLinkUtility,
out DisplayUserSettingsHelper displayUserSettingsHelper,
out FeedAggregateDataProvider feedAggregateDataProvider,
out CoreSettings coreSettings )
{
tenantManager = TenantManager;
paymentManager = PaymentManager;
tenantUtil = TenantUtil;
studioNotifyHelper = StudioNotifyHelper;
userManager = UserManager;
securityContext = SecurityContext;
authContext = AuthContext;
authManager = AuthManager;
commonLinkUtility = CommonLinkUtility;
displayUserSettingsHelper = DisplayUserSettingsHelper;
feedAggregateDataProvider = FeedAggregateDataProvider;
coreSettings = CoreSettings;
}
}
public static class StudioWhatsNewNotifyExtension
{
public static DIHelper AddStudioWhatsNewNotify(this DIHelper services)
{
services.TryAddSingleton<StudioWhatsNewNotify>();
services.TryAddSingleton<StudioWhatsNewNotify>();
services.TryAddScoped<StudioWhatsNewNotifyScope>();
return services
.AddWebItemManager()
.AddFeedAggregateDataProvider()

View File

@ -49,15 +49,13 @@ namespace ASC.Web.Studio.Core.Quota
TaskInfo = new DistributedTask();
ServiceProvider = serviceProvider;
}
public void RunJob(DistributedTask _, CancellationToken cancellationToken)
{
using var scope = ServiceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
tenantManager.SetCurrentTenant(TenantId);
var storageFactoryConfig = scope.ServiceProvider.GetService<StorageFactoryConfig>();
var storageFactory = scope.ServiceProvider.GetService<StorageFactory>();
var scopeClass = scope.ServiceProvider.GetService<QuotaSyncScope>();
var (tenantManager, storageFactoryConfig, storageFactory) = scopeClass;
tenantManager.SetCurrentTenant(TenantId);
var storageModules = storageFactoryConfig.GetModuleList(string.Empty).ToList();
@ -75,11 +73,31 @@ namespace ASC.Web.Studio.Core.Quota
}
}
public virtual DistributedTask GetDistributedTask()
{
TaskInfo.SetProperty(TenantIdKey, TenantId);
return TaskInfo;
}
}
class QuotaSyncScope
{
private TenantManager TenantManager { get; }
private StorageFactoryConfig StorageFactoryConfig { get; }
private StorageFactory StorageFactory { get; }
public QuotaSyncScope(TenantManager tenantManager, StorageFactoryConfig storageFactoryConfig, StorageFactory storageFactory)
{
TenantManager = tenantManager;
StorageFactoryConfig = storageFactoryConfig;
StorageFactory = storageFactory;
}
public void Deconstruct(out TenantManager tenantManager, out StorageFactoryConfig storageFactoryConfig, out StorageFactory storageFactory )
{
tenantManager = TenantManager;
storageFactoryConfig = StorageFactoryConfig;
storageFactory = StorageFactory;
}
}
}