Revert "some useless shit"

This reverts commit 3954f95abc.
This commit is contained in:
2021-05-20 15:21:37 +02:00
parent 3954f95abc
commit d2b95b4aea
15 changed files with 82 additions and 256 deletions
+42 -27
View File
@@ -1,25 +1,26 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.Logging;
using Raven.Client.Documents;
using Raven.Client.Documents.Session;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using zero.Core.Caches.Internal;
using zero.Core.Database;
using zero.Core.Entities;
using zero.Core.Extensions;
using zero.Core.Handlers;
using zero.Core.Identity;
using zero.Core.Options;
namespace zero.Core
{
public class ApplicationResolver : IApplicationResolver
{
ApplicationCache _applicationCache;
BackofficeUserCache _backofficeUserCache;
protected IZeroStore Store { get; private set; }
protected IZeroOptions Options { get; private set; }
@@ -27,12 +28,13 @@ namespace zero.Core
protected IHandlerHolder Handler { get; private set; }
private IList<Application> Apps { get; set; }
public ApplicationResolver(IZeroStore store, IZeroOptions options, ILogger<ApplicationResolver> logger, IHandlerHolder handler = null)
{
_applicationCache = new ApplicationCache(store);
_backofficeUserCache = new BackofficeUserCache(store);
Store = store;
Options = options;
Logger = logger;
Handler = handler;
@@ -62,7 +64,8 @@ namespace zero.Core
if (app == null)
{
//Logger.LogWarning("Could not resolve application for host {host}", context.Request.Host);
app = _applicationCache.All.FirstOrDefault();
IList<Application> apps = await GetApplications();
app = apps.FirstOrDefault();
}
return app;
@@ -72,20 +75,13 @@ namespace zero.Core
/// <inheritdoc />
public async Task<Application> ResolveFromUser(ClaimsPrincipal user)
{
BackofficeUserCache.Result userEntity = GetBackofficeUser(user);
return userEntity != null ? await ResolveFromUser(new BackofficeUser()
{
Id = userEntity.Id,
AppId = userEntity.AppId,
CurrentAppId = userEntity.CurrentAppId,
Claims = userEntity.Claims,
IsSuper = userEntity.IsSuper
}) : null;
BackofficeUser userEntity = await GetBackofficeUser(user);
return await ResolveFromUser(userEntity);
}
/// <inheritdoc />
public Task<Application> ResolveFromUser(BackofficeUser user)
public async Task<Application> ResolveFromUser(BackofficeUser user)
{
if (user == null)
{
@@ -116,35 +112,36 @@ namespace zero.Core
throw new Exception($"User entity ${user.Id} needs a valid AppId");
}
return Task.FromResult(_applicationCache.ById(appId));
using IAsyncDocumentSession session = Store.OpenCoreSession();
return await session.LoadAsync<Application>(appId);
}
/// <inheritdoc />
public async Task<Application> ResolveFromRequest(HttpContext context)
{
return Handler.Get<IApplicationResolverHandler>()?.Resolve(context.Request, _applicationCache.All) ?? await ResolveFromUri(context.Request.GetEncodedUrl());
return Handler.Get<IApplicationResolverHandler>()?.Resolve(context.Request, await GetApplications()) ?? await ResolveFromUri(context.Request.GetEncodedUrl());
}
/// <inheritdoc />
public Task<Application> ResolveFromUri(string uriString)
public async Task<Application> ResolveFromUri(string uriString)
{
return Task.FromResult(ResolveFromUriInternal(new Uri(uriString, UriKind.Absolute), _applicationCache.All));
return ResolveFromUriInternal(new Uri(uriString, UriKind.Absolute), await GetApplications());
}
/// <inheritdoc />
public Task<Application> ResolveFromUri(Uri uri)
public async Task<Application> ResolveFromUri(Uri uri)
{
return Task.FromResult(ResolveFromUriInternal(uri, _applicationCache.All));
return ResolveFromUriInternal(uri, await GetApplications());
}
/// <summary>
/// Get matching application from an URI
/// </summary>
Application ResolveFromUriInternal(Uri uri, IEnumerable<Application> apps)
Application ResolveFromUriInternal(Uri uri, IList<Application> apps)
{
foreach (Application app in apps)
{
@@ -168,13 +165,31 @@ namespace zero.Core
}
/// <summary>
/// Get all applications to choose from
/// </summary>
async Task<IList<Application>> GetApplications()
{
if (Apps != null)
{
return Apps;
}
using IAsyncDocumentSession session = Store.OpenCoreSession();
Apps = await session.Query<Application>().ToListAsync();
return Apps;
}
/// <summary>
/// Get backoffice user from claims principal
/// </summary>
BackofficeUserCache.Result GetBackofficeUser(ClaimsPrincipal user)
async Task<BackofficeUser> GetBackofficeUser(ClaimsPrincipal user)
{
string userId = user.FindFirstValue(Constants.Auth.Claims.UserId);
return _backofficeUserCache.ById(userId);
using IAsyncDocumentSession session = Store.OpenCoreSession();
return await session.LoadAsync<BackofficeUser>(userId);
}
}
@@ -1,10 +0,0 @@
using zero.Core.Database;
using zero.Core.Entities;
namespace zero.Core.Caches.Internal
{
public class ApplicationCache : InternalEntityCache<Application>
{
public ApplicationCache(IZeroStore store) : base(store) { }
}
}
@@ -1,19 +0,0 @@
using System.Collections.Generic;
using zero.Core.Database;
using zero.Core.Entities;
namespace zero.Core.Caches.Internal
{
public class BackofficeUserCache : InternalEntityCache<BackofficeUserCache.Result, BackofficeUser>
{
public BackofficeUserCache(IZeroStore store) : base(store) { }
public class Result : ZeroIdEntity
{
public string AppId { get; set; }
public string CurrentAppId { get; set; }
public bool IsSuper { get; set; }
public List<UserClaim> Claims { get; set; } = new();
}
}
}
@@ -1,119 +0,0 @@
using Raven.Client.Documents;
using Raven.Client.Documents.Changes;
using Raven.Client.Documents.Session;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using zero.Core.Database;
using zero.Core.Entities;
using zero.Core.Extensions;
namespace zero.Core.Caches.Internal
{
public abstract class InternalEntityCache<T> : InternalEntityCache<T, T>, IInternalEntityCache<T> where T : ZeroIdEntity
{
public InternalEntityCache(IZeroStore store, bool isCore = true) : base(store, isCore) { }
}
public abstract class InternalEntityCache<TProjection, T> : IInternalEntityCache<TProjection, T>, IDisposable where T : ZeroIdEntity where TProjection : ZeroIdEntity
{
protected IZeroStore Store { get; private set; }
protected ConcurrentBag<TProjection> _cache = new();
protected bool _isDirty = true;
protected bool _isCore = true;
IDatabaseChanges _subscription = null;
public InternalEntityCache(IZeroStore store, bool isCore = true)
{
Store = store;
_isCore = isCore;
_subscription = store.Changes(isCore ? store.CoreDatabase : store.ResolvedDatabase);
_subscription
.ForDocumentsInCollection<T>()
.Subscribe(change => Refresh(change));
}
/// <inheritdoc />
public bool IsDirty => _isDirty;
/// <inheritdoc />
public ConcurrentBag<TProjection> All
{
get
{
CheckIntegrity();
return _cache;
}
}
/// <inheritdoc />
public TProjection ById(string id)
{
if (id.IsNullOrEmpty())
{
return default;
}
CheckIntegrity();
return _cache.FirstOrDefault(x => x.Id == id);
}
/// <inheritdoc />
public void Dispose()
{
_subscription?.Dispose();
}
void CheckIntegrity()
{
if (_isDirty || _cache.IsEmpty)
{
Refresh();
}
}
/// <summary>
/// Refreshes the application cache
/// </summary>
protected virtual void Refresh(DocumentChange change = null)
{
_isDirty = true;
using IDocumentSession session = Store.OpenSession(_isCore ? Store.CoreDatabase : Store.ResolvedDatabase);
List<TProjection> items = session.Query<T>().ProjectInto<TProjection>().ToList();
_cache.Clear();
foreach (TProjection item in items)
{
_cache.Add(item);
}
_isDirty = false;
}
}
public interface IInternalEntityCache<T> : IInternalEntityCache<T, T> where T : ZeroIdEntity { }
public interface IInternalEntityCache<TProjection, T> : IDisposable where T : ZeroIdEntity where TProjection : ZeroIdEntity
{
/// <summary>
/// Get all registered items
/// </summary>
ConcurrentBag<TProjection> All { get; }
/// <summary>
/// Get a registered items by ID
/// </summary>
TProjection ById(string id);
}
}
+28 -26
View File
@@ -1,10 +1,10 @@
using FluentValidation;
using Microsoft.Extensions.Logging;
using Raven.Client.Documents;
using Raven.Client.Documents.Session;
using System;
using System.Globalization;
using System.Threading.Tasks;
using zero.Core.Database;
using zero.Core.Entities;
namespace zero.Core.Cultures
@@ -13,6 +13,7 @@ namespace zero.Core.Cultures
{
protected ILogger<CultureResolver> Logger { get; private set; }
public CultureResolver(ILogger<CultureResolver> logger)
{
Logger = logger;
@@ -20,32 +21,38 @@ namespace zero.Core.Cultures
/// <inheritdoc />
public CultureInfo DefaultCurrentCulture => CultureInfo.CurrentCulture;
/// <inheritdoc />
public async Task<CultureInfo> Resolve(IZeroDocumentSession session)
public async Task<CultureInfo> Resolve(IZeroContext context)
{
using IAsyncDocumentSession session = context.Store.OpenAsyncSession();
// TODO this is just fake, we need to correctly resolve culture here
Language language = await session.Query<Language>().FirstOrDefaultAsync();
if (language == null)
if (context.IsBackofficeRequest)
{
Logger.LogWarning("Could not set request culture as there is no available Language stored");
return CultureInfo.CurrentCulture;
}
try
{
CultureInfo culture = CultureInfo.CreateSpecificCulture(language.Code);
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
ValidatorOptions.Global.LanguageManager.Culture = culture;
}
catch (Exception ex)
else
{
Logger.LogError(ex, "Could not create culture from Language code {code}", language.Code);
return CultureInfo.CurrentCulture;
Language language = await session.Query<Language>().FirstOrDefaultAsync();
if (language == null)
{
Logger.LogWarning("Could not set request culture as there is no available Language stored");
return CultureInfo.CurrentCulture;
}
try
{
CultureInfo culture = CultureInfo.CreateSpecificCulture(language.Code);
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
ValidatorOptions.Global.LanguageManager.Culture = culture;
}
catch (Exception ex)
{
Logger.LogError(ex, "Could not create culture from Language code {code}", language.Code);
return CultureInfo.CurrentCulture;
}
}
return CultureInfo.CurrentCulture;
@@ -55,15 +62,10 @@ namespace zero.Core.Cultures
public interface ICultureResolver
{
/// <summary>
/// Default value for CultureInfo.CurrentCulture
/// </summary>
CultureInfo DefaultCurrentCulture { get; }
/// <summary>
/// Resolves the current application from either the backoffice user (in case it is backoffice request)
/// or the domain (in case it is frontend request).
/// </summary>
Task<CultureInfo> Resolve(IZeroDocumentSession session);
Task<CultureInfo> Resolve(IZeroContext context);
}
}
@@ -1,19 +0,0 @@
using Raven.Client.Documents.Indexes;
using System.Linq;
using zero.Core.Routing;
namespace zero.Core.Database.Indexes
{
public class Routes_ForResolver : AbstractIndexCreationTask<Route>
{
public Routes_ForResolver()
{
Map = items => items
.Select(x => new
{
Url = x.Url,
AllowSuffix = x.AllowSuffix
});
}
}
}
+2 -7
View File
@@ -4,7 +4,7 @@ using System;
namespace zero.Core.Database
{
public class ZeroDocumentSession : AsyncDocumentSession, IZeroDocumentSession, IZeroCoreDocumentSession
public class ZeroDocumentSession : AsyncDocumentSession, IZeroDocumentSession
{
public ZeroDocumentSession(DocumentStore documentStore, Guid id, SessionOptions options) : base(documentStore, id, options)
{
@@ -12,14 +12,9 @@ namespace zero.Core.Database
}
}
public interface IZeroDocumentSession : IAsyncDocumentSession
{
}
public interface IZeroCoreDocumentSession : IAsyncDocumentSession
{
}
}
-8
View File
@@ -24,9 +24,6 @@ namespace zero.Core.Database
/// <inheritdoc />
public string ResolvedDatabase { get; set; }
/// <inheritdoc />
public string CoreDatabase => Options.Raven.Database;
/// <inheritdoc />
public IDocumentStore Raven => this;
@@ -142,11 +139,6 @@ namespace zero.Core.Database
/// </summary>
string ResolvedDatabase { get; set; }
/// <summary>
/// The core database which hosts applications, users and shared resources
/// </summary>
string CoreDatabase { get; }
/// <summary>
/// Get underlying raven document store
/// </summary>
@@ -10,6 +10,6 @@ namespace zero.Core.Handlers
{
public interface IApplicationResolverHandler : IHandler
{
Application Resolve(HttpRequest request, IEnumerable<Application> applications);
Application Resolve(HttpRequest request, IList<Application> applications);
}
}
+1 -2
View File
@@ -9,7 +9,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using zero.Core.Database;
using zero.Core.Database.Indexes;
using zero.Core.Entities;
using zero.Core.Extensions;
using zero.Core.Options;
@@ -139,7 +138,7 @@ namespace zero.Core.Routing
min -= 1;
}
IList<Route> routes = await session.Query<Route, Routes_ForResolver>()
IList<Route> routes = await session.Query<Route>()
.Where(x => (!x.AllowSuffix && x.Url == path) || (x.AllowSuffix && x.Url.In(parts)))
.Include("References[].Id")
.Include("Dependencies")
+1 -5
View File
@@ -9,19 +9,15 @@ namespace zero.Core.Routing
public class ZeroRoutesTransformer : DynamicRouteValueTransformer
{
IRoutes Routes;
IZeroContext Context;
public ZeroRoutesTransformer(IRoutes routes, IZeroContext context)
public ZeroRoutesTransformer(IRoutes routes)
{
Routes = routes;
Context = context;
}
public override async ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
{
Console.WriteLine("ZeroRoutesTransformer");
await Context.Resolve(httpContext);
IResolvedRoute route = await Routes.ResolveUrl(httpContext);
if (route == null)
+6 -2
View File
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Raven.Client.Documents.Session;
using System.Security.Claims;
using System.Threading.Tasks;
using zero.Core.Cultures;
@@ -41,16 +42,19 @@ namespace zero.Core
protected IApplicationResolver AppResolver { get; private set; }
protected ICultureResolver CultureResolver { get; private set; }
protected ILogger<ZeroContext> Logger { get; private set; }
private bool _resolved = false;
public ZeroContext(IZeroOptions options, IApplicationResolver appResolver, ILogger<ZeroContext> logger, IZeroStore store)
public ZeroContext(IZeroOptions options, IApplicationResolver appResolver, ICultureResolver cultureResolver, ILogger<ZeroContext> logger, IZeroStore store)
{
Options = options;
AppResolver = appResolver;
CultureResolver = cultureResolver;
Logger = logger;
Store = store;
}
@@ -96,7 +100,7 @@ namespace zero.Core
Store.ResolvedDatabase = Application.Database;
// set current culture
//await CultureResolver.Resolve(this);
await CultureResolver.Resolve(this);
// resolve request route
if (IsBackofficeRequest is false && context.Request.RouteValues.TryGetValue("zero.route", out object route))
-1
View File
@@ -30,7 +30,6 @@
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
<PackageReference Include="RavenDB.Client" Version="5.1.1" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.2" />
<PackageReference Include="System.Reactive.Core" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
@@ -1,5 +1,4 @@
using Microsoft.AspNetCore.Http;
using System;
using System.Threading.Tasks;
using zero.Core;
@@ -16,7 +15,6 @@ namespace zero.Web.Middlewares
public async Task Invoke(HttpContext httpContext, IZeroContext zeroContext)
{
Console.WriteLine("ZeroContextMiddleware");
await zeroContext.Resolve(httpContext);
await Next(httpContext);
}
+1 -8
View File
@@ -175,19 +175,12 @@ namespace zero.Web
});
Services.AddScoped<IZeroDocumentSession, ZeroDocumentSession>(services =>
Services.AddScoped<IZeroDocumentSession>(services =>
{
var session = services.GetRequiredService<IZeroStore>()!.OpenAsyncSession();
session.Advanced.WaitForIndexesAfterSaveChanges();
return session as ZeroDocumentSession;
});
Services.AddScoped<IZeroCoreDocumentSession, ZeroDocumentSession>(services =>
{
var session = services.GetRequiredService<IZeroStore>()!.OpenCoreSession();
session.Advanced.WaitForIndexesAfterSaveChanges();
return session as ZeroDocumentSession;
});
}