Browse Source

Closes #145

Closes #144
pull/147/merge
Sebastian Stehle 9 years ago
parent
commit
765d3894c5
  1. 12
      src/Squidex.Domain.Apps.Read.MongoDb/Apps/MongoAppRepository_EventHandling.cs
  2. 9
      src/Squidex.Domain.Apps.Read.MongoDb/Contents/Extensions.cs
  3. 5
      src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentEntity.cs
  4. 14
      src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentRepository.cs
  5. 4
      src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentRepository_EventHandling.cs
  6. 39
      src/Squidex.Domain.Apps.Read.MongoDb/Schemas/MongoSchemaEntity.cs
  7. 12
      src/Squidex.Domain.Apps.Read.MongoDb/Schemas/MongoSchemaRepository.cs
  8. 42
      src/Squidex.Domain.Apps.Read.MongoDb/Schemas/MongoSchemaRepository_EventHandling.cs
  9. 1
      src/Squidex.Domain.Apps.Read/Apps/IAppEntity.cs
  10. 3
      src/Squidex.Domain.Apps.Read/Apps/Repositories/IAppRepository.cs
  11. 3
      src/Squidex.Domain.Apps.Read/Apps/Services/IAppProvider.cs
  12. 45
      src/Squidex.Domain.Apps.Read/Apps/Services/Implementations/CachingAppProvider.cs
  13. 3
      src/Squidex.Domain.Apps.Read/Schemas/Repositories/ISchemaRepository.cs
  14. 3
      src/Squidex.Domain.Apps.Read/Schemas/Services/ISchemaProvider.cs
  15. 45
      src/Squidex.Domain.Apps.Read/Schemas/Services/Implementations/CachingSchemaProvider.cs
  16. 2
      src/Squidex.Infrastructure.RabbitMq/CQRS/Events/RabbitMqEventConsumer.cs
  17. 2
      src/Squidex/Config/Domain/InfrastructureModule.cs
  18. 2
      src/Squidex/Config/Domain/Serializers.cs
  19. 22
      src/Squidex/Config/Domain/StoreMongoDbModule.cs
  20. 20
      src/Squidex/Config/Domain/Usages.cs
  21. 1
      src/Squidex/Config/Identity/LazyClientStore.cs
  22. 28
      tests/Squidex.Domain.Apps.Read.Tests/Apps/CachingAppProviderTests.cs
  23. 26
      tests/Squidex.Domain.Apps.Read.Tests/Schemas/CachingSchemaProviderTests.cs
  24. 2
      tests/Squidex.Infrastructure.Tests/Json/ConverterContractResolverTests.cs

12
src/Squidex.Domain.Apps.Read.MongoDb/Apps/MongoAppRepository_EventHandling.cs

@ -22,8 +22,6 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Apps
{
public partial class MongoAppRepository
{
private readonly List<Action<NamedId<Guid>>> subscribers = new List<Action<NamedId<Guid>>>();
public string Name
{
get { return GetType().Name; }
@ -34,11 +32,6 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Apps
get { return "^app-"; }
}
public void SubscribeOnChanged(Action<NamedId<Guid>> subscriber)
{
subscribers.Add(subscriber);
}
public Task On(Envelope<IEvent> @event)
{
return this.DispatchActionAsync(@event.Payload, @event.Headers);
@ -144,11 +137,6 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Apps
a.ContributorIds = a.Contributors.Keys.ToList();
});
foreach (var subscriber in subscribers)
{
subscriber(@event.AppId);
}
}
}
}

9
src/Squidex.Domain.Apps.Read.MongoDb/Contents/Extensions.cs

