private void ImportCoreOuter(DataImporterContext ctx)
        {
            if (ctx.Request.Profile == null || !ctx.Request.Profile.Enabled)
                return;

            var logPath = ctx.Request.Profile.GetImportLogPath();

            FileSystemHelper.Delete(logPath);

            using (var logger = new TraceLogger(logPath))
            {
                try
                {
                    ctx.Log = logger;

                    ctx.ExecuteContext.DataExchangeSettings = _dataExchangeSettings.Value;
                    ctx.ExecuteContext.Services = _services;
                    ctx.ExecuteContext.Log = logger;
                    ctx.ExecuteContext.Languages = _languageService.GetAllLanguages(true);
                    ctx.ExecuteContext.UpdateOnly = ctx.Request.Profile.UpdateOnly;
                    ctx.ExecuteContext.KeyFieldNames = ctx.Request.Profile.KeyFieldNames.SplitSafe(",");
                    ctx.ExecuteContext.ImportFolder = ctx.Request.Profile.GetImportFolder();
                    ctx.ExecuteContext.ExtraData = XmlHelper.Deserialize<ImportExtraData>(ctx.Request.Profile.ExtraData);

                    {
                        var mapConverter = new ColumnMapConverter();
                        ctx.ExecuteContext.ColumnMap = mapConverter.ConvertFrom<ColumnMap>(ctx.Request.Profile.ColumnMapping) ?? new ColumnMap();
                    }

                    var files = ctx.Request.Profile.GetImportFiles();

                    if (files.Count == 0)
                        throw new SmartException("No files to import.");

                    if (!HasPermission(ctx))
                        throw new SmartException("You do not have permission to perform the selected import.");

                    ctx.Importer = _importerFactory(ctx.Request.Profile.EntityType);

                    files.ForEach(x => ImportCoreInner(ctx, x));
                }
                catch (Exception exception)
                {
                    ctx.ExecuteContext.Result.AddError(exception);
                }
                finally
                {
                    try
                    {
                        // database context sharing problem: if there are entities in modified state left by the provider due to SaveChanges failure,
                        // then all subsequent SaveChanges would fail too (e.g. IImportProfileService.UpdateImportProfile, IScheduledTaskService.UpdateTask...).
                        // so whatever it is, detach\dispose all what the tracker still has tracked.

                        _services.DbContext.DetachAll(false);
                    }
                    catch (Exception exception)
                    {
                        ctx.ExecuteContext.Result.AddError(exception);
                    }

                    try
                    {
                        SendCompletionEmail(ctx);
                    }
                    catch (Exception exception)
                    {
                        ctx.ExecuteContext.Result.AddError(exception);
                    }

                    try
                    {
                        ctx.ExecuteContext.Result.EndDateUtc = DateTime.UtcNow;

                        LogResult(ctx);
                    }
                    catch (Exception exception)
                    {
                        logger.ErrorsAll(exception);
                    }

                    try
                    {
                        ctx.Request.Profile.ResultInfo = XmlHelper.Serialize(ctx.ExecuteContext.Result.Clone());

                        _importProfileService.UpdateImportProfile(ctx.Request.Profile);
                    }
                    catch (Exception exception)
                    {
                        logger.ErrorsAll(exception);
                    }

                    try
                    {
                        ctx.Request.CustomData.Clear();
                        ctx.Log = null;
                    }
                    catch (Exception exception)
                    {
                        logger.ErrorsAll(exception);
                    }
                }
            }
        }
        protected internal virtual void CallEndpoint(Uri uri)
        {
            if (_shuttingDown)
                return;

            var req = WebHelper.CreateHttpRequestForSafeLocalCall(uri);
            req.Method = "POST";
            req.ContentType = "text/plain";
            req.ContentLength = 0;
            req.Timeout = 10000; // 10 sec.

            string authToken = CreateAuthToken();
            req.Headers.Add("X-AUTH-TOKEN", authToken);

            req.GetResponseAsync().ContinueWith(t =>
            {
                if (t.IsFaulted)
                {
                    HandleException(t.Exception, uri);
                    _errCount++;
                    if (_errCount >= 10)
                    {
                        // 10 failed attempts in succession. Stop the timer!
                        this.Stop();
                        using (var logger = new TraceLogger())
                        {
                            logger.Information("Stopping TaskScheduler sweep timer. Too many failed requests in succession.");
                        }
                    }
                }
                else
                {
                    _errCount = 0;
                    var response = t.Result;

                    //using (var logger = new TraceLogger())
                    //{
                    //	logger.Debug("TaskScheduler Sweep called successfully: {0}".FormatCurrent(response.GetResponseStream().AsString()));
                    //}

                    response.Dispose();
                }
            });
        }
        private void HandleException(AggregateException exception, Uri uri)
        {
            using (var logger = new TraceLogger())
            {
                string msg = "Error while calling TaskScheduler endpoint '{0}'.".FormatInvariant(uri.OriginalString);
                var wex = exception.InnerExceptions.OfType<WebException>().FirstOrDefault();

                if (wex == null)
                {
                    logger.Error(msg, exception.InnerException);
                }
                else if (wex.Response == null)
                {
                    logger.Error(msg, wex);
                }
                else
                {
                    using (var response = wex.Response as HttpWebResponse)
                    {
                        if (response != null)
                        {
                            msg += " HTTP {0}, {1}".FormatCurrent((int)response.StatusCode, response.StatusDescription);
                        }
                        logger.Error(msg);
                    }
                }
            }
        }
        private IPackage FindPackage(out string path)
        {
            path = null;
            var dir = CommonHelper.MapPath(UpdatePackagePath, false);

            if (!Directory.Exists(dir))
                return null;

            var files = Directory.GetFiles(dir, "SmartStore.*.nupkg", SearchOption.TopDirectoryOnly);

            // TODO: allow more than one package in folder and return newest
            if (files == null || files.Length == 0 || files.Length > 1)
                return null;

            IPackage package = null;

            try
            {
                path = files[0];
                package = new ZipPackage(files[0]);
                _logger = CreateLogger(package);
                _logger.Information("Found update package '{0}'".FormatInvariant(package.GetFullName()));
                return package;
            }
            catch { }

            return null;
        }
 protected override void OnDispose(bool disposing)
 {
     if (disposing)
     {
         if (_logger != null)
         {
             _logger.Dispose();
             _logger = null;
         }
     }
 }
