Skip to content

Commit

Permalink
Complex type
Browse files Browse the repository at this point in the history
  • Loading branch information
dstenroejl committed Nov 19, 2024
1 parent cf3113f commit 59c7733
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2020 Energinet DataHub A/S
//
// Licensed under the Apache License, Version 2.0 (the "License2");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System.ComponentModel.DataAnnotations.Schema;

namespace Energinet.DataHub.ProcessManagement.Core.Domain.OrchestrationInstance;

public record OperatingIdentityComplexType
{
internal OperatingIdentityComplexType(OperatingIdentity value)
{
Value = value;
}

/// <summary>
/// Used by Entity Framework
/// </summary>
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
// ReSharper disable once UnusedMember.Local -- Used by Entity Framework
private OperatingIdentityComplexType()
{
}
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.

public OperatingIdentity Value
{
get
{
switch (IdentityType)
{
case nameof(ActorIdentity):
return new ActorIdentity(new ActorId(ActorId!.Value));

case nameof(UserIdentity):
return new UserIdentity(new UserId(UserId!.Value), new ActorId(ActorId!.Value));

default:
throw new InvalidOperationException($"Unknown operating identity type '{IdentityType}'.");
}
}

private set
{
switch (value)
{
case ActorIdentity actor:
IdentityType = nameof(ActorIdentity);
ActorId = actor.ActorId.Value;
break;

case UserIdentity user:
IdentityType = nameof(UserIdentity);
ActorId = user.ActorId.Value;
UserId = user.UserId.Value;
break;

default:
throw new InvalidOperationException($"Invalid type '{value.GetType()}'.");
}
}
}

internal string? IdentityType { get; private set; }

internal Guid? ActorId { get; private set; }

internal Guid? UserId { get; private set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class OrchestrationInstanceLifecycleState
{
internal OrchestrationInstanceLifecycleState(OperatingIdentity createdBy, IClock clock, Instant? runAt)
{
CreatedBy = createdBy;
CreatedBy = new OperatingIdentityComplexType(createdBy);
CreatedAt = clock.GetCurrentInstant();
ScheduledToRunAt = runAt;

Expand All @@ -44,7 +44,7 @@ private OrchestrationInstanceLifecycleState()
/// <summary>
/// The identity that caused this orchestration instance to be created.
/// </summary>
public OperatingIdentity CreatedBy { get; }
public OperatingIdentityComplexType CreatedBy { get; }

/// <summary>
/// The time when the orchestration instance was created (State => Pending).
Expand Down Expand Up @@ -77,7 +77,13 @@ private OrchestrationInstanceLifecycleState()
/// <summary>
/// The identity that caused this orchestration instance to be canceled.
/// </summary>
public OperatingIdentity? CanceledBy { get; private set; }
public OperatingIdentityComplexType? CanceledBy { get; private set; }

internal string? CreatedByIdentityType { get; private set; }

internal Guid? CreatedByActorId { get; private set; }

internal Guid? CreatedByUserId { get; private set; }

public bool IsPendingForScheduledStart()
{
Expand Down Expand Up @@ -128,12 +134,15 @@ private void TransitionToTerminated(IClock clock, OrchestrationInstanceTerminati
if (State is not OrchestrationInstanceLifecycleStates.Running)
throw new InvalidOperationException($"Cannot change termination state to '{terminationState}' when '{State}'.");
break;

case OrchestrationInstanceTerminationStates.UserCanceled:
if (!IsPendingForScheduledStart())
throw new InvalidOperationException("User cannot cancel orchestration instance.");
CanceledBy = userIdentity
?? throw new InvalidOperationException("User identity must be specified.");
if (userIdentity == null)
throw new InvalidOperationException("User identity must be specified.");
CanceledBy = new OperatingIdentityComplexType(userIdentity);
break;

default:
throw new InvalidOperationException($"Unsupported termination state '{terminationState}'.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void Configure(EntityTypeBuilder<OrchestrationDescription> builder)
o => o.ParameterDefinition,
b =>
{
b.Property(pv => pv.SerializedParameterDefinition)
b.Property(pd => pd.SerializedParameterDefinition)
.HasColumnName(nameof(OrchestrationDescription.ParameterDefinition.SerializedParameterDefinition));
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,43 @@ public void Configure(EntityTypeBuilder<OrchestrationInstance> builder)
o => o.Lifecycle,
b =>
{
b.Property(pv => pv.State);
b.Property(pv => pv.TerminationState);

b.Property(pv => pv.CreatedAt);
b.Property(pv => pv.ScheduledToRunAt);
b.Property(pv => pv.QueuedAt);
b.Property(pv => pv.StartedAt);
b.Property(pv => pv.TerminatedAt);
b.Property(l => l.State);
b.Property(l => l.TerminationState);

b.OwnsOne(
l => l.CreatedBy,
lb =>
{
lb.Ignore(ct => ct.Value);

lb.Property(ct => ct.IdentityType);
lb.Property(ct => ct.ActorId);
lb.Property(ct => ct.UserId);
});

b.Property(l => l.CreatedAt);
b.Property(l => l.ScheduledToRunAt);
b.Property(l => l.QueuedAt);
b.Property(l => l.StartedAt);
b.Property(l => l.TerminatedAt);

b.OwnsOne(
l => l.CanceledBy,
lb =>
{
lb.Ignore(ct => ct.Value);

lb.Property(ct => ct.IdentityType);
lb.Property(ct => ct.ActorId);
lb.Property(ct => ct.UserId);
});
});

builder.OwnsOne(
o => o.ParameterValue,
b =>
{
b.Property(pv => pv.SerializedParameterValue)
b.Property(l => l.SerializedParameterValue)
.HasColumnName(nameof(OrchestrationInstance.ParameterValue.SerializedParameterValue));
});

Expand All @@ -71,13 +93,13 @@ public void Configure(EntityTypeBuilder<OrchestrationInstance> builder)
o => o.Lifecycle,
b =>
{
b.Property(pv => pv.State);
b.Property(pv => pv.TerminationState);
b.Property(l => l.State);
b.Property(l => l.TerminationState);

b.Property(pv => pv.StartedAt);
b.Property(pv => pv.TerminatedAt);
b.Property(l => l.StartedAt);
b.Property(l => l.TerminatedAt);

b.Property(pv => pv.CanBeSkipped);
b.Property(l => l.CanBeSkipped);
});

b.Property(s => s.Description);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static ApiModel.OrchestrationInstanceLifecycleStateDto MapToDto(
this DomainModel.OrchestrationInstanceLifecycleState entity)
{
return new ApiModel.OrchestrationInstanceLifecycleStateDto(
CreatedBy: entity.CreatedBy.MapToDto(),
CreatedBy: entity.CreatedBy.Value.MapToDto(),
State: Enum
.TryParse<ApiModel.OrchestrationInstanceLifecycleStates>(
entity.State.ToString(),
Expand All @@ -50,7 +50,7 @@ public static ApiModel.OrchestrationInstanceLifecycleStateDto MapToDto(
out var terminationStateResult)
? terminationStateResult
: null,
CanceledBy: entity.CanceledBy?.MapToDto(),
CanceledBy: entity.CanceledBy?.Value.MapToDto(),
CreatedAt: entity.CreatedAt.ToDateTimeOffset(),
ScheduledToRunAt: entity.ScheduledToRunAt?.ToDateTimeOffset(),
QueuedAt: entity.QueuedAt?.ToDateTimeOffset(),
Expand Down

0 comments on commit 59c7733

Please sign in to comment.