@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using MongoDB.Bson;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
@ -22,9 +23,9 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
{
private const int MaxLength = 1024 * 1024;
public static BsonDocument ToBsonDocument(this IdContentData data)
public static BsonDocument ToBsonDocument(this IdContentData data, JsonSerializer jsonSerializer)
{
return (BsonDocument)JToken.FromObject(data).ToBson();
return (BsonDocument)JToken.FromObject(data, jsonSerializer).ToBson();
}
public static List<Guid> ToReferencedIds(this IdContentData data, Schema schema)
@ -32,11 +33,11 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
return data.GetReferencedIds(schema).ToList();
}
public static NamedContentData ToData(this BsonDocument document, Schema schema, List<Guid> deletedIds)
public static NamedContentData ToData(this BsonDocument document, Schema schema, List<Guid> deletedIds, JsonSerializer jsonSerializer)
{
return document
.ToJson()
.ToObject<IdContentData>()
.ToObject<IdContentData>(jsonSerializer)
.ToCleanedReferences(schema, new HashSet<Guid>(deletedIds ?? new List<Guid>()))
.ToNameModel(schema, true);
}

5
src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentEntity.cs

@ -10,6 +10,7 @@ using System;
using System.Collections.Generic;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using Newtonsoft.Json;
using NodaTime;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
@ -82,9 +83,9 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
get { return data; }
}
public void ParseData(Schema schema)
public void ParseData(Schema schema, JsonSerializer serializer)
{
data = DataDocument.ToData(schema, ReferencedIdsDeleted);
data = DataDocument.ToData(schema, ReferencedIdsDeleted, serializer);
}
}
}

14
src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentRepository.cs

@ -13,6 +13,7 @@ using System.Threading.Tasks;
using Microsoft.OData.UriParser;
using MongoDB.Bson;
using MongoDB.Driver;
using Newtonsoft.Json;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Read.Apps;
using Squidex.Domain.Apps.Read.Contents;
@ -30,6 +31,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
private const string Prefix = "Projections_Content_";
private readonly IMongoDatabase database;
private readonly ISchemaProvider schemas;
private readonly JsonSerializer serializer;
protected static FilterDefinitionBuilder<MongoContentEntity> Filter
{
@ -63,13 +65,15 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
}
}
public MongoContentRepository(IMongoDatabase database, ISchemaProvider schemas)
public MongoContentRepository(IMongoDatabase database, ISchemaProvider schemas, JsonSerializer serializer)
{
Guard.NotNull(database, nameof(database));
Guard.NotNull(schemas, nameof(schemas));
Guard.NotNull(serializer, nameof(serializer));
this.schemas = schemas;
this.database = database;
this.schemas = schemas;
this.serializer = serializer;
}
public async Task<IReadOnlyList<IContentEntity>> QueryAsync(IAppEntity app, ISchemaEntity schema, Status[] status, ODataUriParser odataQuery)
@ -99,7 +103,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
foreach (var entity in contentEntities)
{
entity.ParseData(schema.SchemaDef);
entity.ParseData(schema.SchemaDef, serializer);
}
return contentEntities;
@ -147,7 +151,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
foreach (var entity in contentEntities)
{
entity.ParseData(schema.SchemaDef);
entity.ParseData(schema.SchemaDef, serializer);
}
return contentEntities.OfType<IContentEntity>().ToList();
@ -172,7 +176,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
await collection.Find(x => x.Id == id)
.FirstOrDefaultAsync();
contentEntity?.ParseData(schema.SchemaDef);
contentEntity?.ParseData(schema.SchemaDef, serializer);
return contentEntity;
}

4
src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentRepository_EventHandling.cs

@ -79,7 +79,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
var idData = @event.Data?.ToIdModel(schema.SchemaDef, true);
content.DataText = idData?.ToFullText();
content.DataDocument = idData?.ToBsonDocument();
content.DataDocument = idData?.ToBsonDocument(serializer);
content.ReferencedIds = idData?.ToReferencedIds(schema.SchemaDef);
});
});
@ -95,7 +95,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
Filter.Eq(x => x.Id, @event.ContentId),
Update
.Set(x => x.DataText, idData.ToFullText())
.Set(x => x.DataDocument, idData.ToBsonDocument())
.Set(x => x.DataDocument, idData.ToBsonDocument(serializer))
.Set(x => x.ReferencedIds, idData.ToReferencedIds(schema.SchemaDef))
.Set(x => x.LastModified, headers.Timestamp())
.Set(x => x.LastModifiedBy, @event.Actor)