Exemple #6
0
        protected internal virtual void CallEndpoint(string url)
        {
            if (_shuttingDown)
                return;

            var req = (HttpWebRequest)WebRequest.Create(url);
            req.UserAgent = "SmartStore.NET";
            req.Method = "POST";
            req.ContentType = "text/plain";
            req.ContentLength = 0;

            string authToken = Guid.NewGuid().ToString();
            _authTokens.TryAdd(authToken, true);
            req.Headers.Add("X-AUTH-TOKEN", authToken);

            req.GetResponseAsync().ContinueWith(t =>
            {
                if (t.IsFaulted)
                {
                    HandleException(t.Exception, url);
                    _errCount++;
                    if (_errCount >= 10)
                    {
                        // 10 failed attempts in succession. Stop the timer!
                        this.Stop();
                        using (var logger = new TraceLogger())
                        {
                            logger.Information("Stopping TaskScheduler sweep timer. Too many failed requests in succession.");
                        }
                    }
                }
                else
                {
                    _errCount = 0;
                    t.Result.Dispose();
                }
            });
        }
        public void StartCreatingFeeds(Func<FeedFileCreationContext, bool> createFeed, string secondFileName = null)
        {
            try
            {
                using (var scope = new DbContextScope(autoDetectChanges: false, validateOnSave: false, forceNoTracking: true))
                {
                    _cachedPathes = null;
                    _cachedCategories = null;

                    var storeService = _ctx.Resolve<IStoreService>();
                    var stores = new List<Store>();

                    if (BaseSettings.StoreId != 0)
                    {
                        var storeById = storeService.GetStoreById(BaseSettings.StoreId);
                        if (storeById != null)
                            stores.Add(storeById);
                    }

                    if (stores.Count == 0)
                    {
                        stores.AddRange(storeService.GetAllStores());
                    }

                    var context = new FeedFileCreationContext
                    {
                        StoreCount = stores.Count,
                        Progress = new Progress<FeedFileCreationProgress>(x =>
                        {
                            AsyncState.Current.Set(x, SystemName);
                        })
                    };

                    foreach (var store in stores)
                    {
                        var feedFile = GetFeedFileByStore(store, secondFileName);
                        if (feedFile != null)
                        {
                            FileSystemHelper.Delete(feedFile.FileTempPath);

                            if (secondFileName.HasValue())
                                FileSystemHelper.Delete(feedFile.CustomProperties["SecondFileTempPath"] as string);

                            using (var stream = new FileStream(feedFile.FileTempPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
                            using (var logger = new TraceLogger(feedFile.LogPath))
                            {
                                context.Stream = stream;
                                context.Logger = logger;
                                context.Store = store;
                                context.FeedFileUrl = feedFile.FileUrl;

                                if (secondFileName.HasValue())
                                    context.SecondFilePath = feedFile.CustomProperties["SecondFileTempPath"] as string;

                                if (!createFeed(context))
                                    break;
                            }

                            FileSystemHelper.Copy(feedFile.FileTempPath, feedFile.FilePath);

                            if (secondFileName.HasValue())
                                FileSystemHelper.Copy(context.SecondFilePath, feedFile.CustomProperties["SecondFilePath"] as string);
                        }
                    }
                }
            }
            finally
            {
                AsyncState.Current.Remove<FeedFileCreationProgress>(SystemName);
            }
        }
        private void ExportCoreOuter(DataExporterContext ctx)
        {
            if (ctx.Request.Profile == null || !ctx.Request.Profile.Enabled)
                return;

            var logPath = ctx.Request.Profile.GetExportLogPath();
            var zipPath = ctx.Request.Profile.GetExportZipPath();

            FileSystemHelper.Delete(logPath);
            FileSystemHelper.Delete(zipPath);
            FileSystemHelper.ClearDirectory(ctx.FolderContent, false);

            using (var logger = new TraceLogger(logPath))
            {
                try
                {
                    ctx.Log = logger;
                    ctx.ExecuteContext.Log = logger;
                    ctx.ProgressInfo = T("Admin.DataExchange.Export.ProgressInfo");

                    if (!ctx.Request.Provider.IsValid())
                        throw new SmartException("Export aborted because the export provider is not valid.");

                    if (!HasPermission(ctx))
                        throw new SmartException("You do not have permission to perform the selected export.");

                    foreach (var item in ctx.Request.CustomData)
                    {
                        ctx.ExecuteContext.CustomProperties.Add(item.Key, item.Value);
                    }

                    if (ctx.Request.Profile.ProviderConfigData.HasValue())
                    {
                        var configInfo = ctx.Request.Provider.Value.ConfigurationInfo;
                        if (configInfo != null)
                        {
                            ctx.ExecuteContext.ConfigurationData = XmlHelper.Deserialize(ctx.Request.Profile.ProviderConfigData, configInfo.ModelType);
                        }
                    }

                    // lazyLoading: false, proxyCreation: false impossible. how to identify all properties of all data levels of all entities
                    // that require manual resolving for now and for future? fragile, susceptible to faults (e.g. price calculation)...
                    using (var scope = new DbContextScope(_dbContext, autoDetectChanges: false, proxyCreation: true, validateOnSave: false, forceNoTracking: true))
                    {
                        ctx.DeliveryTimes = _deliveryTimeService.Value.GetAllDeliveryTimes().ToDictionary(x => x.Id);
                        ctx.QuantityUnits = _quantityUnitService.Value.GetAllQuantityUnits().ToDictionary(x => x.Id);
                        ctx.ProductTemplates = _productTemplateService.Value.GetAllProductTemplates().ToDictionary(x => x.Id, x => x.ViewPath);
                        ctx.CategoryTemplates = _categoryTemplateService.Value.GetAllCategoryTemplates().ToDictionary(x => x.Id, x => x.ViewPath);

                        if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Product)
                        {
                            var allCategories = _categoryService.Value.GetAllCategories(showHidden: true, applyNavigationFilters: false);
                            ctx.Categories = allCategories.ToDictionary(x => x.Id);
                        }

                        if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Order)
                        {
                            ctx.Countries = _countryService.Value.GetAllCountries(true).ToDictionary(x => x.Id, x => x);
                        }

                        if (ctx.Request.Provider.Value.EntityType == ExportEntityType.Customer)
                        {
                            var subscriptionEmails = _subscriptionRepository.Value.TableUntracked
                                .Where(x => x.Active)
                                .Select(x => x.Email)
                                .Distinct()
                                .ToList();

                            ctx.NewsletterSubscriptions = new HashSet<string>(subscriptionEmails, StringComparer.OrdinalIgnoreCase);
                        }

                        var stores = Init(ctx);

                        ctx.ExecuteContext.Language = ToDynamic(ctx, ctx.ContextLanguage);
                        ctx.ExecuteContext.Customer = ToDynamic(ctx, ctx.ContextCustomer);
                        ctx.ExecuteContext.Currency = ToDynamic(ctx, ctx.ContextCurrency);

                        stores.ForEach(x => ExportCoreInner(ctx, x));
                    }

                    if (!ctx.IsPreview && ctx.ExecuteContext.Abort != DataExchangeAbortion.Hard)
                    {
                        if (ctx.IsFileBasedExport)
                        {
                            if (ctx.Request.Profile.CreateZipArchive)
                            {
                                ZipFile.CreateFromDirectory(ctx.FolderContent, zipPath, CompressionLevel.Fastest, false);
                            }

                            if (ctx.Request.Profile.Deployments.Any(x => x.Enabled))
                            {
                                SetProgress(ctx, T("Common.Publishing"));

                                var allDeploymentsSucceeded = Deploy(ctx, zipPath);

                                if (allDeploymentsSucceeded && ctx.Request.Profile.Cleanup)
                                {
                                    logger.Information("Cleaning up export folder");

                                    FileSystemHelper.ClearDirectory(ctx.FolderContent, false);
                                }
                            }
                        }

                        if (ctx.Request.Profile.EmailAccountId != 0 && ctx.Request.Profile.CompletedEmailAddresses.HasValue())
                        {
                            SendCompletionEmail(ctx, zipPath);
                        }
                        else if (ctx.Request.Profile.IsSystemProfile && !ctx.Supports(ExportFeatures.CanOmitCompletionMail))
                        {
                            SendCompletionEmail(ctx, zipPath);
                        }
                    }
                }
                catch (Exception exception)
                {
                    logger.ErrorsAll(exception);
                    ctx.Result.LastError = exception.ToString();
                }
                finally
                {
                    try
                    {
                        if (!ctx.IsPreview && ctx.Request.Profile.Id != 0)
                        {
                            ctx.Request.Profile.ResultInfo = XmlHelper.Serialize(ctx.Result);

                            _exportProfileService.Value.UpdateExportProfile(ctx.Request.Profile);
                        }
                    }
                    catch (Exception exception)
                    {
                        logger.ErrorsAll(exception);
                    }

                    DetachAllEntitiesAndClear(ctx);

                    try
                    {
                        ctx.NewsletterSubscriptions.Clear();
                        ctx.ProductTemplates.Clear();
                        ctx.CategoryTemplates.Clear();
                        ctx.Countries.Clear();
                        ctx.Languages.Clear();
                        ctx.QuantityUnits.Clear();
                        ctx.DeliveryTimes.Clear();
                        ctx.CategoryPathes.Clear();
                        ctx.Categories.Clear();
                        ctx.Stores.Clear();

                        ctx.Request.CustomData.Clear();

                        ctx.ExecuteContext.CustomProperties.Clear();
                        ctx.ExecuteContext.Log = null;
                        ctx.Log = null;
                    }
                    catch (Exception exception)
                    {
                        logger.ErrorsAll(exception);
                    }
                }
            }

            if (ctx.IsPreview || ctx.ExecuteContext.Abort == DataExchangeAbortion.Hard)
                return;

            // post process order entities
            if (ctx.EntityIdsLoaded.Any() && ctx.Request.Provider.Value.EntityType == ExportEntityType.Order && ctx.Projection.OrderStatusChange != ExportOrderStatusChange.None)
            {
                using (var logger = new TraceLogger(logPath))
                {
                    try
                    {
                        int? orderStatusId = null;

                        if (ctx.Projection.OrderStatusChange == ExportOrderStatusChange.Processing)
                            orderStatusId = (int)OrderStatus.Processing;
                        else if (ctx.Projection.OrderStatusChange == ExportOrderStatusChange.Complete)
                            orderStatusId = (int)OrderStatus.Complete;

                        using (var scope = new DbContextScope(_dbContext, false, null, false, false, false, false))
                        {
                            foreach (var chunk in ctx.EntityIdsLoaded.Chunk())
                            {
                                var entities = _orderRepository.Value.Table.Where(x => chunk.Contains(x.Id)).ToList();

                                entities.ForEach(x => x.OrderStatusId = (orderStatusId ?? x.OrderStatusId));

                                _dbContext.SaveChanges();
                            }
                        }

                        logger.Information("Updated order status for {0} order(s).".FormatInvariant(ctx.EntityIdsLoaded.Count()));
                    }
                    catch (Exception exception)
                    {
                        logger.ErrorsAll(exception);
                        ctx.Result.LastError = exception.ToString();
                    }
                }
            }
        }