onebeyond/onebeyond-studio-core

View on GitHub
src/OneBeyond.Studio.EntityAuditing/OneBeyond.Studio.EntityAuditing.AzureTableStorage/Entities/TableEntityHelper.cs

Summary

Maintainability
A
1 hr
Test Coverage
using System;
using Azure.Data.Tables;
using EnsureThat;
using Newtonsoft.Json.Linq;
using OneBeyond.Studio.Crosscuts.DateTimes;
using OneBeyond.Studio.EntityAuditing.AzureTableStorage.Util;
using OneBeyond.Studio.EntityAuditing.Domain;

namespace OneBeyond.Studio.EntityAuditing.AzureTableStorage.Entities;

public static class TableEntityHelper
{
    private const string JSON_CHANGES_COLUMN = "ChangedData";
    private const string OLD_PREFIX = "Old";
    private const string NEW_PREFIX = "New";

    public static TableEntity CreateEntity(AuditEvent auditEntityEvent, JToken changes, bool expandValuesInTableColumns)
    {
        EnsureArg.IsNotNull(auditEntityEvent, nameof(auditEntityEvent));

        // Need to turn the identity into a string key (if is an int, pad to 10 digits)
        var partitionKey = StorageTableUtils.BuildPartitionKey(auditEntityEvent.EntityId);

        // As this is an audit, we want to use the log-tail pattern
        // in order to optimize TOP queries looking for most recent changes
        // Ref: https://docs.microsoft.com/en-gb/azure/cosmos-db/table-storage-design-guide#log-tail-pattern
        var rowKey = DateTime.UtcNow.ToInvertedTicks();

        var tableEntity = new TableEntity(partitionKey, rowKey)
        {
            ["UserId"] = auditEntityEvent.UserId,
            ["EventType"] = auditEntityEvent.EventType
        };

        if (auditEntityEvent.EntityDescription != null)
        {
            tableEntity["EntityDescriptor"] = auditEntityEvent.EntityDescription;
        }

        if (expandValuesInTableColumns)
        {
            foreach (var change in changes)
            {
                var propertyName = change[nameof(AuditChange.PropertyName)];
                var oldValue = change[nameof(AuditChange.OriginalValue)];
                var newValue = change[nameof(AuditChange.NewValue)];
                tableEntity[$"{OLD_PREFIX}_{propertyName}"] = oldValue.ToEntityProperty();
                tableEntity[$"{NEW_PREFIX}_{propertyName}"] = newValue.ToEntityProperty();
            }
        }

        tableEntity[JSON_CHANGES_COLUMN] = changes.ToString();

        return tableEntity;
    }
}