39
src/Squidex.Domain.Apps.Read.MongoDb/Schemas/MongoSchemaEntity.cs

@ -9,6 +9,7 @@
using System;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Read.Schemas;
@ -19,7 +20,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
{
public sealed class MongoSchemaEntity : MongoEntity, ISchemaEntity
{
private Schema schema;
private Lazy<Schema> schema;
[BsonRequired]
[BsonElement]
@ -73,23 +74,31 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
[BsonElement]
public string ScriptChange { get; set; }
[BsonIgnore]
public Schema SchemaDef
Schema ISchemaEntity.SchemaDef
{
get
{
if (schema == null)
{
schema = SchemaDocument.ToJson().ToObject<Schema>();
}
get { return schema.Value; }
}
return schema;
}
set
{
schema = value;
public void SerializeSchema(Schema newSchema, JsonSerializer serializer)
{
SchemaDocument = JObject.FromObject(newSchema, serializer).ToBson();
schema = new Lazy<Schema>(() => newSchema);
IsPublished = newSchema.IsPublished;
}
SchemaDocument = (BsonDocument)JToken.FromObject(schema).ToBson();
public void UpdateSchema(JsonSerializer serializer, Func<Schema, Schema> updater)
{
DeserializeSchema(serializer);
SerializeSchema(updater(schema.Value), serializer);
}
public void DeserializeSchema(JsonSerializer serializer)
{
if (schema == null)
{
schema = new Lazy<Schema>(() => schema != null ? SchemaDocument.ToJson().ToObject<Schema>(serializer) : null);
}
}
}

12
src/Squidex.Domain.Apps.Read.MongoDb/Schemas/MongoSchemaRepository.cs

@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MongoDB.Driver;
using Newtonsoft.Json;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Read.Schemas;
using Squidex.Domain.Apps.Read.Schemas.Repositories;
@ -22,14 +23,17 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
{
public partial class MongoSchemaRepository : MongoRepositoryBase<MongoSchemaEntity>, ISchemaRepository, IEventConsumer
{
private readonly JsonSerializer serializer;
private readonly FieldRegistry registry;
public MongoSchemaRepository(IMongoDatabase database, FieldRegistry registry)
public MongoSchemaRepository(IMongoDatabase database, JsonSerializer serializer, FieldRegistry registry)
: base(database)
{
Guard.NotNull(registry, nameof(registry));
Guard.NotNull(serializer, nameof(serializer));
this.registry = registry;
this.serializer = serializer;
}
protected override string CollectionName()
@ -50,6 +54,8 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
await Collection.Find(s => s.AppId == appId && !s.IsDeleted)
.ToListAsync();
schemaEntities.ForEach(x => x.DeserializeSchema(serializer));
return schemaEntities.OfType<ISchemaEntity>().ToList();
}
@ -59,6 +65,8 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
await Collection.Find(s => s.AppId == appId && !s.IsDeleted && s.Name == name)
.FirstOrDefaultAsync();
schemaEntity?.DeserializeSchema(serializer);
return schemaEntity;
}
@ -68,6 +76,8 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
await Collection.Find(s => s.Id == schemaId)
.FirstOrDefaultAsync();
schemaEntity?.DeserializeSchema(serializer);
return schemaEntity;
}
}

42
src/Squidex.Domain.Apps.Read.MongoDb/Schemas/MongoSchemaRepository_EventHandling.cs

