DI: dbManager
This commit is contained in:
parent
247a3b787f
commit
e82366a2cd
@ -29,10 +29,12 @@ using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ASC.Common.Data.AdoProxy;
|
||||
using ASC.Common.Data.Sql;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Web;
|
||||
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace ASC.Common.Data
|
||||
@ -67,16 +69,20 @@ namespace ASC.Common.Data
|
||||
public class ConfigureDbManager : IConfigureNamedOptions<DbManager>
|
||||
{
|
||||
public DbRegistry DbRegistry { get; }
|
||||
public IOptionsMonitor<LogNLog> Option { get; }
|
||||
|
||||
public ConfigureDbManager(DbRegistry dbRegistry)
|
||||
public ConfigureDbManager(DbRegistry dbRegistry, IOptionsMonitor<LogNLog> option)
|
||||
{
|
||||
DbRegistry = dbRegistry;
|
||||
Option = option;
|
||||
}
|
||||
|
||||
public void Configure(string name, DbManager dbManager)
|
||||
{
|
||||
dbManager.DbRegistry = DbRegistry;
|
||||
dbManager.DatabaseId = string.IsNullOrEmpty(name) ? "default" : name;
|
||||
dbManager.Logger = Option.Get("ASC.SQL");
|
||||
|
||||
}
|
||||
|
||||
public void Configure(DbManager dbManager)
|
||||
@ -88,7 +94,7 @@ namespace ASC.Common.Data
|
||||
|
||||
public class DbManager : IDbManager
|
||||
{
|
||||
private readonly ILog logger = LogManager.GetLogger("ASC.SQL");
|
||||
public ILog Logger { get; internal set; }
|
||||
private readonly ProxyContext proxyContext;
|
||||
private readonly bool shared;
|
||||
|
||||
@ -155,7 +161,7 @@ namespace ASC.Common.Data
|
||||
DatabaseId = databaseId ?? throw new ArgumentNullException(nameof(databaseId));
|
||||
this.shared = shared;
|
||||
|
||||
if (logger.IsDebugEnabled)
|
||||
if (Logger.IsDebugEnabled)
|
||||
{
|
||||
proxyContext = new ProxyContext(AdoProxyExecutedEventHandler);
|
||||
}
|
||||
@ -185,22 +191,6 @@ namespace ASC.Common.Data
|
||||
|
||||
#endregion
|
||||
|
||||
public static IDbManager FromHttpContext(DbRegistry dbRegistry, string databaseId)
|
||||
{
|
||||
if (HttpContext.Current != null)
|
||||
{
|
||||
if (!(DisposableHttpContext.Current[databaseId] is DbManager dbManager) || dbManager.disposed)
|
||||
{
|
||||
var localDbManager = new DbManager(dbRegistry, databaseId);
|
||||
var dbManagerAdapter = new DbManagerProxy(localDbManager);
|
||||
DisposableHttpContext.Current[databaseId] = localDbManager;
|
||||
return dbManagerAdapter;
|
||||
}
|
||||
return new DbManagerProxy(dbManager);
|
||||
}
|
||||
return new DbManager(dbRegistry, databaseId);
|
||||
}
|
||||
|
||||
private DbConnection OpenConnection()
|
||||
{
|
||||
var connection = GetConnection();
|
||||
@ -367,7 +357,7 @@ namespace ASC.Common.Data
|
||||
|
||||
private void AdoProxyExecutedEventHandler(ExecutedEventArgs a)
|
||||
{
|
||||
logger.DebugWithProps(a.SqlMethod,
|
||||
Logger.DebugWithProps(a.SqlMethod,
|
||||
new KeyValuePair<string, object>("duration", a.Duration.TotalMilliseconds),
|
||||
new KeyValuePair<string, object>("sql", RemoveWhiteSpaces(a.Sql)),
|
||||
new KeyValuePair<string, object>("sqlParams", RemoveWhiteSpaces(a.SqlParameters))
|
||||
@ -380,6 +370,11 @@ namespace ASC.Common.Data
|
||||
str.Replace(Environment.NewLine, " ").Replace("\n", "").Replace("\r", "").Replace("\t", " ") :
|
||||
string.Empty;
|
||||
}
|
||||
|
||||
public ISqlDialect GetSqlDialect(string databaseId)
|
||||
{
|
||||
return DbRegistry.GetSqlDialect(databaseId);
|
||||
}
|
||||
}
|
||||
|
||||
public class DbManagerProxy : IDbManager
|
||||
@ -467,5 +462,10 @@ namespace ASC.Common.Data
|
||||
{
|
||||
return dbManager.ExecuteBatch(batch);
|
||||
}
|
||||
|
||||
public ISqlDialect GetSqlDialect(string databaseId)
|
||||
{
|
||||
return dbManager.GetSqlDialect(databaseId);
|
||||
}
|
||||
}
|
||||
}
|
@ -37,7 +37,8 @@ namespace ASC.Common.Data
|
||||
{
|
||||
DbConnection Connection { get; }
|
||||
string DatabaseId { get; }
|
||||
bool InTransaction { get; }
|
||||
bool InTransaction { get; }
|
||||
ISqlDialect GetSqlDialect(string databaseId);
|
||||
|
||||
IDbTransaction BeginTransaction();
|
||||
|
||||
|
@ -54,17 +54,14 @@ namespace ASC.Common.Data
|
||||
}
|
||||
|
||||
|
||||
public MultiRegionalDbManager(IConfiguration configuration, DbRegistry dbRegistry, string dbId)
|
||||
public MultiRegionalDbManager(IConfiguration configuration, DbOptionsManager optionsManager, string dbId)
|
||||
{
|
||||
const StringComparison cmp = StringComparison.InvariantCultureIgnoreCase;
|
||||
DatabaseId = dbId;
|
||||
databases = configuration.GetConnectionStrings()
|
||||
.Where(c => c.Name.Equals(dbId, cmp) || c.Name.StartsWith(dbId + ".", cmp))
|
||||
.Select(
|
||||
c =>
|
||||
HttpContext.Current != null
|
||||
? DbManager.FromHttpContext(dbRegistry, c.Name)
|
||||
: new DbManager(dbRegistry, c.Name))
|
||||
.Select(c => optionsManager.Get(c.Name))
|
||||
.Cast<IDbManager>()
|
||||
.ToList();
|
||||
localDb = databases.SingleOrDefault(db => db.DatabaseId.Equals(dbId, cmp));
|
||||
}
|
||||
@ -85,11 +82,6 @@ namespace ASC.Common.Data
|
||||
}
|
||||
}
|
||||
|
||||
public static MultiRegionalDbManager FromHttpContext(IConfiguration configuration, DbRegistry dbRegistry, string databaseId)
|
||||
{
|
||||
return new MultiRegionalDbManager(configuration, dbRegistry, databaseId);
|
||||
}
|
||||
|
||||
public IDbTransaction BeginTransaction(IsolationLevel isolationLevel)
|
||||
{
|
||||
return localDb.BeginTransaction(isolationLevel);
|
||||
@ -180,5 +172,10 @@ namespace ASC.Common.Data
|
||||
{
|
||||
return localDb.BeginTransaction();
|
||||
}
|
||||
|
||||
public ISqlDialect GetSqlDialect(string databaseId)
|
||||
{
|
||||
return localDb.GetSqlDialect(databaseId);
|
||||
}
|
||||
}
|
||||
}
|
@ -38,13 +38,13 @@ namespace ASC.Geolocation
|
||||
{
|
||||
private readonly string dbid;
|
||||
|
||||
public DbRegistry DbRegistry { get; }
|
||||
public ILog Log { get; }
|
||||
|
||||
public GeolocationHelper(DbRegistry dbRegistry, IOptionsMonitor<LogNLog> option, string dbid)
|
||||
public ILog Log { get; }
|
||||
public DbOptionsManager DbOptions { get; }
|
||||
|
||||
public GeolocationHelper(DbOptionsManager dbOptions, IOptionsMonitor<LogNLog> option, string dbid)
|
||||
{
|
||||
Log = option.CurrentValue;
|
||||
DbRegistry = dbRegistry;
|
||||
DbOptions = dbOptions;
|
||||
this.dbid = dbid;
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ namespace ASC.Geolocation
|
||||
try
|
||||
{
|
||||
var ipformatted = FormatIP(ip);
|
||||
using var db = new DbManager(DbRegistry, dbid);
|
||||
var db = DbOptions.Get(dbid);
|
||||
var q = new SqlQuery("dbip_location")
|
||||
.Select("ip_start", "ip_end", "country", "city", "timezone_offset", "timezone_name")
|
||||
.Where(Exp.Le("ip_start", ipformatted))
|
||||
|
@ -102,16 +102,15 @@ namespace ASC.Core.Billing
|
||||
public TariffServiceStorage TariffServiceStorage { get; }
|
||||
|
||||
public TariffService(
|
||||
System.Configuration.ConnectionStringSettings connectionString,
|
||||
IQuotaService quotaService,
|
||||
ITenantService tenantService,
|
||||
CoreBaseSettings coreBaseSettings,
|
||||
CoreSettings coreSettings,
|
||||
IConfiguration configuration,
|
||||
DbRegistry dbRegistry,
|
||||
DbOptionsManager dbOptionsManager,
|
||||
TariffServiceStorage tariffServiceStorage,
|
||||
IOptionsMonitor<LogNLog> options)
|
||||
: base(connectionString, dbRegistry, "tenant")
|
||||
: base(dbOptionsManager, "tenant")
|
||||
{
|
||||
log = options.CurrentValue;
|
||||
this.quotaService = quotaService;
|
||||
@ -412,7 +411,7 @@ client.GetPaymentUrls(null, products, !string.IsNullOrEmpty(affiliateId) ? affil
|
||||
var inserted = false;
|
||||
if (!Equals(bi, GetBillingInfo(tenant)))
|
||||
{
|
||||
using var db = GetDb();
|
||||
var db = GetDb();
|
||||
using var tx = db.BeginTransaction();
|
||||
// last record is not the same
|
||||
var q = new SqlQuery("tenants_tariff").SelectCount().Where("tenant", tenant).Where("tariff", bi.Item1).Where("stamp", bi.Item2);
|
||||
@ -444,7 +443,7 @@ client.GetPaymentUrls(null, products, !string.IsNullOrEmpty(affiliateId) ? affil
|
||||
public void DeleteDefaultBillingInfo()
|
||||
{
|
||||
const int tenant = Tenant.DEFAULT_TENANT;
|
||||
using (var db = GetDb())
|
||||
var db = GetDb();
|
||||
{
|
||||
db.ExecuteNonQuery(new SqlUpdate("tenants_tariff")
|
||||
.Set("tenant", -2)
|
||||
|
@ -48,13 +48,16 @@ namespace ASC.Core.Billing
|
||||
private Timer timer;
|
||||
|
||||
|
||||
public TariffSyncService(IServiceProvider serviceProvider, IConfiguration configuration, DbRegistry dbRegistry,
|
||||
public TariffSyncService(
|
||||
IServiceProvider serviceProvider,
|
||||
IConfiguration configuration,
|
||||
DbQuotaService dbQuotaService,
|
||||
IOptionsMonitor<LogNLog> options)
|
||||
{
|
||||
config = TariffSyncServiceSection.GetSection();
|
||||
ServiceProvider = serviceProvider;
|
||||
Configuration = configuration;
|
||||
DbRegistry = dbRegistry;
|
||||
DbQuotaService = dbQuotaService;
|
||||
log = options.CurrentValue;
|
||||
}
|
||||
|
||||
@ -68,7 +71,7 @@ namespace ASC.Core.Billing
|
||||
{
|
||||
var cs = Configuration.GetConnectionStrings(config.ConnectionStringName + version) ??
|
||||
Configuration.GetConnectionStrings(config.ConnectionStringName);
|
||||
quotaServices[version] = new DbQuotaService(cs, DbRegistry).GetTenantQuotas();
|
||||
quotaServices[version] = DbQuotaService.GetTenantQuotas();
|
||||
}
|
||||
return quotaServices[version];
|
||||
}
|
||||
@ -83,7 +86,7 @@ namespace ASC.Core.Billing
|
||||
|
||||
public IServiceProvider ServiceProvider { get; }
|
||||
public IConfiguration Configuration { get; }
|
||||
public DbRegistry DbRegistry { get; }
|
||||
public DbQuotaService DbQuotaService { get; }
|
||||
|
||||
public void Start()
|
||||
{
|
||||
@ -109,7 +112,7 @@ namespace ASC.Core.Billing
|
||||
{
|
||||
var scope = ServiceProvider.CreateScope();
|
||||
var tariffSync = scope.ServiceProvider.GetService<TariffSync>();
|
||||
tariffSync.Sync(config, Configuration);
|
||||
tariffSync.Sync();
|
||||
|
||||
}
|
||||
catch (Exception error)
|
||||
@ -121,24 +124,26 @@ namespace ASC.Core.Billing
|
||||
|
||||
class TariffSync
|
||||
{
|
||||
public TariffSync(TenantManager tenantManager, DbRegistry dbRegistry, CoreSettings coreSettings)
|
||||
public TariffSync(TenantManager tenantManager, DbRegistry dbRegistry, CoreSettings coreSettings, DbQuotaService dbQuotaService)
|
||||
{
|
||||
TenantManager = tenantManager;
|
||||
DbRegistry = dbRegistry;
|
||||
CoreSettings = coreSettings;
|
||||
DbQuotaService = dbQuotaService;
|
||||
}
|
||||
|
||||
public TenantManager TenantManager { get; }
|
||||
public DbRegistry DbRegistry { get; }
|
||||
public CoreSettings CoreSettings { get; }
|
||||
public DbQuotaService DbQuotaService { get; }
|
||||
|
||||
public void Sync(TariffSyncServiceSection config, IConfiguration configuration)
|
||||
public void Sync()
|
||||
{
|
||||
var tenant = TenantManager.GetTenants(false).OrderByDescending(t => t.Version).FirstOrDefault();
|
||||
if (tenant != null)
|
||||
{
|
||||
using var wcfClient = new TariffSyncClient();
|
||||
var quotaService = new DbQuotaService(configuration.GetConnectionStrings(config.ConnectionStringName), DbRegistry);
|
||||
var quotaService = DbQuotaService;
|
||||
|
||||
var oldtariffs = quotaService.GetTenantQuotas().ToDictionary(t => t.Id);
|
||||
// save new
|
||||
|
@ -27,38 +27,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ASC.Common.Caching;
|
||||
|
||||
using ASC.Core.Data;
|
||||
|
||||
namespace ASC.Core.Caching
|
||||
{
|
||||
{
|
||||
public class AzServiceCache
|
||||
{
|
||||
public ICache Cache { get; }
|
||||
public ICacheNotify<AzRecordCache> CacheNotify { get; }
|
||||
|
||||
public AzServiceCache(ICacheNotify<AzRecordCache> cacheNotify)
|
||||
{
|
||||
CacheNotify = cacheNotify;
|
||||
Cache = AscCache.Memory;
|
||||
|
||||
cacheNotify.Subscribe((r) => UpdateCache(r, true), CacheNotifyAction.Remove);
|
||||
cacheNotify.Subscribe((r) => UpdateCache(r, false), CacheNotifyAction.InsertOrUpdate);
|
||||
}
|
||||
|
||||
private void UpdateCache(AzRecord r, bool remove)
|
||||
{
|
||||
var aces = Cache.Get<AzRecordStore>(GetKey(r.Tenant));
|
||||
if (aces != null)
|
||||
{
|
||||
lock (aces)
|
||||
{
|
||||
if (remove)
|
||||
{
|
||||
aces.Remove(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
aces.Add(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetKey(int tenant)
|
||||
{
|
||||
return "acl" + tenant.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class CachedAzService : IAzService
|
||||
{
|
||||
private readonly IAzService service;
|
||||
private readonly ICache cache;
|
||||
private readonly ICacheNotify<AzRecordCache> cacheNotify;
|
||||
|
||||
private readonly ICacheNotify<AzRecordCache> cacheNotify;
|
||||
|
||||
public ICache Cache { get; }
|
||||
|
||||
public TimeSpan CacheExpiration { get; set; }
|
||||
|
||||
|
||||
public CachedAzService(IAzService service, ICacheNotify<AzRecordCache> cacheNotify)
|
||||
public CachedAzService(DbAzService service, AzServiceCache azServiceCache)
|
||||
{
|
||||
this.service = service ?? throw new ArgumentNullException("service");
|
||||
cache = AscCache.Memory;
|
||||
Cache = azServiceCache.Cache;
|
||||
cacheNotify = azServiceCache.CacheNotify;
|
||||
CacheExpiration = TimeSpan.FromMinutes(10);
|
||||
|
||||
cacheNotify.Subscribe((r) => UpdateCache(r, true), CacheNotifyAction.Remove);
|
||||
cacheNotify.Subscribe((r) => UpdateCache(r, false), CacheNotifyAction.InsertOrUpdate);
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<AzRecord> GetAces(int tenant, DateTime from)
|
||||
{
|
||||
var key = GetKey(tenant);
|
||||
var aces = cache.Get<AzRecordStore>(key);
|
||||
var key = AzServiceCache.GetKey(tenant);
|
||||
var aces = Cache.Get<AzRecordStore>(key);
|
||||
if (aces == null)
|
||||
{
|
||||
var records = service.GetAces(tenant, default);
|
||||
cache.Insert(key, aces = new AzRecordStore(records), DateTime.UtcNow.Add(CacheExpiration));
|
||||
Cache.Insert(key, aces = new AzRecordStore(records), DateTime.UtcNow.Add(CacheExpiration));
|
||||
}
|
||||
return aces;
|
||||
}
|
||||
@ -75,30 +114,5 @@ namespace ASC.Core.Caching
|
||||
service.RemoveAce(tenant, r);
|
||||
cacheNotify.Publish(r, CacheNotifyAction.Remove);
|
||||
}
|
||||
|
||||
|
||||
private string GetKey(int tenant)
|
||||
{
|
||||
return "acl" + tenant.ToString();
|
||||
}
|
||||
|
||||
private void UpdateCache(AzRecord r, bool remove)
|
||||
{
|
||||
var aces = cache.Get<AzRecordStore>(GetKey(r.Tenant));
|
||||
if (aces != null)
|
||||
{
|
||||
lock (aces)
|
||||
{
|
||||
if (remove)
|
||||
{
|
||||
aces.Remove(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
aces.Add(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -28,54 +28,83 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Core.Tenants;
|
||||
|
||||
using ASC.Core.Data;
|
||||
using ASC.Core.Tenants;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace ASC.Core.Caching
|
||||
{
|
||||
{
|
||||
public class QuotaServiceCache
|
||||
{
|
||||
internal const string KEY_QUOTA = "quota";
|
||||
internal const string KEY_QUOTA_ROWS = "quotarows";
|
||||
|
||||
public TrustInterval Interval { get; set; }
|
||||
public ICache Cache { get; }
|
||||
public ICacheNotify<QuotaCacheItem> CacheNotify { get; }
|
||||
|
||||
public bool QuotaCacheEnabled { get; }
|
||||
|
||||
public QuotaServiceCache(IConfiguration Configuration, ICacheNotify<QuotaCacheItem> cacheNotify)
|
||||
{
|
||||
if (Configuration["core:enable-quota-cache"] == null)
|
||||
{
|
||||
QuotaCacheEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
QuotaCacheEnabled = !bool.TryParse(Configuration["core:enable-quota-cache"], out var enabled) || enabled;
|
||||
}
|
||||
|
||||
CacheNotify = cacheNotify;
|
||||
Cache = AscCache.Memory;
|
||||
Interval = new TrustInterval();
|
||||
|
||||
cacheNotify.Subscribe((i) =>
|
||||
{
|
||||
if (i.Key == KEY_QUOTA_ROWS)
|
||||
{
|
||||
Interval.Expire();
|
||||
}
|
||||
else if (i.Key == KEY_QUOTA)
|
||||
{
|
||||
Cache.Remove(KEY_QUOTA);
|
||||
}
|
||||
}, CacheNotifyAction.Any);
|
||||
}
|
||||
}
|
||||
|
||||
public class CachedQuotaService : IQuotaService
|
||||
{
|
||||
private const string KEY_QUOTA = "quota";
|
||||
private const string KEY_QUOTA_ROWS = "quotarows";
|
||||
private readonly IQuotaService service;
|
||||
private readonly ICache cache;
|
||||
private readonly ICacheNotify<QuotaCacheItem> cacheNotify;
|
||||
private readonly TrustInterval interval;
|
||||
|
||||
public TimeSpan CacheExpiration { get; set; }
|
||||
public QuotaServiceCache QuotaServiceCache { get; }
|
||||
|
||||
public TimeSpan CacheExpiration
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
public CachedQuotaService(IQuotaService service, ICacheNotify<QuotaCacheItem> cacheNotify)
|
||||
public CachedQuotaService(DbQuotaService service, QuotaServiceCache quotaServiceCache)
|
||||
{
|
||||
this.service = service ?? throw new ArgumentNullException("service");
|
||||
cache = AscCache.Memory;
|
||||
this.service = service ?? throw new ArgumentNullException("service");
|
||||
QuotaServiceCache = quotaServiceCache;
|
||||
cache = quotaServiceCache.Cache;
|
||||
interval = new TrustInterval();
|
||||
CacheExpiration = TimeSpan.FromMinutes(10);
|
||||
|
||||
cacheNotify.Subscribe((i) =>
|
||||
{
|
||||
if (i.Key == KEY_QUOTA_ROWS)
|
||||
{
|
||||
interval.Expire();
|
||||
}
|
||||
else if (i.Key == KEY_QUOTA)
|
||||
{
|
||||
cache.Remove(KEY_QUOTA);
|
||||
}
|
||||
}, CacheNotifyAction.Any);
|
||||
CacheExpiration = TimeSpan.FromMinutes(10);
|
||||
cacheNotify = quotaServiceCache.CacheNotify;
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<TenantQuota> GetTenantQuotas()
|
||||
{
|
||||
var quotas = cache.Get<IEnumerable<TenantQuota>>(KEY_QUOTA);
|
||||
var quotas = cache.Get<IEnumerable<TenantQuota>>(QuotaServiceCache.KEY_QUOTA);
|
||||
if (quotas == null)
|
||||
{
|
||||
cache.Insert(KEY_QUOTA, quotas = service.GetTenantQuotas(), DateTime.UtcNow.Add(CacheExpiration));
|
||||
{
|
||||
quotas = service.GetTenantQuotas();
|
||||
if (QuotaServiceCache.QuotaCacheEnabled)
|
||||
{
|
||||
cache.Insert(QuotaServiceCache.KEY_QUOTA, quotas, DateTime.UtcNow.Add(CacheExpiration));
|
||||
}
|
||||
}
|
||||
return quotas;
|
||||
}
|
||||
@ -88,7 +117,7 @@ namespace ASC.Core.Caching
|
||||
public TenantQuota SaveTenantQuota(TenantQuota quota)
|
||||
{
|
||||
var q = service.SaveTenantQuota(quota);
|
||||
cacheNotify.Publish(new QuotaCacheItem { Key = KEY_QUOTA }, CacheNotifyAction.Any);
|
||||
cacheNotify.Publish(new QuotaCacheItem { Key = QuotaServiceCache.KEY_QUOTA }, CacheNotifyAction.Any);
|
||||
return q;
|
||||
}
|
||||
|
||||
@ -101,14 +130,14 @@ namespace ASC.Core.Caching
|
||||
public void SetTenantQuotaRow(TenantQuotaRow row, bool exchange)
|
||||
{
|
||||
service.SetTenantQuotaRow(row, exchange);
|
||||
cacheNotify.Publish(new QuotaCacheItem { Key = KEY_QUOTA_ROWS }, CacheNotifyAction.Any);
|
||||
cacheNotify.Publish(new QuotaCacheItem { Key = QuotaServiceCache.KEY_QUOTA_ROWS }, CacheNotifyAction.Any);
|
||||
}
|
||||
|
||||
public IEnumerable<TenantQuotaRow> FindTenantQuotaRows(TenantQuotaRowQuery query)
|
||||
{
|
||||
if (query == null) throw new ArgumentNullException("query");
|
||||
|
||||
var rows = cache.Get<Dictionary<string, List<TenantQuotaRow>>>(KEY_QUOTA_ROWS);
|
||||
var rows = cache.Get<Dictionary<string, List<TenantQuotaRow>>>(QuotaServiceCache.KEY_QUOTA_ROWS);
|
||||
if (rows == null || interval.Expired)
|
||||
{
|
||||
var date = rows != null ? interval.StartTime : DateTime.MinValue;
|
||||
@ -145,11 +174,14 @@ namespace ASC.Core.Caching
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cache.Insert(KEY_QUOTA_ROWS, rows, DateTime.UtcNow.Add(CacheExpiration));
|
||||
|
||||
if (QuotaServiceCache.QuotaCacheEnabled)
|
||||
{
|
||||
cache.Insert(QuotaServiceCache.KEY_QUOTA_ROWS, rows, DateTime.UtcNow.Add(CacheExpiration));
|
||||
}
|
||||
}
|
||||
|
||||
var quotaRows = cache.Get<Dictionary<string, List<TenantQuotaRow>>>(KEY_QUOTA_ROWS);
|
||||
var quotaRows = cache.Get<Dictionary<string, List<TenantQuotaRow>>>(QuotaServiceCache.KEY_QUOTA_ROWS);
|
||||
if (quotaRows == null)
|
||||
{
|
||||
return Enumerable.Empty<TenantQuotaRow>();
|
||||
|
@ -28,9 +28,77 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ASC.Common.Caching;
|
||||
|
||||
using ASC.Core.Data;
|
||||
|
||||
namespace ASC.Core.Caching
|
||||
{
|
||||
{
|
||||
public class SubscriptionServiceCache
|
||||
{
|
||||
public ICache Cache { get; }
|
||||
public ICacheNotify<SubscriptionRecord> NotifyRecord { get; }
|
||||
public ICacheNotify<SubscriptionMethodCache> NotifyMethod { get; }
|
||||
|
||||
public SubscriptionServiceCache(ICacheNotify<SubscriptionRecord> notifyRecord, ICacheNotify<SubscriptionMethodCache> notifyMethod)
|
||||
{
|
||||
Cache = AscCache.Memory;
|
||||
NotifyRecord = notifyRecord;
|
||||
NotifyMethod = notifyMethod;
|
||||
|
||||
notifyRecord.Subscribe((s) =>
|
||||
{
|
||||
var store = GetSubsciptionsStore(s.Tenant, s.SourceId, s.ActionId);
|
||||
if (store != null)
|
||||
{
|
||||
lock (store)
|
||||
{
|
||||
store.SaveSubscription(s);
|
||||
}
|
||||
}
|
||||
}, CacheNotifyAction.InsertOrUpdate);
|
||||
|
||||
notifyRecord.Subscribe((s) =>
|
||||
{
|
||||
var store = GetSubsciptionsStore(s.Tenant, s.SourceId, s.ActionId);
|
||||
if (store != null)
|
||||
{
|
||||
lock (store)
|
||||
{
|
||||
if (s.ObjectId == null)
|
||||
{
|
||||
store.RemoveSubscriptions();
|
||||
}
|
||||
else
|
||||
{
|
||||
store.RemoveSubscriptions(s.ObjectId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, CacheNotifyAction.Remove);
|
||||
|
||||
notifyMethod.Subscribe((m) =>
|
||||
{
|
||||
var store = GetSubsciptionsStore(m.Tenant, m.SourceId, m.ActionId);
|
||||
if (store != null)
|
||||
{
|
||||
lock (store)
|
||||
{
|
||||
store.SetSubscriptionMethod(m);
|
||||
}
|
||||
}
|
||||
}, CacheNotifyAction.Any);
|
||||
}
|
||||
|
||||
private SubsciptionsStore GetSubsciptionsStore(int tenant, string sourceId, string actionId)
|
||||
{
|
||||
return Cache.Get<SubsciptionsStore>(GetKey(tenant, sourceId, actionId));
|
||||
}
|
||||
|
||||
public static string GetKey(int tenant, string sourceId, string actionId)
|
||||
{
|
||||
return string.Format("sub/{0}/{1}/{2}", tenant, sourceId, actionId);
|
||||
}
|
||||
}
|
||||
|
||||
public class CachedSubscriptionService : ISubscriptionService
|
||||
{
|
||||
private readonly ISubscriptionService service;
|
||||
@ -40,46 +108,13 @@ namespace ASC.Core.Caching
|
||||
|
||||
public TimeSpan CacheExpiration { get; set; }
|
||||
|
||||
|
||||
public CachedSubscriptionService(ISubscriptionService service, ICacheNotify<SubscriptionRecord> notifyRecord, ICacheNotify<SubscriptionMethodCache> notifyMethod)
|
||||
public CachedSubscriptionService(DbSubscriptionService service, SubscriptionServiceCache subscriptionServiceCache)
|
||||
{
|
||||
this.service = service ?? throw new ArgumentNullException("service");
|
||||
cache = AscCache.Memory;
|
||||
this.service = service ?? throw new ArgumentNullException("service");
|
||||
cache = subscriptionServiceCache.Cache;
|
||||
notifyRecord = subscriptionServiceCache.NotifyRecord;
|
||||
notifyMethod = subscriptionServiceCache.NotifyMethod;
|
||||
CacheExpiration = TimeSpan.FromMinutes(5);
|
||||
|
||||
notifyRecord.Subscribe((s) =>
|
||||
{
|
||||
var store = GetSubsciptionsStore(s.Tenant, s.SourceId, s.ActionId);
|
||||
lock (store)
|
||||
{
|
||||
store.SaveSubscription(s);
|
||||
}
|
||||
}, CacheNotifyAction.InsertOrUpdate);
|
||||
|
||||
notifyRecord.Subscribe((s) =>
|
||||
{
|
||||
var store = GetSubsciptionsStore(s.Tenant, s.SourceId, s.ActionId);
|
||||
lock (store)
|
||||
{
|
||||
if (s.ObjectId == null)
|
||||
{
|
||||
store.RemoveSubscriptions();
|
||||
}
|
||||
else
|
||||
{
|
||||
store.RemoveSubscriptions(s.ObjectId);
|
||||
}
|
||||
}
|
||||
}, CacheNotifyAction.Remove);
|
||||
|
||||
notifyMethod.Subscribe((m) =>
|
||||
{
|
||||
var store = GetSubsciptionsStore(m.Tenant, m.SourceId, m.ActionId);
|
||||
lock (store)
|
||||
{
|
||||
store.SetSubscriptionMethod(m);
|
||||
}
|
||||
}, CacheNotifyAction.Any);
|
||||
}
|
||||
|
||||
|
||||
@ -145,8 +180,8 @@ namespace ASC.Core.Caching
|
||||
|
||||
|
||||
private SubsciptionsStore GetSubsciptionsStore(int tenant, string sourceId, string actionId)
|
||||
{
|
||||
var key = string.Format("sub/{0}/{1}/{2}", tenant, sourceId, actionId);
|
||||
{
|
||||
var key = SubscriptionServiceCache.GetKey(tenant, sourceId, actionId);
|
||||
var store = cache.Get<SubsciptionsStore>(key);
|
||||
if (store == null)
|
||||
{
|
||||
@ -156,97 +191,95 @@ namespace ASC.Core.Caching
|
||||
}
|
||||
return store;
|
||||
}
|
||||
|
||||
|
||||
private class SubsciptionsStore
|
||||
{
|
||||
private readonly List<SubscriptionRecord> records;
|
||||
private IDictionary<string, List<SubscriptionRecord>> recordsByRec;
|
||||
private IDictionary<string, List<SubscriptionRecord>> recordsByObj;
|
||||
|
||||
private readonly List<SubscriptionMethod> methods;
|
||||
private IDictionary<string, List<SubscriptionMethod>> methodsByRec;
|
||||
|
||||
public SubsciptionsStore(IEnumerable<SubscriptionRecord> records, IEnumerable<SubscriptionMethod> methods)
|
||||
{
|
||||
this.records = records.ToList();
|
||||
this.methods = methods.ToList();
|
||||
BuildSubscriptionsIndex(records);
|
||||
BuildMethodsIndex(methods);
|
||||
}
|
||||
|
||||
public IEnumerable<SubscriptionRecord> GetSubscriptions()
|
||||
{
|
||||
return records.ToList();
|
||||
}
|
||||
|
||||
public IEnumerable<SubscriptionRecord> GetSubscriptions(string recipientId, string objectId)
|
||||
{
|
||||
return recipientId != null ?
|
||||
recordsByRec.ContainsKey(recipientId) ? recordsByRec[recipientId].ToList() : new List<SubscriptionRecord>() :
|
||||
recordsByObj.ContainsKey(objectId ?? string.Empty) ? recordsByObj[objectId ?? string.Empty].ToList() : new List<SubscriptionRecord>();
|
||||
}
|
||||
|
||||
public SubscriptionRecord GetSubscription(string recipientId, string objectId)
|
||||
{
|
||||
return recordsByRec.ContainsKey(recipientId) ?
|
||||
recordsByRec[recipientId].Where(s => s.ObjectId == objectId).FirstOrDefault() :
|
||||
null;
|
||||
}
|
||||
|
||||
public void SaveSubscription(SubscriptionRecord s)
|
||||
{
|
||||
var old = GetSubscription(s.RecipientId, s.ObjectId);
|
||||
if (old != null)
|
||||
{
|
||||
old.Subscribed = s.Subscribed;
|
||||
}
|
||||
else
|
||||
{
|
||||
records.Add(s);
|
||||
BuildSubscriptionsIndex(records);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveSubscriptions()
|
||||
{
|
||||
records.Clear();
|
||||
BuildSubscriptionsIndex(records);
|
||||
}
|
||||
|
||||
public void RemoveSubscriptions(string objectId)
|
||||
{
|
||||
records.RemoveAll(s => s.ObjectId == objectId);
|
||||
BuildSubscriptionsIndex(records);
|
||||
}
|
||||
|
||||
public IEnumerable<SubscriptionMethod> GetSubscriptionMethods(string recipientId)
|
||||
{
|
||||
return string.IsNullOrEmpty(recipientId) ?
|
||||
methods.ToList() :
|
||||
methodsByRec.ContainsKey(recipientId) ? methodsByRec[recipientId].ToList() : new List<SubscriptionMethod>();
|
||||
}
|
||||
|
||||
public void SetSubscriptionMethod(SubscriptionMethod m)
|
||||
{
|
||||
methods.RemoveAll(r => r.Tenant == m.Tenant && r.SourceId == m.SourceId && r.ActionId == m.ActionId && r.RecipientId == m.RecipientId);
|
||||
if (m.Methods != null && 0 < m.Methods.Length)
|
||||
{
|
||||
methods.Add(m);
|
||||
}
|
||||
BuildMethodsIndex(methods);
|
||||
}
|
||||
|
||||
private void BuildSubscriptionsIndex(IEnumerable<SubscriptionRecord> records)
|
||||
{
|
||||
recordsByRec = records.GroupBy(r => r.RecipientId).ToDictionary(g => g.Key, g => g.ToList());
|
||||
recordsByObj = records.GroupBy(r => r.ObjectId ?? string.Empty).ToDictionary(g => g.Key, g => g.ToList());
|
||||
}
|
||||
|
||||
private void BuildMethodsIndex(IEnumerable<SubscriptionMethod> methods)
|
||||
{
|
||||
methodsByRec = methods.GroupBy(r => r.RecipientId).ToDictionary(g => g.Key, g => g.ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
internal class SubsciptionsStore
|
||||
{
|
||||
private readonly List<SubscriptionRecord> records;
|
||||
private IDictionary<string, List<SubscriptionRecord>> recordsByRec;
|
||||
private IDictionary<string, List<SubscriptionRecord>> recordsByObj;
|
||||
|
||||
private readonly List<SubscriptionMethod> methods;
|
||||
private IDictionary<string, List<SubscriptionMethod>> methodsByRec;
|
||||
|
||||
public SubsciptionsStore(IEnumerable<SubscriptionRecord> records, IEnumerable<SubscriptionMethod> methods)
|
||||
{
|
||||
this.records = records.ToList();
|
||||
this.methods = methods.ToList();
|
||||
BuildSubscriptionsIndex(records);
|
||||
BuildMethodsIndex(methods);
|
||||
}
|
||||
|
||||
public IEnumerable<SubscriptionRecord> GetSubscriptions()
|
||||
{
|
||||
return records.ToList();
|
||||
}
|
||||
|
||||
public IEnumerable<SubscriptionRecord> GetSubscriptions(string recipientId, string objectId)
|
||||
{
|
||||
return recipientId != null ?
|
||||
recordsByRec.ContainsKey(recipientId) ? recordsByRec[recipientId].ToList() : new List<SubscriptionRecord>() :
|
||||
recordsByObj.ContainsKey(objectId ?? string.Empty) ? recordsByObj[objectId ?? string.Empty].ToList() : new List<SubscriptionRecord>();
|
||||
}
|
||||
|
||||
public SubscriptionRecord GetSubscription(string recipientId, string objectId)
|
||||
{
|
||||
return recordsByRec.ContainsKey(recipientId) ?
|
||||
recordsByRec[recipientId].Where(s => s.ObjectId == objectId).FirstOrDefault() :
|
||||
null;
|
||||
}
|
||||
|
||||
public void SaveSubscription(SubscriptionRecord s)
|
||||
{
|
||||
var old = GetSubscription(s.RecipientId, s.ObjectId);
|
||||
if (old != null)
|
||||
{
|
||||
old.Subscribed = s.Subscribed;
|
||||
}
|
||||
else
|
||||
{
|
||||
records.Add(s);
|
||||
BuildSubscriptionsIndex(records);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveSubscriptions()
|
||||
{
|
||||
records.Clear();
|
||||
BuildSubscriptionsIndex(records);
|
||||
}
|
||||
|
||||
public void RemoveSubscriptions(string objectId)
|
||||
{
|
||||
records.RemoveAll(s => s.ObjectId == objectId);
|
||||
BuildSubscriptionsIndex(records);
|
||||
}
|
||||
|
||||
public IEnumerable<SubscriptionMethod> GetSubscriptionMethods(string recipientId)
|
||||
{
|
||||
return string.IsNullOrEmpty(recipientId) ?
|
||||
methods.ToList() :
|
||||
methodsByRec.ContainsKey(recipientId) ? methodsByRec[recipientId].ToList() : new List<SubscriptionMethod>();
|
||||
}
|
||||
|
||||
public void SetSubscriptionMethod(SubscriptionMethod m)
|
||||
{
|
||||
methods.RemoveAll(r => r.Tenant == m.Tenant && r.SourceId == m.SourceId && r.ActionId == m.ActionId && r.RecipientId == m.RecipientId);
|
||||
if (m.Methods != null && 0 < m.Methods.Length)
|
||||
{
|
||||
methods.Add(m);
|
||||
}
|
||||
BuildMethodsIndex(methods);
|
||||
}
|
||||
|
||||
private void BuildSubscriptionsIndex(IEnumerable<SubscriptionRecord> records)
|
||||
{
|
||||
recordsByRec = records.GroupBy(r => r.RecipientId).ToDictionary(g => g.Key, g => g.ToList());
|
||||
recordsByObj = records.GroupBy(r => r.ObjectId ?? string.Empty).ToDictionary(g => g.Key, g => g.ToList());
|
||||
}
|
||||
|
||||
private void BuildMethodsIndex(IEnumerable<SubscriptionMethod> methods)
|
||||
{
|
||||
methodsByRec = methods.GroupBy(r => r.RecipientId).ToDictionary(g => g.Key, g => g.ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,155 +28,51 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Core.Data;
|
||||
using ASC.Core.Tenants;
|
||||
|
||||
namespace ASC.Core.Caching
|
||||
{
|
||||
public class CachedTenantService : ITenantService
|
||||
{
|
||||
private const string KEY = "tenants";
|
||||
private readonly ITenantService service;
|
||||
private readonly ICache cache;
|
||||
private readonly ICacheNotify<TenantSetting> cacheNotifySettings;
|
||||
private readonly ICacheNotify<TenantCacheItem> cacheNotifyItem;
|
||||
|
||||
|
||||
public TimeSpan CacheExpiration { get; set; }
|
||||
|
||||
public TimeSpan SettingsExpiration { get; set; }
|
||||
public CoreBaseSettings CoreBaseSettings { get; }
|
||||
|
||||
public CachedTenantService(ITenantService service, CoreBaseSettings coreBaseSettings, ICacheNotify<TenantCacheItem> cacheNotifyItem, ICacheNotify<TenantSetting> cacheNotifySettings)
|
||||
{
|
||||
public class TenantServiceCache
|
||||
{
|
||||
private const string KEY = "tenants";
|
||||
public TimeSpan CacheExpiration { get; set; }
|
||||
public ICache Cache { get; }
|
||||
public ICacheNotify<TenantCacheItem> CacheNotifyItem { get; }
|
||||
public ICacheNotify<TenantSetting> CacheNotifySettings { get; }
|
||||
|
||||
public TenantServiceCache(CoreBaseSettings coreBaseSettings, ICacheNotify<TenantCacheItem> cacheNotifyItem, ICacheNotify<TenantSetting> cacheNotifySettings)
|
||||
{
|
||||
this.service = service ?? throw new ArgumentNullException("service");
|
||||
CoreBaseSettings = coreBaseSettings;
|
||||
cache = AscCache.Memory;
|
||||
CacheExpiration = TimeSpan.FromMinutes(2);
|
||||
SettingsExpiration = TimeSpan.FromMinutes(2);
|
||||
|
||||
CacheNotifyItem = cacheNotifyItem;
|
||||
CacheNotifySettings = cacheNotifySettings;
|
||||
Cache = AscCache.Memory;
|
||||
CacheExpiration = TimeSpan.FromMinutes(2);
|
||||
|
||||
cacheNotifyItem.Subscribe((t) =>
|
||||
{
|
||||
var tenants = GetTenantStore();
|
||||
tenants.Remove(t.TenantId);
|
||||
tenants.Clear(CoreBaseSettings);
|
||||
tenants.Clear(coreBaseSettings);
|
||||
}, CacheNotifyAction.InsertOrUpdate);
|
||||
|
||||
cacheNotifySettings.Subscribe((s) =>
|
||||
{
|
||||
cache.Remove(s.Key);
|
||||
}, CacheNotifyAction.Remove);
|
||||
}
|
||||
|
||||
|
||||
public void ValidateDomain(string domain)
|
||||
Cache.Remove(s.Key);
|
||||
}, CacheNotifyAction.Remove);
|
||||
}
|
||||
|
||||
internal TenantStore GetTenantStore()
|
||||
{
|
||||
service.ValidateDomain(domain);
|
||||
}
|
||||
|
||||
public IEnumerable<Tenant> GetTenants(string login, string passwordHash)
|
||||
{
|
||||
return service.GetTenants(login, passwordHash);
|
||||
}
|
||||
|
||||
public IEnumerable<Tenant> GetTenants(DateTime from, bool active = true)
|
||||
{
|
||||
return service.GetTenants(from, active);
|
||||
}
|
||||
|
||||
public Tenant GetTenant(int id)
|
||||
{
|
||||
var tenants = GetTenantStore();
|
||||
var t = tenants.Get(id);
|
||||
if (t == null)
|
||||
{
|
||||
t = service.GetTenant(id);
|
||||
if (t != null)
|
||||
{
|
||||
tenants.Insert(t);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public Tenant GetTenant(string domain)
|
||||
{
|
||||
var tenants = GetTenantStore();
|
||||
var t = tenants.Get(domain);
|
||||
if (t == null)
|
||||
{
|
||||
t = service.GetTenant(domain);
|
||||
if (t != null)
|
||||
{
|
||||
tenants.Insert(t);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public Tenant GetTenantForStandaloneWithoutAlias(string ip)
|
||||
{
|
||||
var tenants = GetTenantStore();
|
||||
var t = tenants.Get(ip);
|
||||
if (t == null)
|
||||
{
|
||||
t = service.GetTenantForStandaloneWithoutAlias(ip);
|
||||
if (t != null)
|
||||
{
|
||||
tenants.Insert(t, ip);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public Tenant SaveTenant(CoreSettings coreSettings, Tenant tenant)
|
||||
{
|
||||
tenant = service.SaveTenant(coreSettings, tenant);
|
||||
cacheNotifyItem.Publish(new TenantCacheItem() { TenantId = tenant.TenantId }, CacheNotifyAction.InsertOrUpdate);
|
||||
return tenant;
|
||||
}
|
||||
|
||||
public void RemoveTenant(int id, bool auto = false)
|
||||
{
|
||||
service.RemoveTenant(id, auto);
|
||||
cacheNotifyItem.Publish(new TenantCacheItem() { TenantId = id }, CacheNotifyAction.InsertOrUpdate);
|
||||
}
|
||||
|
||||
public IEnumerable<TenantVersion> GetTenantVersions()
|
||||
{
|
||||
return service.GetTenantVersions();
|
||||
}
|
||||
|
||||
public byte[] GetTenantSettings(int tenant, string key)
|
||||
{
|
||||
var cacheKey = string.Format("settings/{0}/{1}", tenant, key);
|
||||
var data = cache.Get<byte[]>(cacheKey);
|
||||
if (data == null)
|
||||
{
|
||||
data = service.GetTenantSettings(tenant, key);
|
||||
cache.Insert(cacheKey, data ?? new byte[0], DateTime.UtcNow + SettingsExpiration);
|
||||
}
|
||||
return data == null ? null : data.Length == 0 ? null : data;
|
||||
}
|
||||
|
||||
public void SetTenantSettings(int tenant, string key, byte[] data)
|
||||
{
|
||||
service.SetTenantSettings(tenant, key, data);
|
||||
var cacheKey = string.Format("settings/{0}/{1}", tenant, key);
|
||||
cacheNotifySettings.Publish(new TenantSetting { Key = cacheKey }, CacheNotifyAction.Remove);
|
||||
}
|
||||
|
||||
private TenantStore GetTenantStore()
|
||||
{
|
||||
var store = cache.Get<TenantStore>(KEY);
|
||||
var store = Cache.Get<TenantStore>(KEY);
|
||||
if (store == null)
|
||||
{
|
||||
cache.Insert(KEY, store = new TenantStore(), DateTime.UtcNow.Add(CacheExpiration));
|
||||
Cache.Insert(KEY, store = new TenantStore(), DateTime.UtcNow.Add(CacheExpiration));
|
||||
}
|
||||
return store;
|
||||
}
|
||||
|
||||
|
||||
class TenantStore
|
||||
internal class TenantStore
|
||||
{
|
||||
private readonly Dictionary<int, Tenant> byId = new Dictionary<int, Tenant>();
|
||||
private readonly Dictionary<string, Tenant> byDomain = new Dictionary<string, Tenant>();
|
||||
@ -248,6 +144,126 @@ namespace ASC.Core.Caching
|
||||
byDomain.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CachedTenantService : ITenantService
|
||||
{
|
||||
private readonly ITenantService service;
|
||||
private readonly ICache cache;
|
||||
private readonly ICacheNotify<TenantSetting> cacheNotifySettings;
|
||||
private readonly ICacheNotify<TenantCacheItem> cacheNotifyItem;
|
||||
|
||||
public TimeSpan SettingsExpiration { get; set; }
|
||||
public TenantServiceCache TenantServiceCache { get; }
|
||||
|
||||
public CachedTenantService(DbTenantService service, TenantServiceCache tenantServiceCache)
|
||||
{
|
||||
this.service = service ?? throw new ArgumentNullException("service");
|
||||
cache = AscCache.Memory;
|
||||
SettingsExpiration = TimeSpan.FromMinutes(2);
|
||||
|
||||
TenantServiceCache = tenantServiceCache;
|
||||
cacheNotifyItem = tenantServiceCache.CacheNotifyItem;
|
||||
cacheNotifySettings = tenantServiceCache.CacheNotifySettings;
|
||||
}
|
||||
|
||||
|
||||
public void ValidateDomain(string domain)
|
||||
{
|
||||
service.ValidateDomain(domain);
|
||||
}
|
||||
|
||||
public IEnumerable<Tenant> GetTenants(string login, string passwordHash)
|
||||
{
|
||||
return service.GetTenants(login, passwordHash);
|
||||
}
|
||||
|
||||
public IEnumerable<Tenant> GetTenants(DateTime from, bool active = true)
|
||||
{
|
||||
return service.GetTenants(from, active);
|
||||
}
|
||||
|
||||
public Tenant GetTenant(int id)
|
||||
{
|
||||
var tenants = TenantServiceCache.GetTenantStore();
|
||||
var t = tenants.Get(id);
|
||||
if (t == null)
|
||||
{
|
||||
t = service.GetTenant(id);
|
||||
if (t != null)
|
||||
{
|
||||
tenants.Insert(t);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public Tenant GetTenant(string domain)
|
||||
{
|
||||
var tenants = TenantServiceCache.GetTenantStore();
|
||||
var t = tenants.Get(domain);
|
||||
if (t == null)
|
||||
{
|
||||
t = service.GetTenant(domain);
|
||||
if (t != null)
|
||||
{
|
||||
tenants.Insert(t);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public Tenant GetTenantForStandaloneWithoutAlias(string ip)
|
||||
{
|
||||
var tenants = TenantServiceCache.GetTenantStore();
|
||||
var t = tenants.Get(ip);
|
||||
if (t == null)
|
||||
{
|
||||
t = service.GetTenantForStandaloneWithoutAlias(ip);
|
||||
if (t != null)
|
||||
{
|
||||
tenants.Insert(t, ip);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public Tenant SaveTenant(CoreSettings coreSettings, Tenant tenant)
|
||||
{
|
||||
tenant = service.SaveTenant(coreSettings, tenant);
|
||||
cacheNotifyItem.Publish(new TenantCacheItem() { TenantId = tenant.TenantId }, CacheNotifyAction.InsertOrUpdate);
|
||||
return tenant;
|
||||
}
|
||||
|
||||
public void RemoveTenant(int id, bool auto = false)
|
||||
{
|
||||
service.RemoveTenant(id, auto);
|
||||
cacheNotifyItem.Publish(new TenantCacheItem() { TenantId = id }, CacheNotifyAction.InsertOrUpdate);
|
||||
}
|
||||
|
||||
public IEnumerable<TenantVersion> GetTenantVersions()
|
||||
{
|
||||
return service.GetTenantVersions();
|
||||
}
|
||||
|
||||
public byte[] GetTenantSettings(int tenant, string key)
|
||||
{
|
||||
var cacheKey = string.Format("settings/{0}/{1}", tenant, key);
|
||||
var data = cache.Get<byte[]>(cacheKey);
|
||||
if (data == null)
|
||||
{
|
||||
data = service.GetTenantSettings(tenant, key);
|
||||
cache.Insert(cacheKey, data ?? new byte[0], DateTime.UtcNow + SettingsExpiration);
|
||||
}
|
||||
return data == null ? null : data.Length == 0 ? null : data;
|
||||
}
|
||||
|
||||
public void SetTenantSettings(int tenant, string key, byte[] data)
|
||||
{
|
||||
service.SetTenantSettings(tenant, key, data);
|
||||
var cacheKey = string.Format("settings/{0}/{1}", tenant, key);
|
||||
cacheNotifySettings.Publish(new TenantSetting { Key = cacheKey }, CacheNotifyAction.Remove);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,59 +29,144 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Core.Data;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Core.Users;
|
||||
|
||||
namespace ASC.Core.Caching
|
||||
{
|
||||
public class CachedUserService : IUserService, ICachedService
|
||||
{
|
||||
private const string USERS = "users";
|
||||
{
|
||||
public class UserServiceCache
|
||||
{
|
||||
public const string USERS = "users";
|
||||
private const string GROUPS = "groups";
|
||||
private const string REFS = "refs";
|
||||
|
||||
private readonly IUserService service;
|
||||
private readonly ICache cache;
|
||||
private readonly ICacheNotify<UserGroupRefCacheItem> cacheUserGroupRefItem;
|
||||
private readonly ICacheNotify<UserPhotoCacheItem> cacheUserPhotoItem;
|
||||
private readonly ICacheNotify<UserInfoCacheItem> cacheUserInfoItem;
|
||||
private readonly ICacheNotify<GroupCacheItem> cacheGroupCacheItem;
|
||||
|
||||
private readonly TrustInterval trustInterval;
|
||||
private int getchanges;
|
||||
|
||||
|
||||
public TimeSpan CacheExpiration { get; set; }
|
||||
|
||||
public TimeSpan DbExpiration { get; set; }
|
||||
|
||||
public TimeSpan PhotoExpiration { get; set; }
|
||||
public CoreBaseSettings CoreBaseSettings { get; }
|
||||
|
||||
public CachedUserService(
|
||||
IUserService service,
|
||||
public const string REFS = "refs";
|
||||
|
||||
public TrustInterval TrustInterval { get; set; }
|
||||
public ICache Cache { get; }
|
||||
public CoreBaseSettings CoreBaseSettings { get; }
|
||||
public ICacheNotify<UserInfoCacheItem> CacheUserInfoItem { get; }
|
||||
public ICacheNotify<UserPhotoCacheItem> CacheUserPhotoItem { get; }
|
||||
public ICacheNotify<GroupCacheItem> CacheGroupCacheItem { get; }
|
||||
public ICacheNotify<UserGroupRefCacheItem> CacheUserGroupRefItem { get; }
|
||||
|
||||
public UserServiceCache(
|
||||
CoreBaseSettings coreBaseSettings,
|
||||
ICacheNotify<UserInfoCacheItem> cacheUserInfoItem,
|
||||
ICacheNotify<UserPhotoCacheItem> cacheUserPhotoItem,
|
||||
ICacheNotify<GroupCacheItem> cacheGroupCacheItem,
|
||||
ICacheNotify<UserGroupRefCacheItem> cacheUserGroupRefItem
|
||||
ICacheNotify<UserGroupRefCacheItem> cacheUserGroupRefItem)
|
||||
{
|
||||
TrustInterval = new TrustInterval();
|
||||
Cache = AscCache.Memory;
|
||||
CoreBaseSettings = coreBaseSettings;
|
||||
CacheUserInfoItem = cacheUserInfoItem;
|
||||
CacheUserPhotoItem = cacheUserPhotoItem;
|
||||
CacheGroupCacheItem = cacheGroupCacheItem;
|
||||
CacheUserGroupRefItem = cacheUserGroupRefItem;
|
||||
|
||||
cacheUserInfoItem.Subscribe((u) => InvalidateCache(u), CacheNotifyAction.Any);
|
||||
cacheUserPhotoItem.Subscribe((p) => Cache.Remove(p.Key), CacheNotifyAction.Remove);
|
||||
cacheGroupCacheItem.Subscribe((g) => InvalidateCache(), CacheNotifyAction.Any);
|
||||
|
||||
cacheUserGroupRefItem.Subscribe((r) => UpdateUserGroupRefCache(r, true), CacheNotifyAction.Remove);
|
||||
cacheUserGroupRefItem.Subscribe((r) => UpdateUserGroupRefCache(r, false), CacheNotifyAction.InsertOrUpdate);
|
||||
}
|
||||
|
||||
public void InvalidateCache()
|
||||
{
|
||||
InvalidateCache(null);
|
||||
}
|
||||
|
||||
private void InvalidateCache(UserInfoCacheItem userInfo)
|
||||
{
|
||||
if (CoreBaseSettings.Personal && userInfo != null)
|
||||
{
|
||||
var key = GetUserCacheKeyForPersonal(userInfo.Tenant, userInfo.ID.FromByteString());
|
||||
Cache.Remove(key);
|
||||
}
|
||||
|
||||
TrustInterval.Expire();
|
||||
}
|
||||
|
||||
private void UpdateUserGroupRefCache(UserGroupRef r, bool remove)
|
||||
{
|
||||
var key = GetRefCacheKey(r.Tenant);
|
||||
var refs = Cache.Get<UserGroupRefStore>(key);
|
||||
if (!remove && refs != null)
|
||||
{
|
||||
lock (refs)
|
||||
{
|
||||
refs[r.CreateKey()] = r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InvalidateCache();
|
||||
}
|
||||
}
|
||||
public static string GetUserPhotoCacheKey(int tenant, Guid userId)
|
||||
{
|
||||
return tenant.ToString() + "userphoto" + userId.ToString();
|
||||
}
|
||||
|
||||
public static string GetGroupCacheKey(int tenant)
|
||||
{
|
||||
return tenant.ToString() + GROUPS;
|
||||
}
|
||||
|
||||
public static string GetRefCacheKey(int tenant)
|
||||
{
|
||||
return tenant.ToString() + REFS;
|
||||
}
|
||||
|
||||
public static string GetUserCacheKey(int tenant)
|
||||
{
|
||||
return tenant.ToString() + USERS;
|
||||
}
|
||||
|
||||
public static string GetUserCacheKeyForPersonal(int tenant, Guid userId)
|
||||
{
|
||||
return tenant.ToString() + USERS + userId;
|
||||
}
|
||||
}
|
||||
|
||||
public class CachedUserService : IUserService, ICachedService
|
||||
{
|
||||
private readonly IUserService service;
|
||||
private readonly ICache cache;
|
||||
|
||||
private readonly TrustInterval trustInterval;
|
||||
private int getchanges;
|
||||
|
||||
public TimeSpan CacheExpiration { get; set; }
|
||||
public TimeSpan DbExpiration { get; set; }
|
||||
public TimeSpan PhotoExpiration { get; set; }
|
||||
public CoreBaseSettings CoreBaseSettings { get; }
|
||||
public UserServiceCache UserServiceCache { get; }
|
||||
public ICacheNotify<UserInfoCacheItem> CacheUserInfoItem { get; }
|
||||
public ICacheNotify<UserPhotoCacheItem> CacheUserPhotoItem { get; }
|
||||
public ICacheNotify<GroupCacheItem> CacheGroupCacheItem { get; }
|
||||
public ICacheNotify<UserGroupRefCacheItem> CacheUserGroupRefItem { get; }
|
||||
|
||||
public CachedUserService(
|
||||
DbUserService service,
|
||||
CoreBaseSettings coreBaseSettings,
|
||||
UserServiceCache userServiceCache
|
||||
)
|
||||
{
|
||||
this.service = service ?? throw new ArgumentNullException("service");
|
||||
CoreBaseSettings = coreBaseSettings;
|
||||
cache = AscCache.Memory;
|
||||
trustInterval = new TrustInterval();
|
||||
UserServiceCache = userServiceCache;
|
||||
cache = userServiceCache.Cache;
|
||||
CacheUserInfoItem = userServiceCache.CacheUserInfoItem;
|
||||
CacheUserPhotoItem = userServiceCache.CacheUserPhotoItem;
|
||||
CacheGroupCacheItem = userServiceCache.CacheGroupCacheItem;
|
||||
CacheUserGroupRefItem = userServiceCache.CacheUserGroupRefItem;
|
||||
trustInterval = userServiceCache.TrustInterval;
|
||||
|
||||
CacheExpiration = TimeSpan.FromMinutes(20);
|
||||
DbExpiration = TimeSpan.FromMinutes(1);
|
||||
PhotoExpiration = TimeSpan.FromMinutes(10);
|
||||
|
||||
cacheUserInfoItem.Subscribe((u) => InvalidateCache(u), CacheNotifyAction.Any);
|
||||
cacheUserPhotoItem.Subscribe((p) => cache.Remove(p.Key), CacheNotifyAction.Remove);
|
||||
cacheGroupCacheItem.Subscribe((g) => InvalidateCache(), CacheNotifyAction.Any);
|
||||
|
||||
cacheUserGroupRefItem.Subscribe((r) => UpdateUserGroupRefCache(r, true), CacheNotifyAction.Remove);
|
||||
cacheUserGroupRefItem.Subscribe((r) => UpdateUserGroupRefCache(r, false), CacheNotifyAction.InsertOrUpdate);
|
||||
PhotoExpiration = TimeSpan.FromMinutes(10);
|
||||
}
|
||||
|
||||
|
||||
@ -124,7 +209,7 @@ namespace ASC.Core.Caching
|
||||
{
|
||||
if (!CoreBaseSettings.Personal) return GetUser(tenant, id);
|
||||
|
||||
var key = GetUserCacheKeyForPersonal(tenant, id);
|
||||
var key = UserServiceCache.GetUserCacheKeyForPersonal(tenant, id);
|
||||
var user = cache.Get<UserInfo>(key);
|
||||
|
||||
if (user == null)
|
||||
@ -148,23 +233,23 @@ namespace ASC.Core.Caching
|
||||
public UserInfo SaveUser(int tenant, UserInfo user)
|
||||
{
|
||||
user = service.SaveUser(tenant, user);
|
||||
cacheUserInfoItem.Publish(new UserInfoCacheItem { ID = user.ID.ToByteString(), Tenant = tenant }, CacheNotifyAction.Any);
|
||||
CacheUserInfoItem.Publish(new UserInfoCacheItem { ID = user.ID.ToByteString(), Tenant = tenant }, CacheNotifyAction.Any);
|
||||
return user;
|
||||
}
|
||||
|
||||
public void RemoveUser(int tenant, Guid id)
|
||||
{
|
||||
service.RemoveUser(tenant, id);
|
||||
cacheUserInfoItem.Publish(new UserInfoCacheItem { Tenant = tenant, ID = id.ToByteString() }, CacheNotifyAction.Any);
|
||||
CacheUserInfoItem.Publish(new UserInfoCacheItem { Tenant = tenant, ID = id.ToByteString() }, CacheNotifyAction.Any);
|
||||
}
|
||||
|
||||
public byte[] GetUserPhoto(int tenant, Guid id)
|
||||
{
|
||||
var photo = cache.Get<byte[]>(GetUserPhotoCacheKey(tenant, id));
|
||||
var photo = cache.Get<byte[]>(UserServiceCache.GetUserPhotoCacheKey(tenant, id));
|
||||
if (photo == null)
|
||||
{
|
||||
photo = service.GetUserPhoto(tenant, id);
|
||||
cache.Insert(GetUserPhotoCacheKey(tenant, id), photo, PhotoExpiration);
|
||||
cache.Insert(UserServiceCache.GetUserPhotoCacheKey(tenant, id), photo, PhotoExpiration);
|
||||
}
|
||||
return photo;
|
||||
}
|
||||
@ -172,7 +257,7 @@ namespace ASC.Core.Caching
|
||||
public void SetUserPhoto(int tenant, Guid id, byte[] photo)
|
||||
{
|
||||
service.SetUserPhoto(tenant, id, photo);
|
||||
cacheUserPhotoItem.Publish(new UserPhotoCacheItem { Key = GetUserPhotoCacheKey(tenant, id) }, CacheNotifyAction.Remove);
|
||||
CacheUserPhotoItem.Publish(new UserPhotoCacheItem { Key = UserServiceCache.GetUserPhotoCacheKey(tenant, id) }, CacheNotifyAction.Remove);
|
||||
}
|
||||
|
||||
public string GetUserPassword(int tenant, Guid id)
|
||||
@ -208,14 +293,14 @@ namespace ASC.Core.Caching
|
||||
public Group SaveGroup(int tenant, Group group)
|
||||
{
|
||||
group = service.SaveGroup(tenant, group);
|
||||
cacheGroupCacheItem.Publish(new GroupCacheItem { ID = group.Id.ToString() }, CacheNotifyAction.Any);
|
||||
CacheGroupCacheItem.Publish(new GroupCacheItem { ID = group.Id.ToString() }, CacheNotifyAction.Any);
|
||||
return group;
|
||||
}
|
||||
|
||||
public void RemoveGroup(int tenant, Guid id)
|
||||
{
|
||||
service.RemoveGroup(tenant, id);
|
||||
cacheGroupCacheItem.Publish(new GroupCacheItem { ID = id.ToString() }, CacheNotifyAction.Any);
|
||||
CacheGroupCacheItem.Publish(new GroupCacheItem { ID = id.ToString() }, CacheNotifyAction.Any);
|
||||
}
|
||||
|
||||
|
||||
@ -223,7 +308,7 @@ namespace ASC.Core.Caching
|
||||
{
|
||||
GetChangesFromDb();
|
||||
|
||||
var key = GetRefCacheKey(tenant);
|
||||
var key = UserServiceCache.GetRefCacheKey(tenant);
|
||||
if (!(cache.Get<UserGroupRefStore>(key) is IDictionary<string, UserGroupRef> refs))
|
||||
{
|
||||
refs = service.GetUserGroupRefs(tenant, default);
|
||||
@ -238,7 +323,7 @@ namespace ASC.Core.Caching
|
||||
public UserGroupRef SaveUserGroupRef(int tenant, UserGroupRef r)
|
||||
{
|
||||
r = service.SaveUserGroupRef(tenant, r);
|
||||
cacheUserGroupRefItem.Publish(r, CacheNotifyAction.InsertOrUpdate);
|
||||
CacheUserGroupRefItem.Publish(r, CacheNotifyAction.InsertOrUpdate);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -247,23 +332,7 @@ namespace ASC.Core.Caching
|
||||
service.RemoveUserGroupRef(tenant, userId, groupId, refType);
|
||||
|
||||
var r = new UserGroupRef(userId, groupId, refType) { Tenant = tenant };
|
||||
cacheUserGroupRefItem.Publish(r, CacheNotifyAction.Remove);
|
||||
}
|
||||
|
||||
public void InvalidateCache()
|
||||
{
|
||||
InvalidateCache(null);
|
||||
}
|
||||
|
||||
private void InvalidateCache(UserInfoCacheItem userInfo)
|
||||
{
|
||||
if (CoreBaseSettings.Personal && userInfo != null)
|
||||
{
|
||||
var key = GetUserCacheKeyForPersonal(userInfo.Tenant, userInfo.ID.FromByteString());
|
||||
cache.Remove(key);
|
||||
}
|
||||
|
||||
trustInterval.Expire();
|
||||
CacheUserGroupRefItem.Publish(r, CacheNotifyAction.Remove);
|
||||
}
|
||||
|
||||
|
||||
@ -271,7 +340,7 @@ namespace ASC.Core.Caching
|
||||
{
|
||||
GetChangesFromDb();
|
||||
|
||||
var key = GetUserCacheKey(tenant);
|
||||
var key = UserServiceCache.GetUserCacheKey(tenant);
|
||||
var users = cache.Get<IDictionary<Guid, UserInfo>>(key);
|
||||
if (users == null)
|
||||
{
|
||||
@ -286,7 +355,7 @@ namespace ASC.Core.Caching
|
||||
{
|
||||
GetChangesFromDb();
|
||||
|
||||
var key = GetGroupCacheKey(tenant);
|
||||
var key = UserServiceCache.GetGroupCacheKey(tenant);
|
||||
var groups = cache.Get<IDictionary<Guid, Group>>(key);
|
||||
if (groups == null)
|
||||
{
|
||||
@ -324,7 +393,7 @@ namespace ASC.Core.Caching
|
||||
//get and merge changes in cached tenants
|
||||
foreach (var tenantGroup in service.GetUsers(Tenant.DEFAULT_TENANT, starttime).Values.GroupBy(u => u.Tenant))
|
||||
{
|
||||
var users = cache.Get<IDictionary<Guid, UserInfo>>(GetUserCacheKey(tenantGroup.Key));
|
||||
var users = cache.Get<IDictionary<Guid, UserInfo>>(UserServiceCache.GetUserCacheKey(tenantGroup.Key));
|
||||
if (users != null)
|
||||
{
|
||||
lock (users)
|
||||
@ -339,7 +408,7 @@ namespace ASC.Core.Caching
|
||||
|
||||
foreach (var tenantGroup in service.GetGroups(Tenant.DEFAULT_TENANT, starttime).Values.GroupBy(g => g.Tenant))
|
||||
{
|
||||
var groups = cache.Get<IDictionary<Guid, Group>>(GetGroupCacheKey(tenantGroup.Key));
|
||||
var groups = cache.Get<IDictionary<Guid, Group>>(UserServiceCache.GetGroupCacheKey(tenantGroup.Key));
|
||||
if (groups != null)
|
||||
{
|
||||
lock (groups)
|
||||
@ -354,7 +423,7 @@ namespace ASC.Core.Caching
|
||||
|
||||
foreach (var tenantGroup in service.GetUserGroupRefs(Tenant.DEFAULT_TENANT, starttime).Values.GroupBy(r => r.Tenant))
|
||||
{
|
||||
var refs = cache.Get<UserGroupRefStore>(GetRefCacheKey(tenantGroup.Key));
|
||||
var refs = cache.Get<UserGroupRefStore>(UserServiceCache.GetRefCacheKey(tenantGroup.Key));
|
||||
if (refs != null)
|
||||
{
|
||||
lock (refs)
|
||||
@ -373,49 +442,13 @@ namespace ASC.Core.Caching
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateUserGroupRefCache(UserGroupRef r, bool remove)
|
||||
{
|
||||
var key = GetRefCacheKey(r.Tenant);
|
||||
var refs = cache.Get<UserGroupRefStore>(key);
|
||||
if (!remove && refs != null)
|
||||
{
|
||||
lock (refs)
|
||||
{
|
||||
refs[r.CreateKey()] = r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InvalidateCache();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static string GetUserPhotoCacheKey(int tenant, Guid userId)
|
||||
{
|
||||
return tenant.ToString() + "userphoto" + userId.ToString();
|
||||
}
|
||||
|
||||
private static string GetGroupCacheKey(int tenant)
|
||||
{
|
||||
return tenant.ToString() + GROUPS;
|
||||
}
|
||||
|
||||
private static string GetRefCacheKey(int tenant)
|
||||
{
|
||||
return tenant.ToString() + REFS;
|
||||
}
|
||||
private static string GetUserCacheKey(int tenant)
|
||||
{
|
||||
return tenant.ToString() + USERS;
|
||||
}
|
||||
|
||||
private static string GetUserCacheKeyForPersonal(int tenant, Guid userId)
|
||||
{
|
||||
return tenant.ToString() + USERS + userId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void InvalidateCache()
|
||||
{
|
||||
UserServiceCache.InvalidateCache();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
class UserPhoto
|
||||
{
|
||||
|
@ -186,7 +186,7 @@ namespace ASC.Core
|
||||
|
||||
public Tenant GetCurrentTenant(bool throwIfNotFound)
|
||||
{
|
||||
return GetCurrentTenant(throwIfNotFound, HttpContext ?? ASC.Common.HttpContext.Current);
|
||||
return GetCurrentTenant(throwIfNotFound, HttpContext);
|
||||
}
|
||||
|
||||
public void SetCurrentTenant(Tenant tenant)
|
||||
|
@ -26,7 +26,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using ASC.Common.Data;
|
||||
using ASC.Common.Data.Sql;
|
||||
@ -38,8 +37,8 @@ namespace ASC.Core.Data
|
||||
{
|
||||
public class DbAzService : DbBaseService, IAzService
|
||||
{
|
||||
public DbAzService(ConnectionStringSettings connectionString, DbRegistry dbRegistry)
|
||||
: base(connectionString, dbRegistry, "tenant")
|
||||
public DbAzService(DbOptionsManager dbOptionsManager)
|
||||
: base(dbOptionsManager, "tenant")
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,8 @@ namespace ASC.Core.Data
|
||||
{
|
||||
private readonly string dbid;
|
||||
|
||||
public DbRegistry DbRegistry { get; }
|
||||
public DbRegistry DbRegistry { get; }
|
||||
public DbOptionsManager DbOptionsManager { get; }
|
||||
protected string TenantColumn
|
||||
{
|
||||
get;
|
||||
@ -48,6 +49,12 @@ namespace ASC.Core.Data
|
||||
dbid = connectionString.Name;
|
||||
DbRegistry = dbRegistry;
|
||||
TenantColumn = tenantColumn;
|
||||
}
|
||||
|
||||
protected DbBaseService(DbOptionsManager dbOptionsManager, string tenantColumn)
|
||||
{
|
||||
DbOptionsManager = dbOptionsManager;
|
||||
TenantColumn = tenantColumn;
|
||||
}
|
||||
|
||||
protected T ExecScalar<T>(ISqlInstruction sql)
|
||||
@ -77,7 +84,7 @@ namespace ASC.Core.Data
|
||||
|
||||
protected IDbManager GetDb()
|
||||
{
|
||||
return DbManager.FromHttpContext(DbRegistry, dbid);
|
||||
return DbOptionsManager?.Value;
|
||||
}
|
||||
|
||||
protected SqlQuery Query(string table, int tenant)
|
||||
@ -108,7 +115,7 @@ namespace ASC.Core.Data
|
||||
|
||||
private T Execute<T>(Func<IDbManager, T> action)
|
||||
{
|
||||
using var db = GetDb();
|
||||
var db = GetDb();
|
||||
return action(db);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using ASC.Common.Data;
|
||||
using ASC.Common.Data.Sql;
|
||||
@ -40,9 +39,8 @@ namespace ASC.Core.Data
|
||||
private const string tenants_quota = "tenants_quota";
|
||||
internal const string tenants_quotarow = "tenants_quotarow";
|
||||
|
||||
|
||||
public DbQuotaService(ConnectionStringSettings connectionString, DbRegistry dbRegistry)
|
||||
: base(connectionString, dbRegistry, "tenant")
|
||||
public DbQuotaService(DbOptionsManager dbOptionsManager)
|
||||
: base(dbOptionsManager, "tenant")
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using ASC.Common.Data;
|
||||
using ASC.Common.Data.Sql;
|
||||
@ -37,8 +36,8 @@ namespace ASC.Core.Data
|
||||
{
|
||||
public class DbSubscriptionService : DbBaseService, ISubscriptionService
|
||||
{
|
||||
public DbSubscriptionService(ConnectionStringSettings connectionString, DbRegistry dbRegistry)
|
||||
: base(connectionString, dbRegistry, "tenant")
|
||||
public DbSubscriptionService(DbOptionsManager dbOptionsManager)
|
||||
: base(dbOptionsManager, "tenant")
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -26,10 +26,10 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using ASC.Common.Data;
|
||||
using ASC.Common.Data.Sql;
|
||||
using ASC.Common.Data.Sql.Expressions;
|
||||
@ -47,8 +47,8 @@ namespace ASC.Core.Data
|
||||
public TenantDomainValidator TenantDomainValidator { get; }
|
||||
public TimeZoneConverter TimeZoneConverter { get; }
|
||||
|
||||
public DbTenantService(ConnectionStringSettings connectionString, DbRegistry dbRegistry, TenantDomainValidator tenantDomainValidator, TimeZoneConverter timeZoneConverter)
|
||||
: base(connectionString, dbRegistry, null)
|
||||
public DbTenantService(DbOptionsManager dbOptionsManager, TenantDomainValidator tenantDomainValidator, TimeZoneConverter timeZoneConverter)
|
||||
: base(dbOptionsManager, null)
|
||||
{
|
||||
TenantDomainValidator = tenantDomainValidator;
|
||||
TimeZoneConverter = timeZoneConverter;
|
||||
|
@ -26,7 +26,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using ASC.Common.Data;
|
||||
using ASC.Common.Data.Sql;
|
||||
@ -39,8 +38,8 @@ namespace ASC.Core.Data
|
||||
{
|
||||
public class DbUserService : DbBaseService, IUserService
|
||||
{
|
||||
public DbUserService(ConnectionStringSettings connectionString, DbRegistry dbRegistry)
|
||||
: base(connectionString, dbRegistry, "tenant")
|
||||
public DbUserService(DbOptionsManager dbOptionsManager)
|
||||
: base(dbOptionsManager, "tenant")
|
||||
{
|
||||
}
|
||||
|
||||
@ -213,7 +212,7 @@ namespace ASC.Core.Data
|
||||
user.LastModified = DateTime.UtcNow;
|
||||
user.Tenant = tenant;
|
||||
|
||||
using (var db = GetDb())
|
||||
var db = GetDb();
|
||||
using (var tx = db.BeginTransaction())
|
||||
{
|
||||
user.UserName = user.UserName.Trim();
|
||||
|
@ -77,7 +77,8 @@ namespace ASC.Core
|
||||
: this(configuration, tenantDomainValidator, timeZoneConverter, dbRegistry, connectionString, tariffServiceStorage, options, null)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//TODO:fix
|
||||
public HostedSolution(
|
||||
IConfiguration configuration,
|
||||
TenantDomainValidator tenantDomainValidator,
|
||||
@ -88,13 +89,13 @@ namespace ASC.Core
|
||||
IOptionsMonitor<LogNLog> options,
|
||||
string region)
|
||||
{
|
||||
tenantService = new DbTenantService(connectionString, dbRegistry, tenantDomainValidator, timeZoneConverter);
|
||||
tenantService = new DbTenantService(null, null, null);
|
||||
var baseSettings = new CoreBaseSettings(configuration);
|
||||
coreSettings = new CoreSettings(tenantService, baseSettings, configuration);
|
||||
|
||||
userService = new DbUserService(connectionString, dbRegistry);
|
||||
quotaService = new DbQuotaService(connectionString, dbRegistry);
|
||||
tariffService = new TariffService(connectionString, quotaService, tenantService, baseSettings, coreSettings, configuration, dbRegistry, tariffServiceStorage, options);
|
||||
userService = new DbUserService(null);
|
||||
quotaService = new DbQuotaService(null);
|
||||
tariffService = new TariffService(quotaService, tenantService, baseSettings, coreSettings, configuration, null, tariffServiceStorage, options);
|
||||
clientTenantManager = new TenantManager(tenantService, quotaService, tariffService, null, baseSettings, coreSettings);
|
||||
settingsManager = new DbSettingsManager(connectionString);
|
||||
Region = region ?? string.Empty;
|
||||
|
@ -51,6 +51,7 @@ namespace ASC.Core
|
||||
public TimeZoneConverter TimeZoneConverter { get; }
|
||||
public CookieStorage CookieStorage { get; }
|
||||
public DbRegistry DbRegistry { get; }
|
||||
public DbOptionsManager DbOptions { get; }
|
||||
public TariffServiceStorage TariffServiceStorage { get; }
|
||||
public IOptionsMonitor<LogNLog> Options { get; }
|
||||
|
||||
@ -60,6 +61,7 @@ namespace ASC.Core
|
||||
TimeZoneConverter timeZoneConverter,
|
||||
CookieStorage cookieStorage,
|
||||
DbRegistry dbRegistry,
|
||||
DbOptionsManager dbOptions,
|
||||
TariffServiceStorage tariffServiceStorage,
|
||||
IOptionsMonitor<LogNLog> options)
|
||||
{
|
||||
@ -69,6 +71,7 @@ namespace ASC.Core
|
||||
TimeZoneConverter = timeZoneConverter;
|
||||
CookieStorage = cookieStorage;
|
||||
DbRegistry = dbRegistry;
|
||||
DbOptions = dbOptions;
|
||||
TariffServiceStorage = tariffServiceStorage;
|
||||
Options = options;
|
||||
Initialize();
|
||||
@ -190,12 +193,12 @@ namespace ASC.Core
|
||||
|
||||
public IDbManager GetRegionDb(string region)
|
||||
{
|
||||
return new DbManager(DbRegistry, GetRegionService(region).DbId);
|
||||
return DbOptions.Get(GetRegionService(region).DbId);
|
||||
}
|
||||
|
||||
public IDbManager GetMultiRegionDb()
|
||||
{
|
||||
return new MultiRegionalDbManager(GetRegions().Select(r => new DbManager(DbRegistry, GetRegionService(r).DbId)));
|
||||
return new MultiRegionalDbManager(GetRegions().Select(r => DbOptions.Get(GetRegionService(r).DbId)));
|
||||
}
|
||||
|
||||
public System.Configuration.ConnectionStringSettings GetRegionConnectionString(string region)
|
||||
@ -264,7 +267,7 @@ namespace ASC.Core
|
||||
{
|
||||
try
|
||||
{
|
||||
using var db = new DbManager(DbRegistry, connectionString.Name);
|
||||
using var db = DbOptions.Get(connectionString.Name);
|
||||
var q = new SqlQuery("regions")
|
||||
.Select("region")
|
||||
.Select("connection_string")
|
||||
|
@ -30,9 +30,7 @@ namespace ASC.Core.Common.Tests
|
||||
using System.Linq;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.Data;
|
||||
using ASC.Common.Utils;
|
||||
using ASC.Core.Caching;
|
||||
using ASC.Core.Data;
|
||||
using ASC.Core.Caching;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using NUnit.Framework;
|
||||
|
||||
@ -44,7 +42,7 @@ namespace ASC.Core.Common.Tests
|
||||
|
||||
public CachedSubscriptionServiceTest(IConfiguration configuration, DbRegistry dbRegistry, ICacheNotify<SubscriptionRecord> cacheNotify, ICacheNotify<SubscriptionMethodCache> notify)
|
||||
{
|
||||
service = new CachedSubscriptionService(new DbSubscriptionService(configuration.GetConnectionStrings("core"), dbRegistry), cacheNotify, notify);
|
||||
service = new CachedSubscriptionService(null, null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,7 +40,14 @@ namespace ASC.Core.Common.Tests
|
||||
|
||||
[TestFixture]
|
||||
public class DbQuotaServiceTest : DbBaseTest<DbQuotaService>
|
||||
{
|
||||
{
|
||||
public DbOptionsManager DbOptionsManager { get; }
|
||||
|
||||
public DbQuotaServiceTest(DbOptionsManager dbOptionsManager)
|
||||
{
|
||||
DbOptionsManager = dbOptionsManager;
|
||||
}
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void ClearData()
|
||||
{
|
||||
@ -136,7 +143,7 @@ namespace ASC.Core.Common.Tests
|
||||
private void DeleteQuotaRow(TenantQuotaRow row)
|
||||
{
|
||||
var d = new SqlDelete(DbQuotaService.tenants_quotarow).Where("tenant", row.Tenant).Where("path", row.Path);
|
||||
using var dbManager = new DbManager(null, "core", null);
|
||||
var dbManager = DbOptionsManager.Value;
|
||||
dbManager.ExecuteNonQuery(d);
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ namespace ASC.Core.Common.Tests
|
||||
{
|
||||
using System;
|
||||
using System.Linq;
|
||||
using ASC.Common.Utils;
|
||||
using ASC.Core.Data;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Core.Users;
|
||||
@ -44,7 +43,7 @@ namespace ASC.Core.Common.Tests
|
||||
|
||||
public DbTenantServiceTest()
|
||||
{
|
||||
userService = new DbUserService(Configuration.GetConnectionStrings("core"), DbRegistry);
|
||||
userService = new DbUserService(null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,14 +28,7 @@
|
||||
namespace ASC.Core.Common.Tests
|
||||
{
|
||||
using System;
|
||||
using ASC.Common.Data;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Utils;
|
||||
using ASC.Core.Billing;
|
||||
using ASC.Core.Data;
|
||||
using ASC.Core.Tenants;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
using ASC.Core.Billing;
|
||||
using NUnit.Framework;
|
||||
|
||||
[TestFixture]
|
||||
@ -44,12 +37,9 @@ namespace ASC.Core.Common.Tests
|
||||
private readonly ITariffService tariffService;
|
||||
|
||||
|
||||
public TariffServiceTest(IConfiguration configuration, TenantDomainValidator tenantDomainValidator, TimeZoneConverter timeZoneConverter, DbRegistry dbRegistry, TariffServiceStorage tariffServiceStorage, IOptionsMonitor<LogNLog> options)
|
||||
public TariffServiceTest()
|
||||
{
|
||||
var cs = configuration.GetConnectionStrings("core");
|
||||
var tenantService = new DbTenantService(cs, dbRegistry, tenantDomainValidator, timeZoneConverter);
|
||||
var baseSettings = new CoreBaseSettings(configuration);
|
||||
tariffService = new TariffService(cs, new DbQuotaService(cs, dbRegistry), tenantService, baseSettings, new CoreSettings(tenantService, baseSettings, configuration), configuration, dbRegistry, tariffServiceStorage, options);
|
||||
tariffService = new TariffService(null, null, null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -49,7 +49,7 @@ namespace ASC.Core.Common.Tests
|
||||
|
||||
public TariffSyncServiceTest()
|
||||
{
|
||||
tariffSyncService = new TariffSyncService(ServiceProvider, Configuration, DbRegistry, Options);
|
||||
tariffSyncService = new TariffSyncService(null, null, null, null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -42,18 +42,18 @@ namespace ASC.Feed.Data
|
||||
public AuthContext AuthContext { get; }
|
||||
public TenantManager TenantManager { get; }
|
||||
public TenantUtil TenantUtil { get; }
|
||||
public DbRegistry DbRegistry { get; }
|
||||
public DbOptionsManager DbOptionsManager { get; }
|
||||
|
||||
public FeedAggregateDataProvider(DbRegistry dbRegistry)
|
||||
public FeedAggregateDataProvider(DbOptionsManager dbOptionsManager)
|
||||
{
|
||||
DbRegistry = dbRegistry;
|
||||
DbOptionsManager = dbOptionsManager;
|
||||
}
|
||||
public FeedAggregateDataProvider(AuthContext authContext, TenantManager tenantManager, TenantUtil tenantUtil, DbRegistry dbRegistry)
|
||||
public FeedAggregateDataProvider(AuthContext authContext, TenantManager tenantManager, TenantUtil tenantUtil, DbOptionsManager dbOptionsManager)
|
||||
{
|
||||
AuthContext = authContext;
|
||||
TenantManager = tenantManager;
|
||||
TenantUtil = tenantUtil;
|
||||
DbRegistry = dbRegistry;
|
||||
DbOptionsManager = dbOptionsManager;
|
||||
}
|
||||
|
||||
public DateTime GetLastTimeAggregate(string key)
|
||||
@ -62,17 +62,15 @@ namespace ASC.Feed.Data
|
||||
.Select("last_date")
|
||||
.Where("last_key", key);
|
||||
|
||||
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
|
||||
var db = GetDb();
|
||||
var value = db.ExecuteScalar<DateTime>(q);
|
||||
return value != default ? value.AddSeconds(1) : value;
|
||||
}
|
||||
|
||||
public void SaveFeeds(IEnumerable<FeedRow> feeds, string key, DateTime value)
|
||||
{
|
||||
using (var db = new DbManager(DbRegistry, Constants.FeedDbId))
|
||||
{
|
||||
db.ExecuteNonQuery(new SqlInsert("feed_last", true).InColumnValue("last_key", key).InColumnValue("last_date", value));
|
||||
}
|
||||
var db = GetDb();
|
||||
db.ExecuteNonQuery(new SqlInsert("feed_last", true).InColumnValue("last_key", key).InColumnValue("last_date", value));
|
||||
|
||||
const int feedsPortionSize = 1000;
|
||||
var aggregatedDate = DateTime.UtcNow;
|
||||
@ -94,7 +92,7 @@ namespace ASC.Feed.Data
|
||||
|
||||
private void SaveFeedsPortion(IEnumerable<FeedRow> feeds, DateTime aggregatedDate)
|
||||
{
|
||||
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
|
||||
var db = GetDb();
|
||||
using var tx = db.BeginTransaction();
|
||||
var i = new SqlInsert("feed_aggregate", true)
|
||||
.InColumns("id", "tenant", "product", "module", "author", "modified_by", "group_id", "created_date",
|
||||
@ -131,12 +129,12 @@ namespace ASC.Feed.Data
|
||||
|
||||
public void RemoveFeedAggregate(DateTime fromTime)
|
||||
{
|
||||
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
|
||||
var db = GetDb();
|
||||
using var command = db.Connection.CreateCommand();
|
||||
using var tx = db.Connection.BeginTransaction(IsolationLevel.ReadUncommitted);
|
||||
command.Transaction = tx;
|
||||
command.CommandTimeout = 60 * 60; // a hour
|
||||
var dialect = DbRegistry.GetSqlDialect(Constants.FeedDbId);
|
||||
var dialect = db.GetSqlDialect(Constants.FeedDbId);
|
||||
if (dialect.SupportMultiTableUpdate)
|
||||
{
|
||||
command.ExecuteNonQuery("delete from feed_aggregate, feed_users using feed_aggregate, feed_users where id = feed_id and aggregated_date < @date", new { date = fromTime });
|
||||
@ -228,7 +226,7 @@ namespace ASC.Feed.Data
|
||||
query.Where(exp);
|
||||
}
|
||||
|
||||
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
|
||||
var db = GetDb();
|
||||
var news = db
|
||||
.ExecuteList(query)
|
||||
.ConvertAll(r => new FeedResultItem(
|
||||
@ -259,13 +257,13 @@ namespace ASC.Feed.Data
|
||||
q.Where(Exp.Ge("a.aggregated_date", lastReadedTime));
|
||||
}
|
||||
|
||||
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
|
||||
var db = GetDb();
|
||||
return db.ExecuteList(q).Count();
|
||||
}
|
||||
|
||||
public IEnumerable<int> GetTenants(TimeInterval interval)
|
||||
{
|
||||
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
|
||||
var db = GetDb();
|
||||
var q = new SqlQuery("feed_aggregate")
|
||||
.Select("tenant")
|
||||
.Where(Exp.Between("aggregated_date", interval.From, interval.To))
|
||||
@ -279,7 +277,7 @@ namespace ASC.Feed.Data
|
||||
.Select("a.json, a.module, a.author, a.modified_by, a.group_id, a.created_date, a.modified_date, a.aggregated_date")
|
||||
.Where("a.id", id);
|
||||
|
||||
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
|
||||
var db = GetDb();
|
||||
var news = db
|
||||
.ExecuteList(query)
|
||||
.ConvertAll(r => new FeedResultItem(
|
||||
@ -298,19 +296,21 @@ namespace ASC.Feed.Data
|
||||
|
||||
public void RemoveFeedItem(string id)
|
||||
{
|
||||
using var db = new DbManager(DbRegistry, Constants.FeedDbId);
|
||||
var db = GetDb();
|
||||
using var command = db.Connection.CreateCommand();
|
||||
using var tx = db.Connection.BeginTransaction(IsolationLevel.ReadUncommitted);
|
||||
command.Transaction = tx;
|
||||
command.CommandTimeout = 60 * 60; // a hour
|
||||
|
||||
var dialect = DbRegistry.GetSqlDialect(Constants.FeedDbId);
|
||||
var dialect = db.GetSqlDialect(Constants.FeedDbId);
|
||||
|
||||
command.ExecuteNonQuery(new SqlDelete("feed_users").Where("feed_id", id), dialect);
|
||||
command.ExecuteNonQuery(new SqlDelete("feed_aggregate").Where("id", id), dialect);
|
||||
|
||||
tx.Commit();
|
||||
}
|
||||
|
||||
private IDbManager GetDb() => DbOptionsManager.Get(Constants.FeedDbId);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,13 +39,13 @@ namespace ASC.Feed.Data
|
||||
|
||||
public AuthContext AuthContext { get; }
|
||||
public TenantManager TenantManager { get; }
|
||||
public DbRegistry DbRegistry { get; }
|
||||
public DbOptionsManager DbOptionsManager { get; }
|
||||
|
||||
public FeedReadedDataProvider(AuthContext authContext, TenantManager tenantManager, DbRegistry dbRegistry)
|
||||
public FeedReadedDataProvider(AuthContext authContext, TenantManager tenantManager, DbOptionsManager dbOptionsManager)
|
||||
{
|
||||
AuthContext = authContext;
|
||||
TenantManager = tenantManager;
|
||||
DbRegistry = dbRegistry;
|
||||
DbOptionsManager = dbOptionsManager;
|
||||
}
|
||||
|
||||
public DateTime GetTimeReaded()
|
||||
@ -117,7 +117,7 @@ namespace ASC.Feed.Data
|
||||
|
||||
private DbManager GetDb()
|
||||
{
|
||||
return new DbManager(DbRegistry, dbId);
|
||||
return DbOptionsManager.Get(dbId);
|
||||
}
|
||||
|
||||
private int GetTenant()
|
||||
|
@ -47,16 +47,16 @@ namespace ASC.Resource.Manager
|
||||
private const string ResAuthorsLangTable = "res_authorslang";
|
||||
private const string ResAuthorsFileTable = "res_authorsfile";
|
||||
|
||||
public DbRegistry DbRegistry { get; }
|
||||
public DbOptionsManager DbOptionsManager { get; }
|
||||
|
||||
public ResourceData(DbRegistry dbRegistry)
|
||||
public ResourceData(DbOptionsManager dbOptionsManager)
|
||||
{
|
||||
DbRegistry = dbRegistry;
|
||||
DbOptionsManager = dbOptionsManager;
|
||||
}
|
||||
|
||||
public DateTime GetLastUpdate()
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlQuery(ResFilesTable).SelectMax("LastUpdate");
|
||||
|
||||
return dbManager.ExecuteScalar<DateTime>(sql);
|
||||
@ -64,7 +64,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public List<ResCulture> GetListLanguages(int fileId, string title)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlQuery(ResCultureTable)
|
||||
.Select("res_cultures.title", "res_cultures.value", "res_cultures.available")
|
||||
.LeftOuterJoin("res_data", Exp.EqColumns("res_cultures.title", "res_data.cultureTitle"))
|
||||
@ -80,7 +80,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public Dictionary<ResCulture, List<string>> GetCulturesWithAuthors()
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, "tmresource");
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlQuery("res_authorslang ral")
|
||||
.Select(new[] { "ral.authorLogin", "rc.title", "rc.value" })
|
||||
.InnerJoin("res_cultures rc", Exp.EqColumns("rc.title", "ral.cultureTitle"))
|
||||
@ -94,7 +94,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void AddCulture(string cultureTitle, string name)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sqlInsert = new SqlInsert(ResCultureTable);
|
||||
sqlInsert.InColumnValue("title", cultureTitle).InColumnValue("value", name);
|
||||
dbManager.ExecuteNonQuery(sqlInsert);
|
||||
@ -102,7 +102,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void AddResource(string cultureTitle, string resType, DateTime date, ResWord word, bool isConsole, string authorLogin, bool updateIfExist = true)
|
||||
{
|
||||
using var db = new DbManager(DbRegistry, Dbid);
|
||||
var db = GetDb();
|
||||
var resData = db.ExecuteScalar<string>(GetQuery(ResDataTable, cultureTitle, word));
|
||||
var resReserve = db.ExecuteScalar<string>(GetQuery(ResReserveTable, cultureTitle, word));
|
||||
|
||||
@ -166,7 +166,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void EditEnglish(ResWord word)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var update = new SqlUpdate(ResDataTable);
|
||||
update.Set("textvalue", word.ValueFrom).Where("fileID", word.ResFile.FileID).Where("title", word.Title).Where("cultureTitle", "Neutral");
|
||||
dbManager.ExecuteNonQuery(update);
|
||||
@ -174,7 +174,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void AddComment(ResWord word)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sqlUpdate = new SqlUpdate(ResDataTable);
|
||||
sqlUpdate.Set("description", word.TextComment).Where("title", word.Title).Where("fileID", word.ResFile.FileID).Where("cultureTitle", "Neutral");
|
||||
dbManager.ExecuteNonQuery(sqlUpdate);
|
||||
@ -189,7 +189,7 @@ namespace ASC.Resource.Manager
|
||||
fileName = fileNameWithoutExtension.Split('.')[0] + Path.GetExtension(fileName);
|
||||
}
|
||||
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlQuery(ResFilesTable)
|
||||
.SelectCount()
|
||||
.Where("resName", fileName)
|
||||
@ -220,7 +220,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public IEnumerable<ResCulture> GetCultures()
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlQuery(ResCultureTable);
|
||||
sql.Select("title", "value", "available")
|
||||
.OrderBy("title", true);
|
||||
@ -230,7 +230,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void SetCultureAvailable(string title)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlUpdate(ResCultureTable);
|
||||
sql.Set("available", true).Where("title", title);
|
||||
dbManager.ExecuteNonQuery(sql);
|
||||
@ -243,7 +243,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public List<ResFile> GetAllFiles()
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlQuery(ResFilesTable);
|
||||
|
||||
return dbManager.ExecuteList(sql.SelectAll()).Select(r => new ResFile
|
||||
@ -257,7 +257,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public IEnumerable<ResWord> GetListResWords(ResCurrent current, string search)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var exist = new SqlQuery(ResDataTable + " rd3")
|
||||
.Select("rd3.title")
|
||||
.Where("rd3.fileid = rd1.fileid")
|
||||
@ -313,7 +313,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public List<ResWord> GetListResWords(ResFile resFile, string to, string search)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlQuery(ResDataTable)
|
||||
.Select("title", "fileid", "textValue", "description", "flag", "link")
|
||||
.InnerJoin(ResFilesTable, Exp.EqColumns(ResFilesTable + ".ID", ResDataTable + ".fileID"))
|
||||
@ -335,7 +335,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void GetListModules(ResCurrent currentData)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var notExist = new SqlQuery(ResDataTable + " rd1")
|
||||
.Select("1")
|
||||
.Where("rd1.fileid = rd.fileid")
|
||||
@ -372,7 +372,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void LockModules(string projectName, string modules)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sqlUpdate = new SqlUpdate(ResFilesTable);
|
||||
sqlUpdate.Set("isLock", 1).Where("projectName", projectName).Where(Exp.In("moduleName", modules.Split(',')));
|
||||
dbManager.ExecuteNonQuery(sqlUpdate);
|
||||
@ -380,7 +380,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void UnLockModules()
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sqlUpdate = new SqlUpdate(ResFilesTable);
|
||||
sqlUpdate.Set("isLock", 0);
|
||||
dbManager.ExecuteNonQuery(sqlUpdate);
|
||||
@ -388,7 +388,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void AddLink(string resource, string fileName, string page)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var query = new SqlQuery(ResDataTable);
|
||||
query.Select(ResDataTable + ".id")
|
||||
.InnerJoin(ResFilesTable, Exp.EqColumns(ResFilesTable + ".id", ResDataTable + ".fileid"))
|
||||
@ -403,7 +403,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void GetResWordByKey(ResWord word, string to)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlQuery(ResDataTable)
|
||||
.Select("textvalue", "description", "link")
|
||||
.Where("fileID", word.ResFile.FileID)
|
||||
@ -433,7 +433,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void GetValueByKey(ResWord word, string to)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlQuery(ResDataTable);
|
||||
sql.Select("textvalue")
|
||||
.Where("fileID", word.ResFile.FileID)
|
||||
@ -456,7 +456,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public List<Author> GetListAuthors()
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlQuery(ResAuthorsTable)
|
||||
.Select("login", "password", "isAdmin");
|
||||
|
||||
@ -465,7 +465,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public Author GetAuthor(string login)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlQuery(ResAuthorsTable)
|
||||
.Select("login", "password", "isAdmin")
|
||||
.Where("login", login);
|
||||
@ -514,7 +514,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void CreateAuthor(Author author, IEnumerable<string> languages, string modules)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sqlInsert = new SqlInsert(ResAuthorsTable, true)
|
||||
.InColumnValue("login", author.Login)
|
||||
.InColumnValue("password", author.Password)
|
||||
@ -555,7 +555,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public List<ResWord> SearchAll(string projectName, string moduleName, string languageTo, string searchText, string searchType)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, Dbid);
|
||||
var dbManager = GetDb();
|
||||
var sql = new SqlQuery(ResDataTable)
|
||||
.Select("title", "fileid", "textValue", "resName", "moduleName", "projectName")
|
||||
.InnerJoin(ResFilesTable, Exp.EqColumns(ResFilesTable + ".ID", ResDataTable + ".fileID"))
|
||||
@ -578,7 +578,7 @@ namespace ASC.Resource.Manager
|
||||
|
||||
public void UpdateHashTable(ref Hashtable table, DateTime date)
|
||||
{
|
||||
using var dbManager = new DbManager(DbRegistry, "tmresourceTrans");
|
||||
var dbManager = GetDb("tmresourceTrans");
|
||||
var sql = new SqlQuery(ResDataTable)
|
||||
.Select(ResDataTable + ".textValue", ResDataTable + ".title", ResFilesTable + ".ResName", ResDataTable + ".cultureTitle")
|
||||
.InnerJoin(ResFilesTable, Exp.EqColumns(ResFilesTable + ".id", ResDataTable + ".fileID"))
|
||||
@ -597,6 +597,10 @@ namespace ASC.Resource.Manager
|
||||
}
|
||||
}
|
||||
|
||||
private IDbManager GetDb(string dbId = null)
|
||||
{
|
||||
return DbOptionsManager.Get(dbId ?? Dbid);
|
||||
}
|
||||
|
||||
private static ResWord GetWord(IList<object> r)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@ namespace ASC.People
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
using System.Configuration;
|
||||
|
||||
using ASC.Api.Core;
|
||||
using ASC.Api.Core.Auth;
|
||||
@ -117,85 +116,22 @@ namespace ASC.People
|
||||
.AddSingleton(typeof(ILog), typeof(LogNLog))
|
||||
.AddStorage(Configuration)
|
||||
.AddWebItemManager()
|
||||
.AddSingleton((r) =>
|
||||
{
|
||||
var DbRegistry = r.GetService<DbRegistry>();
|
||||
var cs = DbRegistry.GetConnectionString("core");
|
||||
if (cs == null)
|
||||
{
|
||||
throw new ConfigurationErrorsException("Can not configure CoreContext: connection string with name core not found.");
|
||||
}
|
||||
return (ISubscriptionService)new CachedSubscriptionService(new DbSubscriptionService(cs, DbRegistry), r.GetService<ICacheNotify<SubscriptionRecord>>(), r.GetService<ICacheNotify<SubscriptionMethodCache>>());
|
||||
})
|
||||
.AddSingleton((r) =>
|
||||
{
|
||||
var DbRegistry = r.GetService<DbRegistry>();
|
||||
var cs = DbRegistry.GetConnectionString("core");
|
||||
if (cs == null)
|
||||
{
|
||||
throw new ConfigurationErrorsException("Can not configure CoreContext: connection string with name core not found.");
|
||||
}
|
||||
return (IAzService)new CachedAzService(new DbAzService(cs, DbRegistry), r.GetService<ICacheNotify<AzRecordCache>>());
|
||||
})
|
||||
.AddSingleton((r) =>
|
||||
{
|
||||
var DbRegistry = r.GetService<DbRegistry>();
|
||||
var cs = DbRegistry.GetConnectionString("core");
|
||||
if (cs == null)
|
||||
{
|
||||
throw new ConfigurationErrorsException("Can not configure CoreContext: connection string with name core not found.");
|
||||
}
|
||||
return (IUserService)new CachedUserService(new DbUserService(cs, DbRegistry), r.GetService<CoreBaseSettings>(), r.GetService<ICacheNotify<UserInfoCacheItem>>(), r.GetService<ICacheNotify<UserPhotoCacheItem>>(), r.GetService<ICacheNotify<GroupCacheItem>>(), r.GetService<ICacheNotify<UserGroupRefCacheItem>>());
|
||||
})
|
||||
.AddSingleton((r) =>
|
||||
{
|
||||
var DbRegistry = r.GetService<DbRegistry>();
|
||||
var cs = DbRegistry.GetConnectionString("core");
|
||||
if (cs == null)
|
||||
{
|
||||
throw new ConfigurationErrorsException("Can not configure CoreContext: connection string with name core not found.");
|
||||
}
|
||||
return (ITenantService)new CachedTenantService(new DbTenantService(cs, DbRegistry, r.GetService<TenantDomainValidator>(), r.GetService<TimeZoneConverter>()), r.GetService<CoreBaseSettings>(), r.GetService<ICacheNotify<TenantCacheItem>>(), r.GetService<ICacheNotify<TenantSetting>>());
|
||||
})
|
||||
.AddSingleton((r) =>
|
||||
{
|
||||
var DbRegistry = r.GetService<DbRegistry>();
|
||||
var quotaCacheEnabled = false;
|
||||
if (Configuration["core:enable-quota-cache"] == null)
|
||||
{
|
||||
quotaCacheEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
quotaCacheEnabled = !bool.TryParse(Configuration["core:enable-quota-cache"], out var enabled) || enabled;
|
||||
}
|
||||
|
||||
var cs = DbRegistry.GetConnectionString("core");
|
||||
if (cs == null)
|
||||
{
|
||||
throw new ConfigurationErrorsException("Can not configure CoreContext: connection string with name core not found.");
|
||||
}
|
||||
return quotaCacheEnabled ? (IQuotaService)new CachedQuotaService(new DbQuotaService(cs, DbRegistry), r.GetService<ICacheNotify<QuotaCacheItem>>()) : new DbQuotaService(cs, DbRegistry);
|
||||
})
|
||||
.AddSingleton((r) =>
|
||||
{
|
||||
var DbRegistry = r.GetService<DbRegistry>();
|
||||
var cs = DbRegistry.GetConnectionString("core");
|
||||
if (cs == null)
|
||||
{
|
||||
throw new ConfigurationErrorsException("Can not configure CoreContext: connection string with name core not found.");
|
||||
}
|
||||
return (ITariffService)new TariffService(cs,
|
||||
r.GetService<IQuotaService>(),
|
||||
r.GetService<ITenantService>(),
|
||||
r.GetService<CoreBaseSettings>(),
|
||||
r.GetService<CoreSettings>(),
|
||||
Configuration,
|
||||
DbRegistry,
|
||||
r.GetService<TariffServiceStorage>(),
|
||||
r.GetService<IOptionsMonitor<LogNLog>>()
|
||||
);
|
||||
})
|
||||
.AddScoped<DbSubscriptionService>()
|
||||
.AddScoped<ISubscriptionService, CachedSubscriptionService>()
|
||||
.AddSingleton<SubscriptionServiceCache>()
|
||||
.AddScoped<DbAzService>()
|
||||
.AddScoped<IAzService, CachedAzService>()
|
||||
.AddSingleton<AzServiceCache>()
|
||||
.AddSingleton<UserServiceCache>()
|
||||
.AddScoped<DbUserService>()
|
||||
.AddScoped<IUserService, CachedUserService>()
|
||||
.AddSingleton<TenantServiceCache>()
|
||||
.AddScoped<DbTenantService>()
|
||||
.AddScoped<ITenantService, CachedTenantService>()
|
||||
.AddSingleton<QuotaServiceCache>()
|
||||
.AddScoped<DbQuotaService>()
|
||||
.AddScoped<IQuotaService, CachedQuotaService>()
|
||||
.AddScoped<ITariffService, TariffService>()
|
||||
.AddScoped<ApiContext>()
|
||||
.AddScoped<StudioNotifyService>()
|
||||
.AddScoped<UserManagerWrapper>()
|
||||
@ -252,7 +188,7 @@ namespace ASC.People
|
||||
.AddScoped<FileUtility>()
|
||||
.AddScoped<LicenseReader>()
|
||||
.AddScoped<ApiSystemHelper>()
|
||||
.AddSingleton<CoreSettings>()
|
||||
.AddScoped<CoreSettings>()
|
||||
.AddSingleton<WebPathSettings>()
|
||||
.AddSingleton<BaseStorageSettingsListener>()
|
||||
.AddSingleton<CoreBaseSettings>()
|
||||
|
@ -74,7 +74,7 @@ namespace ASC.Web.Core.Mail
|
||||
public DbRegistry DbRegistry { get; }
|
||||
public CoreBaseSettings CoreBaseSettings { get; }
|
||||
public MailServiceHelperStorage MailServiceHelperStorage { get; }
|
||||
|
||||
public DbOptionsManager DbOptions { get; }
|
||||
public ICache Cache { get; }
|
||||
|
||||
public MailServiceHelper(
|
||||
@ -83,7 +83,8 @@ namespace ASC.Web.Core.Mail
|
||||
IConfiguration configuration,
|
||||
DbRegistry dbRegistry,
|
||||
CoreBaseSettings coreBaseSettings,
|
||||
MailServiceHelperStorage mailServiceHelperStorage)
|
||||
MailServiceHelperStorage mailServiceHelperStorage,
|
||||
DbOptionsManager dbOptions)
|
||||
{
|
||||
UserManager = userManager;
|
||||
AuthContext = authContext;
|
||||
@ -91,6 +92,7 @@ namespace ASC.Web.Core.Mail
|
||||
DbRegistry = dbRegistry;
|
||||
CoreBaseSettings = coreBaseSettings;
|
||||
MailServiceHelperStorage = mailServiceHelperStorage;
|
||||
DbOptions = dbOptions;
|
||||
Cache = mailServiceHelperStorage.Cache;
|
||||
DefaultDatabase = GetDefaultDatabase();
|
||||
}
|
||||
@ -103,7 +105,7 @@ namespace ASC.Web.Core.Mail
|
||||
|
||||
private DbManager GetDb()
|
||||
{
|
||||
return new DbManager(DbRegistry, "webstudio");
|
||||
return DbOptions.Get("webstudio");
|
||||
}
|
||||
|
||||
private DbManager GetDb(string dbid, string connectionString)
|
||||
@ -117,7 +119,7 @@ namespace ASC.Web.Core.Mail
|
||||
|
||||
DbRegistry.RegisterDatabase(connectionSettings.Name, connectionSettings);
|
||||
|
||||
return new DbManager(DbRegistry, connectionSettings.Name);
|
||||
return DbOptions.Get(connectionSettings.Name);
|
||||
}
|
||||
|
||||
private void DemandPermission()
|
||||
|
@ -99,7 +99,7 @@ namespace ASC.Web.Studio.Core.Notify
|
||||
var commonLinkUtility = scope.ServiceProvider.GetService<CommonLinkUtility>();
|
||||
var apiSystemHelper = scope.ServiceProvider.GetService<ApiSystemHelper>();
|
||||
var setupInfo = scope.ServiceProvider.GetService<SetupInfo>();
|
||||
var dbRegistry = scope.ServiceProvider.GetService<DbRegistry>();
|
||||
var options = scope.ServiceProvider.GetService<DbOptionsManager>();
|
||||
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
|
||||
|
||||
var tariff = paymentManager.GetTariff(tenant.TenantId);
|
||||
@ -200,12 +200,11 @@ namespace ASC.Web.Studio.Core.Notify
|
||||
.Where(Exp.Le("created_date", now.AddDays(-1)))
|
||||
.GroupBy("short_date");
|
||||
|
||||
using (var db = new DbManager(dbRegistry, dbid))
|
||||
{
|
||||
datesWithActivity = db
|
||||
.ExecuteList(query)
|
||||
.ConvertAll(r => Convert.ToDateTime(r[0]));
|
||||
}
|
||||
var db = options.Get(dbid);
|
||||
|
||||
datesWithActivity = db
|
||||
.ExecuteList(query)
|
||||
.ConvertAll(r => Convert.ToDateTime(r[0]));
|
||||
|
||||
if (datesWithActivity.Count < 5)
|
||||
{
|
||||
@ -559,7 +558,7 @@ namespace ASC.Web.Studio.Core.Notify
|
||||
var tenantExtra = scope.ServiceProvider.GetService<TenantExtra>();
|
||||
var coreBaseSettings = scope.ServiceProvider.GetService<CoreBaseSettings>();
|
||||
var commonLinkUtility = scope.ServiceProvider.GetService<CommonLinkUtility>();
|
||||
var dbRegistry = scope.ServiceProvider.GetService<DbRegistry>();
|
||||
var options = scope.ServiceProvider.GetService<DbOptionsManager>();
|
||||
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(studioNotifyHelper.NotifySource, scope);
|
||||
|
||||
var tariff = paymentManager.GetTariff(tenant.TenantId);
|
||||
@ -690,12 +689,11 @@ namespace ASC.Web.Studio.Core.Notify
|
||||
.Where(Exp.Le("created_date", now.AddDays(-1)))
|
||||
.GroupBy("short_date");
|
||||
|
||||
using (var db = new DbManager(dbRegistry, dbid))
|
||||
{
|
||||
datesWithActivity = db
|
||||
.ExecuteList(query)
|
||||
.ConvertAll(r => Convert.ToDateTime(r[0]));
|
||||
}
|
||||
var db = options.Get(dbid);
|
||||
|
||||
datesWithActivity = db
|
||||
.ExecuteList(query)
|
||||
.ConvertAll(r => Convert.ToDateTime(r[0]));
|
||||
|
||||
if (datesWithActivity.Count < 5)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user