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