@ -7,7 +7,6 @@
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Events;
@ -15,7 +14,6 @@ using Squidex.Domain.Apps.Events.Schemas;
using Squidex.Domain.Apps.Events.Schemas.Old;
using Squidex.Domain.Apps.Events.Schemas.Utils;
using Squidex.Domain.Apps.Read.MongoDb.Utils;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.Dispatching;
using Squidex.Infrastructure.Reflection;
@ -26,8 +24,6 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
{
public partial class MongoSchemaRepository
{
private readonly List<Action<NamedId<Guid>, NamedId<Guid>>> subscribers = new List<Action<NamedId<Guid>, NamedId<Guid>>>();
public string Name
{
get { return GetType().Name; }
@ -38,11 +34,6 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
get { return "^schema-"; }
}
public void SubscribeOnChanged(Action<NamedId<Guid>, NamedId<Guid>> subscriber)
{
subscribers.Add(subscriber);
}
public Task On(Envelope<IEvent> @event)
{
return this.DispatchActionAsync(@event.Payload, @event.Headers);
@ -52,7 +43,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
{
var schema = SchemaEventDispatcher.Dispatch(@event, registry);
return Collection.CreateAsync(@event, headers, s => { s.SchemaDef = schema; SimpleMapper.Map(@event, s); });
return Collection.CreateAsync(@event, headers, s => { UpdateSchema(s, schema); SimpleMapper.Map(@event, s); });
}
protected Task On(FieldDeleted @event, EnvelopeHeaders headers)
@ -125,30 +116,29 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Schemas
return Collection.UpdateAsync(@event, headers, e => e.IsDeleted = true);
}
protected Task On(WebhookAdded @event, EnvelopeHeaders headers)
private Task UpdateSchema(SquidexEvent @event, EnvelopeHeaders headers, Func<Schema, Schema> updater)
{
return Collection.UpdateAsync(@event, headers, e => { });
return Collection.UpdateAsync(@event, headers, e => UpdateSchema(e, updater));
}
protected Task On(WebhookDeleted @event, EnvelopeHeaders headers)
private void UpdateSchema(MongoSchemaEntity entity, Func<Schema, Schema> updater)
{
return Collection.UpdateAsync(@event, headers, e => { });
entity.UpdateSchema(serializer, updater);
}
private async Task UpdateSchema(SchemaEvent @event, EnvelopeHeaders headers, Func<Schema, Schema> updater = null)
private void UpdateSchema(MongoSchemaEntity entity, Schema schema)
{
await Collection.UpdateAsync(@event, headers, e =>
{
if (updater != null)
{
e.SchemaDef = updater(e.SchemaDef);
}
});
entity.SerializeSchema(schema, serializer);
}
foreach (var subscriber in subscribers)
{
subscriber(@event.AppId, @event.SchemaId);
}
protected Task On(WebhookAdded @event, EnvelopeHeaders headers)
{
return Collection.UpdateAsync(@event, headers, e => { });
}
protected Task On(WebhookDeleted @event, EnvelopeHeaders headers)
{
return Collection.UpdateAsync(@event, headers, e => { });
}
}
}

1
src/Squidex.Domain.Apps.Read/Apps/IAppEntity.cs

@ -8,7 +8,6 @@
using System.Collections.Generic;
using Squidex.Domain.Apps.Core;
using Squidex.Domain.Apps.Core.Apps;
namespace Squidex.Domain.Apps.Read.Apps
{

3
src/Squidex.Domain.Apps.Read/Apps/Repositories/IAppRepository.cs

@ -9,7 +9,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Read.Apps.Repositories
{
@ -20,7 +19,5 @@ namespace Squidex.Domain.Apps.Read.Apps.Repositories
Task<IAppEntity> FindAppAsync(Guid appId);
Task<IAppEntity> FindAppAsync(string name);
void SubscribeOnChanged(Action<NamedId<Guid>> subscriber);
}
}

3
src/Squidex.Domain.Apps.Read/Apps/Services/IAppProvider.cs

@ -8,7 +8,6 @@
using System;
using System.Threading.Tasks;
using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Read.Apps.Services
{
@ -17,7 +16,5 @@ namespace Squidex.Domain.Apps.Read.Apps.Services
Task<IAppEntity> FindAppByIdAsync(Guid id);
Task<IAppEntity> FindAppByNameAsync(string name);
void Invalidate(NamedId<Guid> appId);
}
}

