Browse Source

Migration completed

pull/218/head
Sebastian Stehle 8 years ago
parent
commit
c095b3636e
  1. 3
      src/Squidex.Domain.Apps.Entities/Apps/AppDomainObject.cs
  2. 3
      src/Squidex.Domain.Apps.Entities/Assets/AssetDomainObject.cs
  3. 3
      src/Squidex.Domain.Apps.Entities/Contents/ContentDomainObject.cs
  4. 3
      src/Squidex.Domain.Apps.Entities/Rules/RuleDomainObject.cs
  5. 3
      src/Squidex.Domain.Apps.Entities/Schemas/SchemaDomainObject.cs
  6. 26
      src/Squidex.Domain.Apps.Entities/SquidexDomainObjectBase.cs
  7. 28
      src/Squidex.Domain.Apps.Events/SquidexHeaderExtensions.cs
  8. 14
      src/Squidex.Domain.Apps.Events/SquidexHeaders.cs
  9. 4
      src/Squidex.Infrastructure.GetEventStore/EventSourcing/ProjectionClient.cs
  10. 13
      src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEvent.cs
  11. 2
      src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Reader.cs
  12. 2
      src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Writer.cs
  13. 1
      src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonConvention.cs
  14. 4
      src/Squidex.Infrastructure/Commands/DomainObjectBase.cs
  15. 13
      src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs
  16. 13
      src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs
  17. 2
      src/Squidex.Infrastructure/Migrations/Migrator.cs
  18. 22
      src/Squidex.Infrastructure/NamedId.cs
  19. 6
      tools/Migrate_01/MigrationPath.cs
  20. 17
      tools/Migrate_01/Migrations/ConvertEventStore.cs

3
src/Squidex.Domain.Apps.Entities/Apps/AppDomainObject.cs

