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); } } }
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); } } }
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); } } }