45
src/Squidex.Domain.Apps.Read/Apps/Services/Implementations/CachingAppProvider.cs

@ -9,19 +9,31 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Squidex.Domain.Apps.Events;
using Squidex.Domain.Apps.Read.Apps.Repositories;
using Squidex.Domain.Apps.Read.Utils;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Caching;
using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.Tasks;
namespace Squidex.Domain.Apps.Read.Apps.Services.Implementations
{
public class CachingAppProvider : CachingProviderBase, IAppProvider
public class CachingAppProvider : CachingProviderBase, IAppProvider, IEventConsumer
{
private static readonly TimeSpan CacheDuration = TimeSpan.FromMinutes(30);
private readonly IAppRepository repository;
public string Name
{
get { return GetType().Name; }
}
public string EventsFilter
{
get { return string.Empty; }
}
public CachingAppProvider(IMemoryCache cache, IAppRepository repository)
: base(cache)
{
@ -70,16 +82,26 @@ namespace Squidex.Domain.Apps.Read.Apps.Services.Implementations
return result;
}
public void Invalidate(NamedId<Guid> appId)
public Task On(Envelope<IEvent> @event)
{
var cacheKeyById = BuildIdCacheKey(appId.Id);
var cacheKeyByName = BuildNameCacheKey(appId.Name);
void Remove(NamedId<Guid> id)
{
var cacheKeyById = BuildIdCacheKey(id.Id);
var cacheKeyByName = BuildNameCacheKey(id.Name);
Cache.Remove(cacheKeyById);
Cache.Remove(cacheKeyByName);
Cache.Remove(cacheKeyById);
Cache.Remove(cacheKeyByName);
Cache.Invalidate(cacheKeyById);
Cache.Invalidate(cacheKeyByName);
Cache.Invalidate(cacheKeyById);
Cache.Invalidate(cacheKeyByName);
}
if (@event.Payload is AppEvent appEvent)
{
Remove(appEvent.AppId);
}
return TaskHelper.Done;
}
private static string BuildNameCacheKey(string name)
@ -91,5 +113,10 @@ namespace Squidex.Domain.Apps.Read.Apps.Services.Implementations
{
return $"App_Names_{schemaId}";
}
public Task ClearAsync()
{
return TaskHelper.Done;
}
}
}

3
src/Squidex.Domain.Apps.Read/Schemas/Repositories/ISchemaRepository.cs

@ -9,7 +9,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Read.Schemas.Repositories
{
@ -20,7 +19,5 @@ namespace Squidex.Domain.Apps.Read.Schemas.Repositories
Task<ISchemaEntity> FindSchemaAsync(Guid appId, string name);
Task<ISchemaEntity> FindSchemaAsync(Guid schemaId);
void SubscribeOnChanged(Action<NamedId<Guid>, NamedId<Guid>> subscriber);
}
}

3
src/Squidex.Domain.Apps.Read/Schemas/Services/ISchemaProvider.cs

@ -8,7 +8,6 @@
using System;
using System.Threading.Tasks;
using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Read.Schemas.Services
{
@ -17,7 +16,5 @@ namespace Squidex.Domain.Apps.Read.Schemas.Services
Task<ISchemaEntity> FindSchemaByIdAsync(Guid id, bool provideDeleted = false);
Task<ISchemaEntity> FindSchemaByNameAsync(Guid appId, string name);
void Invalidate(NamedId<Guid> appId, NamedId<Guid> schemaId);
}
}

45
src/Squidex.Domain.Apps.Read/Schemas/Services/Implementations/CachingSchemaProvider.cs

