mirror of https://github.com/Squidex/squidex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
8.1 KiB
234 lines
8.1 KiB
// ==========================================================================
|
|
// Squidex Headless CMS
|
|
// ==========================================================================
|
|
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|
// All rights reserved. Licensed under the MIT license.
|
|
// ==========================================================================
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Orleans;
|
|
using Squidex.Domain.Apps.Entities.Apps;
|
|
using Squidex.Domain.Apps.Entities.Apps.Indexes;
|
|
using Squidex.Domain.Apps.Entities.Rules;
|
|
using Squidex.Domain.Apps.Entities.Rules.Indexes;
|
|
using Squidex.Domain.Apps.Entities.Schemas;
|
|
using Squidex.Domain.Apps.Entities.Schemas.Indexes;
|
|
using Squidex.Infrastructure;
|
|
using Squidex.Infrastructure.Caching;
|
|
using Squidex.Infrastructure.Log;
|
|
using Squidex.Infrastructure.Orleans;
|
|
using Squidex.Infrastructure.Security;
|
|
using Squidex.Shared;
|
|
|
|
namespace Squidex.Domain.Apps.Entities
|
|
{
|
|
public sealed class AppProvider : IAppProvider
|
|
{
|
|
private readonly IGrainFactory grainFactory;
|
|
private readonly ILocalCache localCache;
|
|
|
|
public AppProvider(IGrainFactory grainFactory, ILocalCache localCache)
|
|
{
|
|
Guard.NotNull(grainFactory, nameof(grainFactory));
|
|
Guard.NotNull(localCache, nameof(localCache));
|
|
|
|
this.grainFactory = grainFactory;
|
|
|
|
this.localCache = localCache;
|
|
}
|
|
|
|
public Task<(IAppEntity, ISchemaEntity)> GetAppWithSchemaAsync(Guid appId, Guid id)
|
|
{
|
|
return localCache.GetOrCreateAsync($"GetAppWithSchemaAsync({appId}, {id})", async () =>
|
|
{
|
|
using (Profiler.TraceMethod<AppProvider>())
|
|
{
|
|
var app = await grainFactory.GetGrain<IAppGrain>(appId).GetStateAsync();
|
|
|
|
if (!IsExisting(app))
|
|
{
|
|
return (null, null);
|
|
}
|
|
|
|
var schema = await GetSchemaAsync(appId, id, false);
|
|
|
|
if (schema == null)
|
|
{
|
|
return (null, null);
|
|
}
|
|
|
|
return (app.Value, schema);
|
|
}
|
|
});
|
|
}
|
|
|
|
public Task<IAppEntity> GetAppAsync(string appName)
|
|
{
|
|
return localCache.GetOrCreateAsync($"GetAppAsync({appName})", async () =>
|
|
{
|
|
using (Profiler.TraceMethod<AppProvider>())
|
|
{
|
|
var appId = await GetAppIdAsync(appName);
|
|
|
|
if (appId == Guid.Empty)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var app = await grainFactory.GetGrain<IAppGrain>(appId).GetStateAsync();
|
|
|
|
if (!IsExisting(app))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return app.Value;
|
|
}
|
|
});
|
|
}
|
|
|
|
public Task<ISchemaEntity> GetSchemaAsync(Guid appId, string name)
|
|
{
|
|
return localCache.GetOrCreateAsync($"GetSchemaAsync({appId}, {name})", async () =>
|
|
{
|
|
using (Profiler.TraceMethod<AppProvider>("GetSchemaAsyncByName"))
|
|
{
|
|
var schemaId = await GetSchemaIdAsync(appId, name);
|
|
|
|
if (schemaId == Guid.Empty)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return await GetSchemaAsync(appId, schemaId, false);
|
|
}
|
|
});
|
|
}
|
|
|
|
public Task<ISchemaEntity> GetSchemaAsync(Guid appId, Guid id, bool allowDeleted = false)
|
|
{
|
|
return localCache.GetOrCreateAsync($"GetSchemaAsync({appId}, {id}, {allowDeleted})", async () =>
|
|
{
|
|
using (Profiler.TraceMethod<AppProvider>("GetSchemaAsyncById"))
|
|
{
|
|
var schema = await grainFactory.GetGrain<ISchemaGrain>(id).GetStateAsync();
|
|
|
|
if (!IsExisting(schema, allowDeleted) || schema.Value.AppId.Id != appId)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return schema.Value;
|
|
}
|
|
});
|
|
}
|
|
|
|
public Task<List<ISchemaEntity>> GetSchemasAsync(Guid appId)
|
|
{
|
|
return localCache.GetOrCreateAsync($"GetSchemasAsync({appId})", async () =>
|
|
{
|
|
using (Profiler.TraceMethod<AppProvider>())
|
|
{
|
|
var ids = await grainFactory.GetGrain<ISchemasByAppIndex>(appId).GetSchemaIdsAsync();
|
|
|
|
var schemas =
|
|
await Task.WhenAll(
|
|
ids.Select(id => grainFactory.GetGrain<ISchemaGrain>(id).GetStateAsync()));
|
|
|
|
return schemas.Where(s => IsFound(s.Value)).Select(s => s.Value).ToList();
|
|
}
|
|
});
|
|
}
|
|
|
|
public Task<List<IRuleEntity>> GetRulesAsync(Guid appId)
|
|
{
|
|
return localCache.GetOrCreateAsync($"GetRulesAsync({appId})", async () =>
|
|
{
|
|
using (Profiler.TraceMethod<AppProvider>())
|
|
{
|
|
var ids = await grainFactory.GetGrain<IRulesByAppIndex>(appId).GetRuleIdsAsync();
|
|
|
|
var rules =
|
|
await Task.WhenAll(
|
|
ids.Select(id => grainFactory.GetGrain<IRuleGrain>(id).GetStateAsync()));
|
|
|
|
return rules.Where(r => IsFound(r.Value)).Select(r => r.Value).ToList();
|
|
}
|
|
});
|
|
}
|
|
|
|
public Task<List<IAppEntity>> GetUserApps(string userId, PermissionSet permissions)
|
|
{
|
|
Guard.NotNull(userId, nameof(userId));
|
|
Guard.NotNull(permissions, nameof(permissions));
|
|
|
|
return localCache.GetOrCreateAsync($"GetUserApps({userId})", async () =>
|
|
{
|
|
using (Profiler.TraceMethod<AppProvider>())
|
|
{
|
|
var ids =
|
|
await Task.WhenAll(
|
|
GetAppIdsByUserAsync(userId),
|
|
GetAppIdsAsync(permissions.ToAppNames()));
|
|
|
|
var apps =
|
|
await Task.WhenAll(ids
|
|
.SelectMany(x => x)
|
|
.Select(id => grainFactory.GetGrain<IAppGrain>(id).GetStateAsync()));
|
|
|
|
return apps.Where(a => IsFound(a.Value)).Select(a => a.Value).ToList();
|
|
}
|
|
});
|
|
}
|
|
|
|
private async Task<List<Guid>> GetAppIdsByUserAsync(string userId)
|
|
{
|
|
using (Profiler.TraceMethod<AppProvider>())
|
|
{
|
|
return await grainFactory.GetGrain<IAppsByUserIndex>(userId).GetAppIdsAsync();
|
|
}
|
|
}
|
|
|
|
private async Task<List<Guid>> GetAppIdsAsync(IEnumerable<string> names)
|
|
{
|
|
using (Profiler.TraceMethod<AppProvider>())
|
|
{
|
|
return await grainFactory.GetGrain<IAppsByNameIndex>(SingleGrain.Id).GetAppIdsAsync(names.ToArray());
|
|
}
|
|
}
|
|
|
|
private async Task<Guid> GetAppIdAsync(string name)
|
|
{
|
|
using (Profiler.TraceMethod<AppProvider>())
|
|
{
|
|
return await grainFactory.GetGrain<IAppsByNameIndex>(SingleGrain.Id).GetAppIdAsync(name);
|
|
}
|
|
}
|
|
|
|
private async Task<Guid> GetSchemaIdAsync(Guid appId, string name)
|
|
{
|
|
using (Profiler.TraceMethod<AppProvider>())
|
|
{
|
|
return await grainFactory.GetGrain<ISchemasByAppIndex>(appId).GetSchemaIdAsync(name);
|
|
}
|
|
}
|
|
|
|
private static bool IsFound(IEntityWithVersion entity)
|
|
{
|
|
return entity.Version > EtagVersion.Empty;
|
|
}
|
|
|
|
private static bool IsExisting(J<IAppEntity> app)
|
|
{
|
|
return IsFound(app.Value) && !app.Value.IsArchived;
|
|
}
|
|
|
|
private static bool IsExisting(J<ISchemaEntity> schema, bool allowDeleted)
|
|
{
|
|
return IsFound(schema.Value) && (!schema.Value.IsDeleted || allowDeleted);
|
|
}
|
|
}
|
|
}
|
|
|