Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Use data from events, not from db #455

Merged
merged 4 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,71 +1,58 @@
using Digdir.Domain.Dialogporten.Application.Externals;
using Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Activities;
using Digdir.Domain.Dialogporten.Domain.Dialogs.Events.Activities;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;

namespace Digdir.Domain.Dialogporten.Application.Features.V1.Common.Events;

internal sealed class DialogActivityEventToAltinnForwarder : DomainEventToAltinnForwarderBase,
INotificationHandler<DialogActivityCreatedDomainEvent>
{
public DialogActivityEventToAltinnForwarder(ICloudEventBus cloudEventBus, IDialogDbContext db, IOptions<ApplicationSettings> settings)
: base(cloudEventBus, db, settings) { }
public DialogActivityEventToAltinnForwarder(ICloudEventBus cloudEventBus, IOptions<ApplicationSettings> settings)
: base(cloudEventBus, settings) { }

public async Task Handle(DialogActivityCreatedDomainEvent domainEvent, CancellationToken cancellationToken)
{
var dialogActivity = await Db.DialogActivities
.Include(e => e.Dialog)
.Include(e => e.DialogElement)
.Include(e => e.RelatedActivity)
.AsNoTracking()
.FirstOrDefaultAsync(x => x.Id == domainEvent.DialogActivityId, cancellationToken)
?? throw new KeyNotFoundException($"DialogActivity with id {domainEvent.DialogActivityId} not found");

var cloudEvent = new CloudEvent
{
Id = domainEvent.EventId,
Type = CloudEventTypes.Get(dialogActivity.TypeId),
Type = CloudEventTypes.Get(domainEvent.TypeId),
Time = domainEvent.OccuredAt,
Resource = dialogActivity.Dialog.ServiceResource,
ResourceInstance = dialogActivity.Dialog.Id.ToString(),
Subject = dialogActivity.Dialog.Party,
Source = $"{DialogportenBaseUrl()}/api/v1/enduser/dialogs/{dialogActivity.Dialog.Id}/activities/{dialogActivity.Id}",
Data = GetCloudEventData(dialogActivity)
Resource = domainEvent.ServiceResource,
ResourceInstance = domainEvent.DialogId.ToString(),
Subject = domainEvent.Party,
Source = $"{SourceBaseUrl()}{domainEvent.DialogId}/activities/{domainEvent.ActivityId}",
Data = GetCloudEventData(domainEvent)
};

await CloudEventBus.Publish(cloudEvent, cancellationToken);
}

private static Dictionary<string, object> GetCloudEventData(DialogActivity dialogActivity)
private static Dictionary<string, object> GetCloudEventData(DialogActivityCreatedDomainEvent domainEvent)
{
var data = new Dictionary<string, object>
{
["activityId"] = dialogActivity.Id.ToString(),
["activityId"] = domainEvent.ActivityId.ToString(),
};

if (dialogActivity.ExtendedType is not null)
if (domainEvent.ExtendedType is not null)
{
data["extendedActivityType"] = dialogActivity.ExtendedType.ToString();
data["extendedActivityType"] = domainEvent.ExtendedType.ToString();
}

if (dialogActivity.RelatedActivity is not null)
if (domainEvent.RelatedActivityId is not null)
{
data["extendedActivityType"] = dialogActivity.RelatedActivity.Id.ToString()!;
data["relatedActivityId"] = domainEvent.RelatedActivityId.ToString()!;
}

if (dialogActivity.DialogElement is null) return data;

data["dialogElementId"] = dialogActivity.DialogElement.Id.ToString();
if (dialogActivity.DialogElement.Type is not null)
if (domainEvent.DialogElementId is not null)
{
data["dialogElementType"] = dialogActivity.DialogElement.Type.ToString();
data["dialogElementId"] = domainEvent.DialogElementId.ToString()!;
}

if (dialogActivity.DialogElement.RelatedDialogElement is not null)
if (domainEvent.DialogElementType is not null)
{
data["relatedDialogElementId"] = dialogActivity.DialogElement.RelatedDialogElement.Id.ToString()!;
data["dialogElementType"] = domainEvent.DialogElementType.ToString();
}

return data;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using Digdir.Domain.Dialogporten.Application.Externals;
using Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Elements;
using Digdir.Domain.Dialogporten.Domain.Dialogs.Events.DialogElements;
using Digdir.Library.Entity.Abstractions.Features.EventPublisher;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;

namespace Digdir.Domain.Dialogporten.Application.Features.V1.Common.Events;
Expand All @@ -13,100 +10,102 @@ internal sealed class DialogElementEventToAltinnForwarder : DomainEventToAltinnF
INotificationHandler<DialogElementCreatedDomainEvent>,
INotificationHandler<DialogElementDeletedDomainEvent>
{
public DialogElementEventToAltinnForwarder(ICloudEventBus cloudEventBus, IDialogDbContext db, IOptions<ApplicationSettings> settings)
: base(cloudEventBus, db, settings)
{
}
public DialogElementEventToAltinnForwarder(ICloudEventBus cloudEventBus, IOptions<ApplicationSettings> settings)
: base(cloudEventBus, settings) { }

public async Task Handle(DialogElementUpdatedDomainEvent domainEvent, CancellationToken cancellationToken)
{
var dialogElement = await GetDialogElement(domainEvent.DialogElementId, cancellationToken);
var cloudEvent = CreateCloudEvent(dialogElement, domainEvent);
await CloudEventBus.Publish(cloudEvent, cancellationToken);
}
var data = new Dictionary<string, object>
{
["dialogElementId"] = domainEvent.DialogElementId.ToString()
};

if (domainEvent.RelatedDialogElementId is not null)
{
data["relatedDialogElementId"] = domainEvent.RelatedDialogElementId;
}

if (domainEvent.Type is not null)
{
data["dialogElementType"] = domainEvent.Type;
}

var cloudEvent = new CloudEvent
{
Id = domainEvent.EventId,
Type = CloudEventTypes.Get(domainEvent),
Time = domainEvent.OccuredAt,
Resource = domainEvent.ServiceResource,
ResourceInstance = domainEvent.DialogId.ToString(),
Subject = domainEvent.Party,
Source = $"{SourceBaseUrl()}{domainEvent.DialogId}/elements/{domainEvent.DialogElementId}",
Data = data
};

public async Task Handle(DialogElementCreatedDomainEvent domainEvent, CancellationToken cancellationToken)
{
var dialogElement = await GetDialogElement(domainEvent.DialogElementId, cancellationToken);
var cloudEvent = CreateCloudEvent(dialogElement, domainEvent);
await CloudEventBus.Publish(cloudEvent, cancellationToken);
}

public async Task Handle(DialogElementDeletedDomainEvent domainEvent, CancellationToken cancellationToken)
public async Task Handle(DialogElementCreatedDomainEvent domainEvent, CancellationToken cancellationToken)
{
var dialog = await GetDialog(domainEvent.DialogId, cancellationToken);

var data = new Dictionary<string, object>
{
["dialogElementId"] = domainEvent.DialogElementId.ToString()
};

if (domainEvent.RelatedDialogElementId is not null)
{
data["relatedDialogElementId"] = domainEvent.RelatedDialogElementId.Value.ToString();
data["relatedDialogElementId"] = domainEvent.RelatedDialogElementId;
}

if (domainEvent.Type is not null)
{
data["dialogElementType"] = domainEvent.Type.ToString();
data["dialogElementType"] = domainEvent.Type;
}

var cloudEvent = new CloudEvent
{
Id = domainEvent.EventId,
Type = CloudEventTypes.Get(domainEvent),
Time = domainEvent.OccuredAt,
Resource = dialog.ServiceResource,
ResourceInstance = dialog.Id.ToString(),
Subject = dialog.Party,
Source = $"{DialogportenBaseUrl()}/api/v1/enduser/dialogs/{dialog.Id}/elements/{domainEvent.DialogElementId}",
Resource = domainEvent.ServiceResource,
ResourceInstance = domainEvent.DialogId.ToString(),
Subject = domainEvent.Party,
Source = $"{SourceBaseUrl()}{domainEvent.DialogId}/elements/{domainEvent.DialogElementId}",
Data = data
};

await CloudEventBus.Publish(cloudEvent, cancellationToken);
}

private CloudEvent CreateCloudEvent(DialogElement dialogElement, IDomainEvent domainEvent) => new()
{
Id = domainEvent.EventId,
Type = CloudEventTypes.Get(domainEvent),
Time = domainEvent.OccuredAt,
Resource = dialogElement.Dialog.ServiceResource,
ResourceInstance = dialogElement.Dialog.Id.ToString(),
Subject = dialogElement.Dialog.Party,
Source = $"{DialogportenBaseUrl()}/api/v1/enduser/dialogs/{dialogElement.Dialog.Id}/elements/{dialogElement.Id}",
Data = GetCloudEventData(dialogElement)
};

private static Dictionary<string, object> GetCloudEventData(DialogElement dialogElement)
public async Task Handle(DialogElementDeletedDomainEvent domainEvent, CancellationToken cancellationToken)
{
var data = new Dictionary<string, object>
{
["dialogElementId"] = dialogElement.Id.ToString()
["dialogElementId"] = domainEvent.DialogElementId.ToString()
};

if (dialogElement.RelatedDialogElement is not null)
if (domainEvent.RelatedDialogElementId is not null)
{
data["relatedDialogElementId"] = dialogElement.RelatedDialogElement.Id.ToString();
data["relatedDialogElementId"] = domainEvent.RelatedDialogElementId;
}

if (dialogElement.Type is not null)
if (domainEvent.Type is not null)
{
data["dialogElementType"] = dialogElement.Type.ToString();
data["dialogElementType"] = domainEvent.Type;
}

return data;
}
var cloudEvent = new CloudEvent
{
Id = domainEvent.EventId,
Type = CloudEventTypes.Get(domainEvent),
Time = domainEvent.OccuredAt,
Resource = domainEvent.ServiceResource,
ResourceInstance = domainEvent.DialogId.ToString(),
Subject = domainEvent.Party,
Source = $"{SourceBaseUrl()}{domainEvent.DialogId}/elements/{domainEvent.DialogElementId}",
Data = data
};

private async Task<DialogElement> GetDialogElement(Guid dialogElementId, CancellationToken cancellationToken)
{
var dialogElement = await Db.DialogElements
.Include(e => e.Dialog)
.Include(e => e.RelatedDialogElement)
.AsNoTracking()
.FirstOrDefaultAsync(x => x.Id == dialogElementId, cancellationToken)
?? throw new KeyNotFoundException($"DialogElement with id {dialogElementId} not found");

return dialogElement;
await CloudEventBus.Publish(cloudEvent, cancellationToken);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Digdir.Domain.Dialogporten.Application.Externals;
using Digdir.Domain.Dialogporten.Domain.Dialogs.Entities;
using Digdir.Domain.Dialogporten.Domain.Dialogs.Events;
using Digdir.Library.Entity.Abstractions.Features.EventPublisher;
using MediatR;
using Microsoft.Extensions.Options;

Expand All @@ -13,28 +11,53 @@ internal sealed class DialogEventToAltinnForwarder : DomainEventToAltinnForwarde
INotificationHandler<DialogDeletedDomainEvent>,
INotificationHandler<DialogSeenDomainEvent>
{
public DialogEventToAltinnForwarder(ICloudEventBus cloudEventBus, IDialogDbContext db,
IOptions<ApplicationSettings> settings)
: base(cloudEventBus, db, settings) { }
public DialogEventToAltinnForwarder(ICloudEventBus cloudEventBus, IOptions<ApplicationSettings> settings)
: base(cloudEventBus, settings) { }

public async Task Handle(DialogCreatedDomainEvent domainEvent, CancellationToken cancellationToken)
{
var dialog = await GetDialog(domainEvent.DialogId, cancellationToken);
var cloudEvent = CreateCloudEvent(domainEvent, dialog);
var cloudEvent = new CloudEvent
{
Id = domainEvent.EventId,
Type = CloudEventTypes.Get(domainEvent),
Time = domainEvent.OccuredAt,
Resource = domainEvent.ServiceResource,
ResourceInstance = domainEvent.DialogId.ToString(),
Subject = domainEvent.Party,
Source = $"{SourceBaseUrl()}{domainEvent.DialogId}"
};
await CloudEventBus.Publish(cloudEvent, cancellationToken);
}

public async Task Handle(DialogUpdatedDomainEvent domainEvent, CancellationToken cancellationToken)
{
var dialog = await GetDialog(domainEvent.DialogId, cancellationToken);
var cloudEvent = CreateCloudEvent(domainEvent, dialog);
var cloudEvent = new CloudEvent
{
Id = domainEvent.EventId,
Type = CloudEventTypes.Get(domainEvent),
Time = domainEvent.OccuredAt,
Resource = domainEvent.ServiceResource,
ResourceInstance = domainEvent.DialogId.ToString(),
Subject = domainEvent.Party,
Source = $"{SourceBaseUrl()}{domainEvent.DialogId}"
};

await CloudEventBus.Publish(cloudEvent, cancellationToken);
}

public async Task Handle(DialogSeenDomainEvent domainEvent, CancellationToken cancellationToken)
{
var dialog = await GetDialog(domainEvent.DialogId, cancellationToken);
var cloudEvent = CreateCloudEvent(domainEvent, dialog);
var cloudEvent = new CloudEvent
{
Id = domainEvent.EventId,
Type = CloudEventTypes.Get(domainEvent),
Time = domainEvent.OccuredAt,
Resource = domainEvent.ServiceResource,
ResourceInstance = domainEvent.DialogId.ToString(),
Subject = domainEvent.Party,
Source = $"{SourceBaseUrl()}{domainEvent.DialogId}"
};

await CloudEventBus.Publish(cloudEvent, cancellationToken);
}

Expand All @@ -48,21 +71,9 @@ public async Task Handle(DialogDeletedDomainEvent domainEvent, CancellationToken
Resource = domainEvent.ServiceResource,
ResourceInstance = domainEvent.DialogId.ToString(),
Subject = domainEvent.Party,
Source = $"{DialogportenBaseUrl()}/api/v1/enduser/dialogs/{domainEvent.DialogId}"
Source = $"{SourceBaseUrl()}{domainEvent.DialogId}"
};

await CloudEventBus.Publish(cloudEvent, cancellationToken);
}

private CloudEvent CreateCloudEvent(IDomainEvent domainEvent, DialogEntity dialog, Dictionary<string, object>? data = null) => new()
{
Id = domainEvent.EventId,
Type = CloudEventTypes.Get(domainEvent),
Time = domainEvent.OccuredAt,
Resource = dialog.ServiceResource,
ResourceInstance = dialog.Id.ToString(),
Subject = dialog.Party,
Source = $"{DialogportenBaseUrl()}/api/v1/enduser/dialogs/{dialog.Id}",
Data = data
};
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,19 @@
using Digdir.Domain.Dialogporten.Application.Externals;
using Digdir.Domain.Dialogporten.Domain.Dialogs.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;

namespace Digdir.Domain.Dialogporten.Application.Features.V1.Common.Events;

internal class DomainEventToAltinnForwarderBase
{
protected readonly ICloudEventBus CloudEventBus;
protected readonly IDialogDbContext Db;
private readonly DialogportenSettings _dialogportenSettings;

protected DomainEventToAltinnForwarderBase(ICloudEventBus cloudEventBus, IDialogDbContext db, IOptions<ApplicationSettings> settings)
protected DomainEventToAltinnForwarderBase(ICloudEventBus cloudEventBus, IOptions<ApplicationSettings> settings)
{
CloudEventBus = cloudEventBus ?? throw new ArgumentNullException(nameof(cloudEventBus));
Db = db ?? throw new ArgumentNullException(nameof(db));
_dialogportenSettings = settings.Value.Dialogporten ?? throw new ArgumentNullException(nameof(settings));
}

protected string DialogportenBaseUrl() => _dialogportenSettings.BaseUri.ToString();

protected async Task<DialogEntity> GetDialog(Guid dialogId, CancellationToken cancellationToken)
{
var dialog = await Db.Dialogs
.IgnoreQueryFilters()
.AsNoTracking()
.FirstOrDefaultAsync(x => x.Id == dialogId, cancellationToken)
?? throw new KeyNotFoundException($"Dialog with id {dialogId} not found");

return dialog;
}
internal string SourceBaseUrl() =>
$"{_dialogportenSettings.BaseUri}/api/v1/enduser/dialogs/";
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ public class DialogActivity : IImmutableEntity, IAggregateCreatedHandler, IEvent

public void OnCreate(AggregateNode self, DateTimeOffset utcNow)
{
_domainEvents.Add(new DialogActivityCreatedDomainEvent(DialogId, Id));
_domainEvents.Add(new DialogActivityCreatedDomainEvent(
DialogId, Id, TypeId, Dialog.Party,
Dialog.ServiceResource, ExtendedType,
RelatedActivityId, DialogElementId, DialogElement?.Type));
}

private readonly List<IDomainEvent> _domainEvents = [];
Expand Down
Loading
Loading