@ -9,19 +9,31 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Squidex.Domain.Apps.Events;
using Squidex.Domain.Apps.Read.Schemas.Repositories;
using Squidex.Domain.Apps.Read.Utils;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Caching;
using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.Tasks;
namespace Squidex.Domain.Apps.Read.Schemas.Services.Implementations
{
public class CachingSchemaProvider : CachingProviderBase, ISchemaProvider
public class CachingSchemaProvider : CachingProviderBase, ISchemaProvider, IEventConsumer
{
private static readonly TimeSpan CacheDuration = TimeSpan.FromMinutes(10);
private readonly ISchemaRepository repository;
public string Name
{
get { return GetType().Name; }
}
public string EventsFilter
{
get { return string.Empty; }
}
public CachingSchemaProvider(IMemoryCache cache, ISchemaRepository repository)
: base(cache)
{
@ -80,16 +92,26 @@ namespace Squidex.Domain.Apps.Read.Schemas.Services.Implementations
return result;
}
public void Invalidate(NamedId<Guid> appId, NamedId<Guid> schemaId)
public Task On(Envelope<IEvent> @event)
{
var cacheKeyById = BuildIdCacheKey(schemaId.Id);
var cacheKeyByName = BuildNameCacheKey(appId.Id, schemaId.Name);
void Remove(NamedId<Guid> appId, NamedId<Guid> schemaId)
{
var cacheKeyById = BuildIdCacheKey(schemaId.Id);
var cacheKeyByName = BuildNameCacheKey(appId.Id, schemaId.Name);
Cache.Remove(cacheKeyById);
Cache.Remove(cacheKeyByName);
Cache.Remove(cacheKeyById);
Cache.Remove(cacheKeyByName);
Cache.Invalidate(cacheKeyById);
Cache.Invalidate(cacheKeyByName);
Cache.Invalidate(cacheKeyById);
Cache.Invalidate(cacheKeyByName);
}
if (@event.Payload is SchemaEvent schemaEvent)
{
Remove(schemaEvent.AppId, schemaEvent.SchemaId);
}
return TaskHelper.Done;
}
private static string BuildNameCacheKey(Guid appId, string name)
@ -101,5 +123,10 @@ namespace Squidex.Domain.Apps.Read.Schemas.Services.Implementations
{
return $"Schema_Names_{schemaId}";
}
public Task ClearAsync()
{
return TaskHelper.Done;
}
}
}

2
src/Squidex.Infrastructure.RabbitMq/CQRS/Events/RabbitMqEventConsumer.cs

@ -44,7 +44,7 @@ namespace Squidex.Infrastructure.CQRS.Events
connectionFactory = new ConnectionFactory { Uri = new Uri(uri, UriKind.Absolute) };
connection = new Lazy<IConnection>(connectionFactory.CreateConnection);
channel = new Lazy<IModel>(() => connection.Value.CreateModel());
channel = new Lazy<IModel>(connection.Value.CreateModel);
this.exchange = exchange;
this.eventsFilter = eventsFilter;

2
src/Squidex/Config/Domain/InfrastructureModule.cs

@ -15,8 +15,6 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using NodaTime;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.Schemas.Json;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Actors;
using Squidex.Infrastructure.Assets;

2
src/Squidex/Config/Domain/Serializers.cs

@ -60,8 +60,6 @@ namespace Squidex.Config.Domain
TypeNameRegistry.Map(typeof(NoopEvent).GetTypeInfo().Assembly);
ConfigureJson(SerializerSettings, TypeNameHandling.Auto);
JsonConvert.DefaultSettings = () => SerializerSettings;
}
public static IServiceCollection AddMyEventFormatter(this IServiceCollection services)

22
src/Squidex/Config/Domain/StoreMongoDbModule.cs