@ -13,13 +13,12 @@ using Squidex.Domain.Apps.Entities.Apps.State;
using Squidex.Domain.Apps.Events; using Squidex.Domain.Apps.Events;
using Squidex.Domain.Apps.Events.Apps; using Squidex.Domain.Apps.Events.Apps;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Entities.Apps namespace Squidex.Domain.Apps.Entities.Apps
{ {
public sealed class AppDomainObject : DomainObjectBase<AppState> public sealed class AppDomainObject : SquidexDomainObjectBase<AppState>
{ {
private readonly InitialPatterns initialPatterns; private readonly InitialPatterns initialPatterns;

3
src/Squidex.Domain.Apps.Entities/Assets/AssetDomainObject.cs

@ -9,13 +9,12 @@ using Squidex.Domain.Apps.Entities.Assets.Commands;
using Squidex.Domain.Apps.Entities.Assets.State; using Squidex.Domain.Apps.Entities.Assets.State;
using Squidex.Domain.Apps.Events.Assets; using Squidex.Domain.Apps.Events.Assets;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Entities.Assets namespace Squidex.Domain.Apps.Entities.Assets
{ {
public sealed class AssetDomainObject : DomainObjectBase<AssetState> public sealed class AssetDomainObject : SquidexDomainObjectBase<AssetState>
{ {
public AssetDomainObject Create(CreateAsset command) public AssetDomainObject Create(CreateAsset command)
{ {

3
src/Squidex.Domain.Apps.Entities/Contents/ContentDomainObject.cs

@ -10,13 +10,12 @@ using Squidex.Domain.Apps.Entities.Contents.Commands;
using Squidex.Domain.Apps.Entities.Contents.State; using Squidex.Domain.Apps.Entities.Contents.State;
using Squidex.Domain.Apps.Events.Contents; using Squidex.Domain.Apps.Events.Contents;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Entities.Contents namespace Squidex.Domain.Apps.Entities.Contents
{ {
public sealed class ContentDomainObject : DomainObjectBase<ContentState> public sealed class ContentDomainObject : SquidexDomainObjectBase<ContentState>
{ {
public ContentDomainObject Create(CreateContent command) public ContentDomainObject Create(CreateContent command)
{ {

3
src/Squidex.Domain.Apps.Entities/Rules/RuleDomainObject.cs

@ -9,13 +9,12 @@ using Squidex.Domain.Apps.Entities.Rules.Commands;
using Squidex.Domain.Apps.Entities.Rules.State; using Squidex.Domain.Apps.Entities.Rules.State;
using Squidex.Domain.Apps.Events.Rules; using Squidex.Domain.Apps.Events.Rules;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Entities.Rules namespace Squidex.Domain.Apps.Entities.Rules
{ {
public sealed class RuleDomainObject : DomainObjectBase<RuleState> public sealed class RuleDomainObject : SquidexDomainObjectBase<RuleState>
{ {
public void Create(CreateRule command) public void Create(CreateRule command)
{ {

3
src/Squidex.Domain.Apps.Entities/Schemas/SchemaDomainObject.cs

@ -12,13 +12,12 @@ using Squidex.Domain.Apps.Entities.Schemas.Commands;
using Squidex.Domain.Apps.Entities.Schemas.State; using Squidex.Domain.Apps.Entities.Schemas.State;
using Squidex.Domain.Apps.Events.Schemas; using Squidex.Domain.Apps.Events.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Entities.Schemas namespace Squidex.Domain.Apps.Entities.Schemas
{ {
public sealed class SchemaDomainObject : DomainObjectBase<SchemaState> public sealed class SchemaDomainObject : SquidexDomainObjectBase<SchemaState>
{ {
private readonly FieldRegistry registry; private readonly FieldRegistry registry;

26
src/Squidex.Domain.Apps.Entities/SquidexDomainObjectBase.cs

@ -0,0 +1,26 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Domain.Apps.Events;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.EventSourcing;
namespace Squidex.Domain.Apps.Entities
{
public abstract class SquidexDomainObjectBase<T> : DomainObjectBase<T> where T : IDomainState, new()
{
public override void RaiseEvent(Envelope<IEvent> @event)
{
if (@event.Payload is AppEvent appEvent)
{
@event.SetAppId(appEvent.AppId.Id);
}
base.RaiseEvent(@event);
}
}
}

28
src/Squidex.Domain.Apps.Events/SquidexHeaderExtensions.cs

@ -0,0 +1,28 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Globalization;
using Squidex.Infrastructure.EventSourcing;
namespace Squidex.Domain.Apps.Events
{
public static class SquidexHeaderExtensions
{
public static Guid AppId(this EnvelopeHeaders headers)
{
return headers[SquidexHeaders.AppId].ToGuid(CultureInfo.InvariantCulture);
}
public static Envelope<T> SetAppId<T>(this Envelope<T> envelope, Guid value) where T : class
{
envelope.Headers.Set(SquidexHeaders.AppId, value);
return envelope;
}
}
}

14
src/Squidex.Domain.Apps.Events/SquidexHeaders.cs

@ -0,0 +1,14 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
namespace Squidex.Domain.Apps.Events
{
public static class SquidexHeaders
{
public static readonly string AppId = "AppId";
}
}

4
src/Squidex.Infrastructure.GetEventStore/EventSourcing/ProjectionClient.cs

@ -51,8 +51,8 @@ namespace Squidex.Infrastructure.EventSourcing
$@"fromAll() $@"fromAll()
.when({{ .when({{
$any: function (s, e) {{ $any: function (s, e) {{
if (e.streamId.indexOf('{prefix}') === 0 && e.data.{property}) {{ if (e.streamId.indexOf('{prefix}') === 0 && e.metadata.{property}) {{
linkTo('{name}-' + e.data.{property}, e); linkTo('{name}-' + e.metadata.{property}, e);
}} }}
}} }}
}});"; }});";

13
src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEvent.cs

@ -7,7 +7,6 @@
using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.Serialization.Attributes;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Infrastructure.EventSourcing namespace Squidex.Infrastructure.EventSourcing
{ {
@ -15,7 +14,7 @@ namespace Squidex.Infrastructure.EventSourcing
{ {
[BsonElement] [BsonElement]
[BsonRequired] [BsonRequired]
public JToken Payload { get; set; } public string Payload { get; set; }
[BsonElement] [BsonElement]
[BsonRequired] [BsonRequired]
@ -25,18 +24,14 @@ namespace Squidex.Infrastructure.EventSourcing
[BsonRequired] [BsonRequired]
public string Type { get; set; } public string Type { get; set; }
public MongoEvent() public static MongoEvent FromEventData(EventData data)
{ {
} return new MongoEvent { Type = data.Type, Metadata = data.Metadata, Payload = data.ToString() };
public MongoEvent(EventData data)
{
SimpleMapper.Map(data, this);
} }
public EventData ToEventData() public EventData ToEventData()
{ {
return SimpleMapper.Map(this, new EventData()); return new EventData { Type = Type, Metadata = Metadata, Payload = JObject.Parse(Payload) };
} }
} }
} }

2
src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Reader.cs

@ -167,7 +167,7 @@ namespace Squidex.Infrastructure.EventSourcing
private static string CreateIndexPath(string property) private static string CreateIndexPath(string property)
{ {
return $"Events.Payload.{property}"; return $"Events.Metadata.{property}";
} }
} }
} }

2
src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Writer.cs

@ -108,7 +108,7 @@ namespace Squidex.Infrastructure.EventSourcing
foreach (var e in events) foreach (var e in events)
{ {
var mongoEvent = new MongoEvent(e); var mongoEvent = MongoEvent.FromEventData(e);
commitEvents[i++] = mongoEvent; commitEvents[i++] = mongoEvent;
} }

1
src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonConvention.cs

@ -12,6 +12,7 @@ using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Conventions; using MongoDB.Bson.Serialization.Conventions;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Squidex.Infrastructure.MongoDb;
namespace Squidex.Infrastructure.MongoDb namespace Squidex.Infrastructure.MongoDb
{ {

4
src/Squidex.Infrastructure/Commands/DomainObjectBase.cs

@ -45,13 +45,13 @@ namespace Squidex.Infrastructure.Commands
RaiseEvent(Envelope.Create(@event)); RaiseEvent(Envelope.Create(@event));
} }
public void RaiseEvent<TEvent>(Envelope<TEvent> @event) where TEvent : class, IEvent public virtual void RaiseEvent(Envelope<IEvent> @event)
{ {
Guard.NotNull(@event, nameof(@event)); Guard.NotNull(@event, nameof(@event));
@event.SetAggregateId(id); @event.SetAggregateId(id);
ApplyEvent(@event.To<IEvent>()); ApplyEvent(@event);
snapshot.Version++; snapshot.Version++;

13
src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs

@ -25,19 +25,14 @@ namespace Squidex.Infrastructure.Json
throw new JsonException($"Expected String, but got {reader.TokenType}."); throw new JsonException($"Expected String, but got {reader.TokenType}.");
} }
var parts = reader.Value.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); try
if (parts.Length < 2)
{ {
throw new JsonException("Named id must have more than 2 parts divided by commata."); return NamedId<Guid>.Parse(reader.Value.ToString(), Guid.TryParse);
} }
catch (ArgumentException ex)
if (!Guid.TryParse(parts[0], out var id))
{ {
throw new JsonException("Named id must be a valid guid."); throw new JsonException(ex.Message);
} }
return new NamedId<Guid>(id, string.Join(",", parts.Skip(1)));
} }
} }
} }

13
src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs

@ -25,19 +25,14 @@ namespace Squidex.Infrastructure.Json
throw new JsonException($"Expected String, but got {reader.TokenType}."); throw new JsonException($"Expected String, but got {reader.TokenType}.");
} }
var parts = reader.Value.ToString().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); try
if (parts.Length < 2)
{ {
throw new JsonException("Named id must have more than 2 parts divided by commata."); return NamedId<long>.Parse(reader.Value.ToString(), long.TryParse);
} }
catch (ArgumentException ex)
if (!long.TryParse(parts[0], out var id))
{ {
throw new JsonException("Named id must be a valid long."); throw new JsonException(ex.Message);
} }
return new NamedId<long>(id, string.Join(",", parts.Skip(1)));
} }
} }
} }

2
src/Squidex.Infrastructure/Migrations/Migrator.cs

@ -17,7 +17,7 @@ namespace Squidex.Infrastructure.Migrations
private readonly IMigrationStatus migrationStatus; private readonly IMigrationStatus migrationStatus;
private readonly IMigrationPath migrationPath; private readonly IMigrationPath migrationPath;
public int LockWaitMs { get; set; } = 5000; public int LockWaitMs { get; set; } = 500;
public Migrator(IMigrationStatus migrationStatus, IMigrationPath migrationPath, ISemanticLog log) public Migrator(IMigrationStatus migrationStatus, IMigrationPath migrationPath, ISemanticLog log)
{ {

22
src/Squidex.Infrastructure/NamedId.cs

@ -6,9 +6,12 @@
// ========================================================================== // ==========================================================================
using System; using System;
using System.Linq;
namespace Squidex.Infrastructure namespace Squidex.Infrastructure
{ {
public delegate bool Parser<T>(string input, out T result);
public sealed class NamedId<T> : IEquatable<NamedId<T>> public sealed class NamedId<T> : IEquatable<NamedId<T>>
{ {
public T Id { get; } public T Id { get; }
@ -44,5 +47,24 @@ namespace Squidex.Infrastructure
{ {
return (Id.GetHashCode() * 397) ^ Name.GetHashCode(); return (Id.GetHashCode() * 397) ^ Name.GetHashCode();
} }
public static NamedId<T> Parse(string value, Parser<T> parser)
{
Guard.NotNull(value, nameof(value));
var parts = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 2)
{
throw new ArgumentException("Named id must have more than 2 parts divided by commata.");
}
if (!parser(parts[0], out var id))
{
throw new ArgumentException("Named id must be a valid guid.");
}
return new NamedId<T>(id, string.Join(",", parts.Skip(1)));
}
} }
} }

6
tools/Migrate_01/MigrationPath.cs

@ -13,16 +13,16 @@ using Squidex.Infrastructure.Migrations;
namespace Migrate_01 namespace Migrate_01
{ {
public class MigrationMatrix public sealed class MigrationPath : IMigrationPath
{ {
private readonly IServiceProvider serviceProvider; private readonly IServiceProvider serviceProvider;
public MigrationMatrix(IServiceProvider serviceProvider) public MigrationPath(IServiceProvider serviceProvider)
{ {
this.serviceProvider = serviceProvider; this.serviceProvider = serviceProvider;
} }
public (int Version, IEnumerable<IMigration> Migrations) MigrationPath(int version) public (int Version, IEnumerable<IMigration> Migrations) GetNext(int version)
{ {
switch (version) switch (version)
{ {

17
tools/Migrate_01/Migrations/ConvertEventStore.cs

@ -5,11 +5,16 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using MongoDB.Bson; using MongoDB.Bson;
using MongoDB.Driver; using MongoDB.Driver;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Events;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Migrations; using Squidex.Infrastructure.Migrations;
using Squidex.Infrastructure.MongoDb;
namespace Migrate_01.Migrations namespace Migrate_01.Migrations
{ {
@ -34,10 +39,16 @@ namespace Migrate_01.Migrations
{ {
foreach (BsonDocument @event in commit["Events"].AsBsonArray) foreach (BsonDocument @event in commit["Events"].AsBsonArray)
{ {
@event.Remove("EventId"); var meta = JObject.Parse(@event["Metadata"].AsString);
var data = JObject.Parse(@event["Payload"].AsString);
if (data.TryGetValue("appId", out var appId))
{
meta[SquidexHeaders.AppId] = NamedId<Guid>.Parse(appId.ToString(), Guid.TryParse).Id;
}
@event["Payload"] = BsonDocument.Parse(@event["Payload"].AsString); @event.Remove("EventId");
@event["Metadata"] = BsonDocument.Parse(@event["Metadata"].AsString); @event["Metadata"] = meta.ToBson();
} }
await collection.ReplaceOneAsync(filter.Eq("_id", commit["_id"].AsString), commit); await collection.ReplaceOneAsync(filter.Eq("_id", commit["_id"].AsString), commit);

Loading…
Cancel
Save