private static async Task PopulateResourceEventData(
            IResourceEventRepository resourceEventRepository,
            ApiOperationContext context,
            ResourceEvent resourceEvent)
        {
            // Get the latest after creation or update (cannot, obviously, get for a deleted record)
            if (resourceEvent.ChangeType != ResourceEventChangeType.Deleted)
            {
                resourceEvent.Data = await GetByIdAsync(context, resourceEvent.SelfQuery);
            }

            if (resourceEvent.ChangeType == ResourceEventChangeType.Updated)
            {
                var previousResource =
                    await resourceEventRepository.GetCurrentDataAsync(resourceEvent.Href, resourceEvent.ResourceType);

                // There are cases where the old resource will not exist because resources being saved was a new
                // introduction after being in prod for over a year
                if (previousResource != null)
                {
                    resourceEvent.ChangedValues = ObjectComparer.GetPreviousValues(
                        previousResource,
                        resourceEvent.Data);
                }
            }
        }
Esempio n. 2
0
        public static async Task HandleAsync(
            IResourceEventRepository resourceEventRepository,
            IApiLinkGenerator apiLinkGenerator,
            ApiOperationContext context,
            OperationResult result)
        {
            if (result is OkResult okResult)
            {
                var innerResult = okResult.Content;

                if (innerResult is ResourceEvent resourceEvent)
                {
                    var logger = context.ServiceProvider.GetRequiredService <ILogger <ResourceEventHandlerMiddlewareBuilder> >();

                    void AddMetadata(string k, object v) => resourceEvent.Metadata[k] = v;

                    context.UserAuthorisationContext?.PopulateMetadata(AddMetadata);

                    resourceEvent.CorrelationId = context.Activity?.Id;
                    resourceEvent.Operation     = context.Operation;

                    var metadataProviders = context.ServiceProvider.GetServices <IContextMetadataProvider>();

                    foreach (var p in metadataProviders)
                    {
                        await p.PopulateMetadataAsync(context, AddMetadata);
                    }

                    // If we do not already have Data use the "SelfQuery" to populate using a nested query if possible
                    if (resourceEvent.Data == null && resourceEvent.SelfQuery != null)
                    {
                        await TryPopulateResourceEventDataAsync(context, resourceEvent);
                    }

                    var selfLink = context.DataModel.GetLinkFor(resourceEvent.ResourceType, "self");

                    if (selfLink == null)
                    {
                        logger.LogWarning(
                            "No self link exists. Href property of the resource event of type {ResourceType} will not be populated",
                            resourceEvent.ResourceType);
                    }
                    else
                    {
                        resourceEvent.Href = apiLinkGenerator.CreateUrl(selfLink, resourceEvent.Data ?? resourceEvent.SelfQuery);
                    }

                    if (resourceEvent.Data != null)
                    {
                        await TryPopulateChangedValuesAsync(resourceEventRepository, resourceEvent);
                    }

                    await resourceEventRepository.AddAsync(resourceEvent);
                }
            }
        }
        public static async Task HandleAsync(
            IResourceEventRepository resourceEventRepository,
            IApiLinkGenerator apiLinkGenerator,
            ApiOperationContext context,
            OperationResult result)
        {
            if (result is OkResult okResult)
            {
                var innerResult = okResult.Content;

                if (innerResult is ResourceEvent resourceEvent)
                {
                    var logger = context.ServiceProvider.GetRequiredService <ILogger <ResourceEventHandlerMiddlewareBuilder> >();

                    logger.LogDebug("ResourceEvent found. Loading resource. resource_type={0}", resourceEvent.ResourceType);

                    void AddMetadata(string k, object v) => resourceEvent.Metadata[k] = v;

                    context.UserAuthorisationContext?.PopulateMetadata(AddMetadata);

                    resourceEvent.CorrelationId = Activity.Current?.Id;
                    resourceEvent.Operation     = context.Operation;

                    var metadataProviders = context.ServiceProvider.GetServices <IContextMetadataProvider>();

                    foreach (var p in metadataProviders)
                    {
                        await p.PopulateMetadataAsync(context, AddMetadata);
                    }

                    var selfLink = context.DataModel.GetLinkFor(resourceEvent.ResourceType, "self");

                    if (selfLink == null)
                    {
                        logger.LogWarning(
                            "No self link exists. Link and payload will not be populated. resource_type={0}",
                            resourceEvent.ResourceType.Name);

                        return;
                    }

                    resourceEvent.Href = apiLinkGenerator.CreateUrl(selfLink, resourceEvent.SelfQuery);

                    await PopulateResourceEventData(resourceEventRepository, context, resourceEvent);

                    await resourceEventRepository.AddAsync(resourceEvent);
                }
            }
        }
Esempio n. 4
0
        private static async Task TryPopulateChangedValuesAsync(
            IResourceEventRepository resourceEventRepository,
            ResourceEvent resourceEvent)
        {
            if (resourceEvent.ChangeType == ResourceEventChangeType.Updated && resourceEvent.Data != null)
            {
                var previousResource =
                    await resourceEventRepository.GetCurrentDataAsync(resourceEvent.Href, resourceEvent.Data.GetType());

                // There are cases where the old resource will not exist because resources being saved was a new
                // introduction after being in prod for over a year
                if (previousResource != null)
                {
                    resourceEvent.ChangedValues = ObjectComparer.GetPreviousValues(
                        previousResource,
                        resourceEvent.Data);
                }
            }
        }