@ -13,7 +13,9 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using MongoDB.Driver;
using Squidex.Domain.Apps.Read.Apps.Repositories;
using Squidex.Domain.Apps.Read.Apps.Services.Implementations;
using Squidex.Domain.Apps.Read.Assets.Repositories;
using Squidex.Domain.Apps.Read.Contents.GraphQL;
using Squidex.Domain.Apps.Read.Contents.Repositories;
using Squidex.Domain.Apps.Read.History.Repositories;
using Squidex.Domain.Apps.Read.MongoDb.Apps;
@ -23,6 +25,7 @@ using Squidex.Domain.Apps.Read.MongoDb.History;
using Squidex.Domain.Apps.Read.MongoDb.Schemas;
using Squidex.Domain.Apps.Read.MongoDb.Webhooks;
using Squidex.Domain.Apps.Read.Schemas.Repositories;
using Squidex.Domain.Apps.Read.Schemas.Services.Implementations;
using Squidex.Domain.Apps.Read.Webhooks.Repositories;
using Squidex.Domain.Users;
using Squidex.Domain.Users.MongoDb;
@ -144,7 +147,6 @@ namespace Squidex.Config.Domain
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration))
.As<IAppRepository>()
.As<IExternalSystem>()
.As<IEventConsumer>()
.AsSelf()
.SingleInstance();
@ -152,7 +154,6 @@ namespace Squidex.Config.Domain
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration))
.As<ISchemaRepository>()
.As<IExternalSystem>()
.As<IEventConsumer>()
.AsSelf()
.SingleInstance();
@ -185,6 +186,23 @@ namespace Squidex.Config.Domain
.As<IEventConsumer>()
.AsSelf()
.SingleInstance();
builder.Register(c =>
new CompoundEventConsumer(
c.Resolve<MongoSchemaRepository>(),
c.Resolve<CachingGraphQLService>(),
c.Resolve<CachingSchemaProvider>()))
.As<IEventConsumer>()
.AsSelf()
.SingleInstance();
builder.Register(c =>
new CompoundEventConsumer(
c.Resolve<MongoAppRepository>(),
c.Resolve<CachingAppProvider>()))
.As<IEventConsumer>()
.AsSelf()
.SingleInstance();
}
}
}

20
src/Squidex/Config/Domain/Usages.cs

@ -9,10 +9,6 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Squidex.Domain.Apps.Read.Apps.Repositories;
using Squidex.Domain.Apps.Read.Apps.Services;
using Squidex.Domain.Apps.Read.Schemas.Repositories;
using Squidex.Domain.Apps.Read.Schemas.Services;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Actors;
using Squidex.Infrastructure.CQRS.Events;
@ -42,22 +38,6 @@ namespace Squidex.Config.Domain
}
}
var appRepository = services.GetService<IAppRepository>();
var appProvider = services.GetService<IAppProvider>();
if (appProvider != null)
{
appRepository?.SubscribeOnChanged(appProvider.Invalidate);
}
var schemaRepository = services.GetService<ISchemaRepository>();
var schemaProvider = services.GetService<ISchemaProvider>();
if (schemaProvider != null)
{
schemaRepository?.SubscribeOnChanged(schemaProvider.Invalidate);
}
return app;
}

1
src/Squidex/Config/Identity/LazyClientStore.cs

@ -8,7 +8,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using IdentityServer4;
using IdentityServer4.Models;

28
tests/Squidex.Domain.Apps.Read.Tests/Apps/CachingAppProviderTests.cs

