public static async Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "CatalogueScanState/Update")] CatalogueScanStateDto dto, [DurableClient] IDurableEntityClient durableEntityClient ) { #region null checks if (dto is null) { throw new ArgumentNullException(nameof(dto)); } if (durableEntityClient is null) { throw new ArgumentNullException(nameof(durableEntityClient)); } #endregion var entityId = ICatalogueScanState.CreateId(new CatalogueScanStateKey(dto.CatalogueType, dto.Store, dto.CatalogueId)); await durableEntityClient.SignalEntityAsync <ICatalogueScanState>( entityId, (scanState) => scanState.UpdateState(dto.ScanState) ).ConfigureAwait(false); return(new OkResult()); }
public static async Task RunOrchestrator([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { #region null checks if (context is null) { throw new ArgumentNullException(nameof(context)); } if (log is null) { throw new ArgumentNullException(nameof(log)); } #endregion log = context.CreateReplaySafeLogger(log); var catalogueDownloadInfo = context.GetInput <SaleFinderCatalogueDownloadInformation>(); var scanStateId = ICatalogueScanState.CreateId(new CatalogueScanStateKey(CatalogueType, catalogueDownloadInfo.Store, catalogueDownloadInfo.SaleId.ToString(CultureInfo.InvariantCulture))); var scanState = context.CreateEntityProxy <ICatalogueScanState>(scanStateId); using (await context.LockAsync(scanStateId).ConfigureAwait(true)) { #region Check and update the catalogue's scan state context.SetCustomStatus("CheckingState"); log.LogDebug($"Checking state - {scanStateId.EntityKey}"); var state = await scanState.GetState().ConfigureAwait(true); if (state != ScanState.NotStarted) { log.LogInformation($"Catalogue {scanStateId.EntityKey} already in state {state}, skipping scan."); context.SetCustomStatus("Skipped"); return; } await scanState.UpdateState(ScanState.InProgress).ConfigureAwait(true); #endregion #region Download catalogue context.SetCustomStatus("Downloading"); log.LogDebug($"Downloading - {scanStateId.EntityKey}"); var downloadedCatalogue = await context.CallActivityAsync <Catalogue>(SaleFinderFunctionNames.DownloadSaleFinderCatalogue, catalogueDownloadInfo).ConfigureAwait(true); #endregion #region Filter catalouge items context.SetCustomStatus("Filtering"); log.LogDebug($"Filtering - {scanStateId.EntityKey}"); var itemTasks = downloadedCatalogue.Items .Select(item => context.CallActivityAsync <CatalogueItem?>(CoreFunctionNames.FilterCatalogueItem, item)) .ToList(); await Task.WhenAll(itemTasks).ConfigureAwait(true); #endregion #region Send digest email context.SetCustomStatus("SendingDigestEmail"); log.LogDebug($"Sending digest email - {scanStateId.EntityKey}"); var filteredItems = itemTasks .Where(task => task.Result != null) .Select(task => task.Result !) .ToList(); if (filteredItems.Any()) { var filteredCatalogue = new Catalogue(downloadedCatalogue.Store, downloadedCatalogue.StartDate, downloadedCatalogue.EndDate, filteredItems); await context.CallActivityAsync(CoreFunctionNames.SendCatalogueDigestEmail, filteredCatalogue).ConfigureAwait(true); } else { log.LogInformation($"Catalogue {scanStateId.EntityKey} had no matching items, skipping digest email."); } #endregion #region Update catalogue's scan state context.SetCustomStatus("UpdatingState"); log.LogDebug($"Updating state - {scanStateId.EntityKey}"); await scanState.UpdateState(ScanState.Completed).ConfigureAwait(true); #endregion log.LogDebug($"Completed - {scanStateId.EntityKey}"); context.SetCustomStatus("Completed"); } }