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());
        }
Esempio n. 2
0
        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");
            }
        }