@ -11,9 +11,11 @@ using System.Threading.Tasks;
using FakeItEasy;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using Squidex.Domain.Apps.Events.Apps;
using Squidex.Domain.Apps.Read.Apps.Repositories;
using Squidex.Domain.Apps.Read.Apps.Services.Implementations;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS.Events;
using Xunit;
namespace Squidex.Domain.Apps.Read.Apps
@ -38,6 +40,24 @@ namespace Squidex.Domain.Apps.Read.Apps
sut = new CachingAppProvider(cache, repository);
}
[Fact]
public void Should_return_empty_for_events_filter()
{
Assert.Equal(string.Empty, sut.EventsFilter);
}
[Fact]
public void Should_return_empty_for_name()
{
Assert.Equal(typeof(CachingAppProvider).Name, sut.Name);
}
[Fact]
public void Should_do_nothing_when_clearing()
{
Assert.NotNull(sut.ClearAsync());
}
[Fact]
public async Task Should_also_retrieve_app_by_name_if_retrieved_by_id_before()
{
@ -65,7 +85,7 @@ namespace Squidex.Domain.Apps.Read.Apps
}
[Fact]
public async Task Should_clear_cache_for_id_after_invalidating()
public async Task Should_clear_cache_for_id_after_update_event()
{
A.CallTo(() => repository.FindAppAsync(appId.Id))
.Returns(appV2);
@ -74,7 +94,7 @@ namespace Squidex.Domain.Apps.Read.Apps
await ProvideAppByIdAsync(appV1);
sut.Invalidate(appId);
sut.On(Envelope.Create(new AppLanguageAdded { AppId = appId }).To<IEvent>()).Wait();
await ProvideAppByIdAsync(appV2);
@ -82,7 +102,7 @@ namespace Squidex.Domain.Apps.Read.Apps
}
[Fact]
public async Task Should_clear_cache_for_name_after_invalidating()
public async Task Should_clear_cache_for_name_after_update_event()
{
A.CallTo(() => repository.FindAppAsync(appId.Name))
.Returns(appV2);
@ -91,7 +111,7 @@ namespace Squidex.Domain.Apps.Read.Apps
await ProvideAppByNameAsync(appV1);
sut.Invalidate(appId);
sut.On(Envelope.Create(new AppLanguageAdded { AppId = appId }).To<IEvent>()).Wait();
await ProvideAppByNameAsync(appV2);

26
tests/Squidex.Domain.Apps.Read.Tests/Schemas/CachingSchemaProviderTests.cs

@ -43,6 +43,24 @@ namespace Squidex.Domain.Apps.Read.Schemas
sut = new CachingSchemaProvider(cache, repository);
}
[Fact]
public void Should_return_empty_for_events_filter()
{
Assert.Equal(string.Empty, sut.EventsFilter);
}
[Fact]
public void Should_return_empty_for_name()
{
Assert.Equal(typeof(CachingSchemaProvider).Name, sut.Name);
}
[Fact]
public void Should_do_nothing_when_clearing()
{
Assert.NotNull(sut.ClearAsync());
}
[Fact]
public async Task Should_also_retrieve_schema_by_name_if_retrieved_by_id_before()
{
@ -70,7 +88,7 @@ namespace Squidex.Domain.Apps.Read.Schemas
}
[Fact]
public async Task Should_clear_cache_for_id_after_invalidating()
public async Task Should_clear_cache_for_id_after_update_event()
{
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id))
.Returns(schemaV2);
@ -79,7 +97,7 @@ namespace Squidex.Domain.Apps.Read.Schemas
await ProvideSchemaById(schemaV1);
sut.Invalidate(appId, schemaId);
sut.On(Envelope.Create(new FieldAdded { AppId = appId, SchemaId = schemaId })).Wait();
await ProvideSchemaById(schemaV2);
@ -87,7 +105,7 @@ namespace Squidex.Domain.Apps.Read.Schemas
}
[Fact]
public async Task Should_clear_cache_for_name_after_invalidating()
public async Task Should_clear_cache_for_name_after_update_event()
{
A.CallTo(() => repository.FindSchemaAsync(appId.Id, schemaId.Name))
.Returns(schemaV2);
@ -96,7 +114,7 @@ namespace Squidex.Domain.Apps.Read.Schemas
await ProvideSchemaByName(schemaV1);
sut.Invalidate(appId, schemaId);
sut.On(Envelope.Create(new SchemaUpdated { AppId = appId, SchemaId = schemaId })).Wait();
await ProvideSchemaByName(schemaV2);

2
tests/Squidex.Infrastructure.Tests/Json/ConverterContractResolverTests.cs

@ -31,7 +31,7 @@ namespace Squidex.Infrastructure.Json
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
throw new NotSupportedException();
}
public override bool CanConvert(Type objectType)

Loading…
Cancel
Save