예제 #1
0
            /// <summary>
            /// Initiates a catalog publishing.
            /// </summary>
            /// <param name="catalogPublisher">Instance of the object which implements ICatalogPublisher.</param>
            /// <returns>True if changed products were found in CRT, False otherwise.</returns>
            /// <remarks>Retrieves the channel's catalogs from CRT and then checks whether CRT contains changed products for each of the catalogs. If changed products are found then
            /// ICatalogPublisher's callbacks are executed to let the caller's code process changed products.</remarks>
            public bool PublishCatalog(ICatalogPublisher catalogPublisher)
            {
                if (catalogPublisher == null)
                {
                    throw new ArgumentNullException(nameof(catalogPublisher));
                }

                List <long> productCatalogIds = new List <long>(1);

                // If catalogs were published to this channel, a given product will be published into SP for each catalog
                // in which it appears, so catalogless publishing would not yield different results for those products.
                // If, however, a product was published directly from the assortment, that product will only be detected
                // and published to SP if the ForceCataloglessPublishing flag is set to 'true' (1) in the job configuration file.
                // The semantics of forcing catalogless publishing as strict, in that catalog-less products will be published
                // if and only if the flag is set. That means, for instance, that if the flag is not set and there are no
                // catalogs published to this channel, the SP job will not detect/publish any products to SP.
                if (this.publishingConfig.ForceNoCatalogPublishing)
                {
                    NetTracer.Information(Resources.ProductCatalogToPublish, 0, "unspecified", "(not a proper catalog)");
                    productCatalogIds.Add(0);
                }

                IReadOnlyCollection <ProductCatalog> productCatalogs = this.GetCatalogs();

                bool deletesFound = this.DeleteProducts(productCatalogs, catalogPublisher);

                foreach (ProductCatalog productCatalog in productCatalogs)
                {
                    productCatalogIds.Add(productCatalog.RecordId);
                }

                ChangedProductsSearchCriteria searchCriteria = new ChangedProductsSearchCriteria
                {
                    DataLevel = CommerceEntityDataLevel.Complete
                };

                searchCriteria.Context.ChannelId = this.onlineChannel.RecordId;

                bool isInitialSync;

                QueryResultSettings productsQuerySettings = this.CreateGetListingsCriteria(
                    this.onlineChannel.ChannelProperties,
                    searchCriteria,
                    out isInitialSync);

                bool changesFound = false;

                try
                {
                    Stopwatch readChangedProductsWatch = Stopwatch.StartNew();
                    searchCriteria.Session = this.productManager.BeginReadChangedProducts(searchCriteria);
                    readChangedProductsWatch.Stop();
                    this.LogTimingMessage(Resources.Duration_ReadChangedProducts, readChangedProductsWatch.Elapsed, searchCriteria.Session.TotalNumberOfProducts);

                    if (searchCriteria.Session.TotalNumberOfProducts > 0)
                    {
                        changesFound = true;
                        int totalProductsCount = 0;

                        Stopwatch timerCummulativeListingRetrieval = new Stopwatch();

                        // loop through the product catalogs, retrieving products.
                        foreach (long productCatalogId in productCatalogIds)
                        {
                            NetTracer.Information(Resources.StartReadProductsFromCatalog, productCatalogId);

                            // set the catalog id on the search criteria
                            searchCriteria.Context.CatalogId = productCatalogId;
                            searchCriteria.Session.ResetNumberOfProductsRead();

                            int pageNumberForCatalog = 0;
                            int catalogProductsCount = 0;

                            // inner loop: load changes, page by page, up to catalog max size
                            do
                            {
                                timerCummulativeListingRetrieval.Start();
                                ChangedProductsSearchResult getProductsResults = this.LoadChangedProducts(searchCriteria, productsQuerySettings);
                                timerCummulativeListingRetrieval.Stop();

                                int numberOfReadProducts = getProductsResults.Results.Count;
                                totalProductsCount   += numberOfReadProducts;
                                catalogProductsCount += numberOfReadProducts;
                                this.LogTimingMessage(Resources.NumberOfReadProductsInPageSummary, productCatalogId, catalogProductsCount, totalProductsCount, timerCummulativeListingRetrieval.Elapsed);

                                catalogPublisher.OnChangedProductsFound(getProductsResults, pageNumberForCatalog, productCatalogId);
                                pageNumberForCatalog++;
                            }while (searchCriteria.Session.NumberOfProductsRead < searchCriteria.Session.TotalNumberOfProducts);

                            this.LogTimingMessage(Resources.CatalogReadCompleted, productCatalogId, catalogProductsCount, totalProductsCount, timerCummulativeListingRetrieval.Elapsed);

                            catalogPublisher.OnCatalogReadCompleted(productCatalogId, this);
                        }   // for each product catalog

                        this.LogTimingMessage(Resources.AllCatalogsReadCompleted, totalProductsCount, timerCummulativeListingRetrieval.Elapsed);
                    } // if changed products were found
                }
                finally
                {
                    this.productManager.EndReadChangedProducts(searchCriteria.Session);
                }

                ChannelProperty channelProperty = new ChannelProperty
                {
                    Name  = KeySyncAnchor,
                    Value = new string(searchCriteria.Session.NextSynchronizationToken)
                };

                this.channelManager.UpdateChannelProperties(new ChannelProperty[] { channelProperty });

                return(changesFound || deletesFound);
            }