Add ContextType to WorkflowInstance (#539)

* Add ContextType to WorkflowInstance

* Removed ContextType from WorkflowDefinition

* Added ContextType to WorkflowInstanceDocument and WorkflowInstanceIndex
This commit is contained in:
Rafael Carnucci 2020-12-25 21:15:58 +01:00 committed by GitHub
parent a1c1ee9ce0
commit f6685189f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 130 additions and 10 deletions

View file

@ -0,0 +1,15 @@
using System;
namespace Elsa.Attributes
{
[AttributeUsage(AttributeTargets.Class)]
public class ContextTypeNameAttribute : Attribute
{
public string Name { get; }
public ContextTypeNameAttribute(string name)
{
Name = name;
}
}
}

View file

@ -0,0 +1,16 @@
using Elsa.Attributes;
using System;
using System.Reflection;
namespace Elsa.Extensions
{
public static class TypeExtensions
{
public static string GetContextTypeName(this Type type, bool inherit = false)
{
var attribute = type.GetCustomAttribute<ContextTypeNameAttribute>(inherit);
return attribute?.Name ?? type.FullName!;
}
}
}

View file

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using System.Collections.Generic;
namespace Elsa.Models
{

View file

@ -1,5 +1,9 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.Json.Serialization;
using Elsa.Comparers;
using Elsa.Converters;
using NodaTime;
namespace Elsa.Models
@ -22,6 +26,7 @@ namespace Elsa.Models
public int Version { get; set; }
public WorkflowStatus WorkflowStatus { get; set; }
public string? CorrelationId { get; set; }
public string? ContextType { get; set; }
public string? ContextId { get; set; }
public string? Name { get; set; }
public Instant CreatedAt { get; set; }

View file

@ -1,13 +1,9 @@
using Elsa.Models;
using Elsa.Models;
namespace Elsa.Persistence.Specifications
{
public static class SpecificationExtensions
{
public static ISpecification<T> WithTenant<T>(this ISpecification<T> specification, string? tenantId) where T : ITenantScope => specification.And(new TenantSpecification<T>(tenantId));
public static ISpecification<WorkflowInstance> WithWorkflowDefinition(this ISpecification<WorkflowInstance> specification, string workflowDefinitionId) => specification.And(new WorkflowInstanceDefinitionIdSpecification(workflowDefinitionId));
public static ISpecification<WorkflowInstance> WithWorkflowName(this ISpecification<WorkflowInstance> specification, string name) => specification.And(new WorkflowInstanceNameMatchSpecification(name));
public static ISpecification<WorkflowInstance> WithStatus(this ISpecification<WorkflowInstance> specification, WorkflowStatus status) => specification.And(new WorkflowStatusSpecification(status));
public static ISpecification<WorkflowDefinition> WithVersionOptions(this ISpecification<WorkflowDefinition> specification, VersionOptions versionOptions) => specification.And(new VersionOptionsSpecification(versionOptions));
}
}

View file

@ -0,0 +1,9 @@
using Elsa.Models;
namespace Elsa.Persistence.Specifications
{
public static class WorkflowDefinitionSpecificationExtensions
{
public static ISpecification<WorkflowDefinition> WithVersionOptions(this ISpecification<WorkflowDefinition> specification, VersionOptions versionOptions) => specification.And(new VersionOptionsSpecification(versionOptions));
}
}

View file

@ -0,0 +1,19 @@
using Elsa.Models;
using System;
namespace Elsa.Persistence.Specifications
{
public static class WorkflowInstancSpecificationExtensions
{
public static ISpecification<WorkflowInstance> WithWorkflowDefinition(this ISpecification<WorkflowInstance> specification, string workflowDefinitionId) => specification.And(new WorkflowInstanceDefinitionIdSpecification(workflowDefinitionId));
public static ISpecification<WorkflowInstance> WithWorkflowName(this ISpecification<WorkflowInstance> specification, string name) => specification.And(new WorkflowInstanceNameMatchSpecification(name));
public static ISpecification<WorkflowInstance> WithContextId(this ISpecification<WorkflowInstance> specification, string contextType, string contextId) => specification.And(new WorkflowInstanceContextIdMatchSpecification(contextType, contextId));
public static ISpecification<WorkflowInstance> WithContextId(this ISpecification<WorkflowInstance> specification, Type contextType, string contextId) => specification.And(new WorkflowInstanceContextIdMatchSpecification(contextType, contextId));
public static ISpecification<WorkflowInstance> WithContextId<TContextType>(this ISpecification<WorkflowInstance> specification, string contextId) => specification.And(new WorkflowInstanceContextIdMatchSpecification(typeof(TContextType), contextId));
public static ISpecification<WorkflowInstance> WithContext(this ISpecification<WorkflowInstance> specification, string contextType) => specification.And(new WorkflowInstanceContextMatchSpecification(contextType));
public static ISpecification<WorkflowInstance> WithContext(this ISpecification<WorkflowInstance> specification, Type contextType) => specification.And(new WorkflowInstanceContextMatchSpecification(contextType));
public static ISpecification<WorkflowInstance> WithContextd<TContextType>(this ISpecification<WorkflowInstance> specification) => specification.And(new WorkflowInstanceContextMatchSpecification(typeof(TContextType)));
public static ISpecification<WorkflowInstance> WithStatus(this ISpecification<WorkflowInstance> specification, WorkflowStatus status) => specification.And(new WorkflowStatusSpecification(status));
}
}

View file

@ -0,0 +1,30 @@
using System;
using System.Linq.Expressions;
using Elsa.Extensions;
using Elsa.Models;
namespace Elsa.Persistence.Specifications
{
public class WorkflowInstanceContextIdMatchSpecification : Specification<WorkflowInstance>
{
public string ContextType { get; set; }
public string ContextId { get; set; }
public WorkflowInstanceContextIdMatchSpecification(string contextType, string contextId)
{
ContextType = contextType;
ContextId = contextId;
}
public WorkflowInstanceContextIdMatchSpecification(Type contextType, string contextId) : this(contextType.GetContextTypeName(), contextId)
{
}
public override Expression<Func<WorkflowInstance, bool>> ToExpression() => x => x.ContextType!.Contains(ContextType) && x.ContextId!.Contains(ContextId);
public override bool IsSatisfiedBy(WorkflowInstance entity) => entity.ContextType != null
&& entity.ContextType.IndexOf(ContextType, StringComparison.OrdinalIgnoreCase) >= 0
&& entity.ContextId != null
&& entity.ContextId.IndexOf(ContextId, StringComparison.OrdinalIgnoreCase) >= 0;
}
}

View file

@ -0,0 +1,26 @@
using System;
using System.Linq.Expressions;
using Elsa.Extensions;
using Elsa.Models;
namespace Elsa.Persistence.Specifications
{
public class WorkflowInstanceContextMatchSpecification : Specification<WorkflowInstance>
{
public string ContextType { get; set; }
public WorkflowInstanceContextMatchSpecification(string contextType)
{
ContextType = contextType;
}
public WorkflowInstanceContextMatchSpecification(Type contextType) : this(contextType.GetContextTypeName())
{
}
public override Expression<Func<WorkflowInstance, bool>> ToExpression() => x => x.ContextType!.Contains(ContextType);
public override bool IsSatisfiedBy(WorkflowInstance entity) => entity.ContextType != null
&& entity.ContextType.IndexOf(ContextType, StringComparison.OrdinalIgnoreCase) >= 0;
}
}

View file

@ -1,6 +1,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Extensions;
using Elsa.Models;
using Elsa.Services.Models;
using NodaTime;
@ -37,7 +38,8 @@ namespace Elsa.Services
ContextId = contextId,
CreatedAt = _clock.GetCurrentInstant(),
Activities = workflowBlueprint.Activities.Select(CreateInstance).ToList(),
Variables = new Variables(workflowBlueprint.Variables)
Variables = new Variables(workflowBlueprint.Variables),
ContextType = workflowBlueprint.ContextOptions?.ContextType ?.GetContextTypeName()
};
return Task.FromResult(workflowInstance);

View file

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using AutoMapper.Configuration.Conventions;
using Elsa.Comparers;
using Elsa.Models;
@ -16,6 +16,7 @@ namespace Elsa.Persistence.YesSql.Documents
public int Version { get; set; }
public WorkflowStatus WorkflowStatus { get; set; }
public string? CorrelationId { get; set; }
public string? ContextType { get; set; }
public string? ContextId { get; set; }
public string? Name { get; set; }
public Instant CreatedAt { get; set; }

View file

@ -14,6 +14,7 @@ namespace Elsa.Persistence.YesSql.Indexes
public string DefinitionId { get; set; } = default!;
public int Version { get; set; }
public string? CorrelationId { get; set; }
public string? ContextType { get; set; }
public string? ContextId { get; set; }
public string? Name { get; set; }
public WorkflowStatus WorkflowStatus { get; set; }
@ -50,6 +51,7 @@ namespace Elsa.Persistence.YesSql.Indexes
Version = workflowInstance.Version,
WorkflowStatus = workflowInstance.WorkflowStatus,
CorrelationId = workflowInstance.CorrelationId,
ContextType = workflowInstance.ContextType,
ContextId = workflowInstance.ContextId,
Name = workflowInstance.Name,
CreatedAt = workflowInstance.CreatedAt.ToDateTimeOffset(),