Skip to content

Commit

Permalink
Use 'instanceandevents' endpoint when updating process state, so that…
Browse files Browse the repository at this point in the history
… process and events are updated in a single transaction (#937)
  • Loading branch information
martinothamar authored Dec 11, 2024
1 parent 383c9e5 commit 80c12b5
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 210 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,11 @@ internal void InstanceDeleted(Instance instance)
return activity;
}

internal Activity? StartUpdateProcessActivity(Instance instance)
internal Activity? StartUpdateProcessActivity(Instance instance, int eventCount = 0)
{
var activity = ActivitySource.StartActivity($"{Prefix}.UpdateProcess");
activity?.SetInstanceId(instance);
activity?.SetTag(Labels.InstanceEventsCount, eventCount);
return activity;
}

Expand Down
5 changes: 5 additions & 0 deletions src/Altinn.App.Core/Features/Telemetry/Telemetry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ public static class Labels
/// </summary>
public static readonly string InstanceGuid = "instance.guid";

/// <summary>
/// Label for the guid that identifies the instance.
/// </summary>
public static readonly string InstanceEventsCount = "instance.events.count";

/// <summary>
/// Label for the guid that identifies the data.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,39 @@ public async Task<Instance> UpdateProcess(Instance instance)
}
}

/// <inheritdoc />
public async Task<Instance> UpdateProcessAndEvents(Instance instance, List<InstanceEvent> events)
{
using var activity = _telemetry?.StartUpdateProcessActivity(instance, events.Count);
ProcessState processState = instance.Process;

foreach (var instanceEvent in events)
instanceEvent.InstanceId = instance.Id;

string apiUrl = $"instances/{instance.Id}/process/instanceandevents";
string token = _userTokenProvider.GetUserToken();

var update = new ProcessStateUpdate { State = processState, Events = events };
string updateString = JsonConvert.SerializeObject(update);
_logger.LogInformation($"update process state: {updateString}");

StringContent httpContent = new(updateString, Encoding.UTF8, "application/json");
HttpResponseMessage response = await _client.PutAsync(token, apiUrl, httpContent);
if (response.StatusCode == HttpStatusCode.OK)
{
string instanceData = await response.Content.ReadAsStringAsync();
Instance updatedInstance =
JsonConvert.DeserializeObject<Instance>(instanceData)
?? throw new Exception("Could not deserialize instance");
return updatedInstance;
}
else
{
_logger.LogError($"Unable to update instance process with instance id {instance.Id}");
throw await PlatformHttpException.CreateAsync(response);
}
}

/// <inheritdoc/>
public async Task<Instance> CreateInstance(string org, string app, Instance instanceTemplate)
{
Expand Down
5 changes: 5 additions & 0 deletions src/Altinn.App.Core/Internal/Instances/IInstanceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ public interface IInstanceClient
/// </summary>
Task<Instance> UpdateProcess(Instance instance);

/// <summary>
/// Updates the process model of the instance and the instance events and returns the updated instance.
/// </summary>
Task<Instance> UpdateProcessAndEvents(Instance instance, List<InstanceEvent> events);

/// <summary>
/// Creates an instance of an application with no data.
/// </summary>
Expand Down
25 changes: 1 addition & 24 deletions src/Altinn.App.Core/Internal/Process/ProcessEventDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ namespace Altinn.App.Core.Internal.Process;
public class ProcessEventDispatcher : IProcessEventDispatcher
{
private readonly IInstanceClient _instanceClient;
private readonly IInstanceEventClient _instanceEventClient;
private readonly IEventsClient _eventsClient;
private readonly IOptions<AppSettings> _appSettings;
private readonly ILogger<ProcessEventDispatcher> _logger;
Expand All @@ -23,14 +22,12 @@ public class ProcessEventDispatcher : IProcessEventDispatcher
/// </summary>
public ProcessEventDispatcher(
IInstanceClient instanceClient,
IInstanceEventClient instanceEventClient,
IEventsClient eventsClient,
IOptions<AppSettings> appSettings,
ILogger<ProcessEventDispatcher> logger
)
{
_instanceClient = instanceClient;
_instanceEventClient = instanceEventClient;
_eventsClient = eventsClient;
_appSettings = appSettings;
_logger = logger;
Expand All @@ -39,12 +36,7 @@ ILogger<ProcessEventDispatcher> logger
/// <inheritdoc/>
public async Task<Instance> DispatchToStorage(Instance instance, List<InstanceEvent>? events)
{
// need to update the instance process and then the instance in case appbase has changed it, e.g. endEvent sets status.archived
Instance updatedInstance = await _instanceClient.UpdateProcess(instance);
await DispatchProcessEventsToStorage(updatedInstance, events);

// remember to get the instance anew since AppBase can have updated a data element or stored something in the database.
updatedInstance = await _instanceClient.GetInstance(updatedInstance);
Instance updatedInstance = await _instanceClient.UpdateProcessAndEvents(instance, events ?? []);

return updatedInstance;
}
Expand Down Expand Up @@ -74,19 +66,4 @@ await _eventsClient.AddEvent(
}
}
}

private async Task DispatchProcessEventsToStorage(Instance instance, List<InstanceEvent>? events)
{
string org = instance.Org;
string app = instance.AppId.Split("/")[1];

if (events != null)
{
foreach (InstanceEvent instanceEvent in events)
{
instanceEvent.InstanceId = instance.Id;
await _instanceEventClient.SaveInstanceEvent(instanceEvent, org, app);
}
}
}
}
5 changes: 5 additions & 0 deletions test/Altinn.App.Api.Tests/Mocks/InstanceClientMockSi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ public Task<Instance> UpdateProcess(Instance instance)
return Task.FromResult(storedInstance);
}

public Task<Instance> UpdateProcessAndEvents(Instance instance, List<InstanceEvent> events)
{
return UpdateProcess(instance);
}

private static Instance GetTestInstance(string app, string org, int instanceOwnerId, Guid instanceId)
{
string instancePath = GetInstancePath(app, org, instanceOwnerId, instanceId);
Expand Down
Loading

0 comments on commit 80c12b5

Please sign in to comment.