コード例 #1
0
        /// <summary>Runs the export job.</summary>
        /// <param name="exportJob">The export job.</param>
        /// <param name="result">The result.</param>
        /// <param name="scheduleHistoryItem">The schedule history item.</param>
        public void Export(ExportImportJob exportJob, ExportImportResult result, ScheduleHistoryItem scheduleHistoryItem)
        {
            var exportDto = JsonConvert.DeserializeObject <ExportDto>(exportJob.JobObject);

            if (exportDto == null)
            {
                exportJob.CompletedOnDate = DateUtils.GetDatabaseUtcTime();
                exportJob.JobStatus       = JobStatus.Failed;
                return;
            }

            this.timeoutSeconds = GetTimeoutPerSlot();
            var dbName = Path.Combine(ExportFolder, exportJob.Directory, Constants.ExportDbName);
            var finfo  = new FileInfo(dbName);

            dbName = finfo.FullName;

            var checkpoints = EntitiesController.Instance.GetJobChekpoints(exportJob.JobId);

            // Delete so we start a fresh export database; only if there is no previous checkpoint exists
            if (checkpoints.Count == 0)
            {
                if (finfo.Directory != null && finfo.Directory.Exists)
                {
                    finfo.Directory.Delete(true);
                }

                // Clear all the files in finfo.Directory. Create if doesn't exists.
                finfo.Directory?.Create();
                result.AddSummary("Starting Exporting Repository", finfo.Name);
            }
            else
            {
                if (finfo.Directory != null && finfo.Directory.Exists)
                {
                    result.AddSummary("Resuming Exporting Repository", finfo.Name);
                }
                else
                {
                    scheduleHistoryItem.AddLogNote("Resuming data not found.");
                    result.AddSummary("Resuming data not found.", finfo.Name);
                    return;
                }
            }

            exportJob.JobStatus = JobStatus.InProgress;

            // there must be one parent implementor at least for this to work
            var implementors   = Util.GetPortableImplementors().ToList();
            var parentServices = implementors.Where(imp => string.IsNullOrEmpty(imp.ParentCategory)).ToList();

            implementors = implementors.Except(parentServices).ToList();
            var nextLevelServices = new List <BasePortableService>();
            var includedItems     = GetAllCategoriesToInclude(exportDto, implementors);

            if (includedItems.Count == 0)
            {
                scheduleHistoryItem.AddLogNote("Export NOT Possible");
                scheduleHistoryItem.AddLogNote("<br/>No items selected for exporting");
                result.AddSummary("Export NOT Possible", "No items selected for exporting");
                exportJob.CompletedOnDate = DateUtils.GetDatabaseUtcTime();
                exportJob.JobStatus       = JobStatus.Failed;
                return;
            }

            scheduleHistoryItem.AddLogNote($"<br/><b>SITE EXPORT Preparing Check Points. JOB #{exportJob.JobId}: {exportJob.Name}</b>");
            this.PrepareCheckPoints(exportJob.JobId, parentServices, implementors, includedItems, checkpoints);

            scheduleHistoryItem.AddLogNote($"<br/><b>SITE EXPORT Started. JOB #{exportJob.JobId}: {exportJob.Name}</b>");
            scheduleHistoryItem.AddLogNote($"<br/>Between [{exportDto.FromDateUtc ?? Constants.MinDbTime}] and [{exportDto.ToDateUtc:g}]");
            var firstIteration = true;

            AddJobToCache(exportJob);

            using (var ctx = new ExportImportRepository(dbName))
            {
                ctx.AddSingleItem(exportDto);
                do
                {
                    foreach (var service in parentServices.OrderBy(x => x.Priority))
                    {
                        if (exportJob.IsCancelled)
                        {
                            exportJob.JobStatus = JobStatus.Cancelled;
                            break;
                        }

                        if (implementors.Count > 0)
                        {
                            // collect children for next iteration
                            var children =
                                implementors.Where(imp => service.Category.Equals(imp.ParentCategory, IgnoreCaseComp));
                            nextLevelServices.AddRange(children);
                            implementors = implementors.Except(nextLevelServices).ToList();
                        }

                        if ((firstIteration && includedItems.Any(x => x.Equals(service.Category, IgnoreCaseComp))) ||
                            (!firstIteration && includedItems.Any(x => x.Equals(service.ParentCategory, IgnoreCaseComp))))
                        {
                            var serviceAssembly = service.GetType().Assembly.GetName().Name;
                            service.Result                  = result;
                            service.Repository              = ctx;
                            service.CheckCancelled          = CheckCancelledCallBack;
                            service.CheckPointStageCallback = this.CheckpointCallback;
                            service.CheckPoint              = checkpoints.FirstOrDefault(cp => cp.Category == service.Category && cp.AssemblyName == serviceAssembly);

                            if (service.CheckPoint == null)
                            {
                                service.CheckPoint = new ExportImportChekpoint
                                {
                                    JobId        = exportJob.JobId,
                                    Category     = service.Category,
                                    AssemblyName = serviceAssembly,
                                    StartDate    = DateUtils.GetDatabaseUtcTime(),
                                };

                                // persist the record in db
                                this.CheckpointCallback(service);
                            }
                            else if (service.CheckPoint.StartDate == Null.NullDate)
                            {
                                service.CheckPoint.StartDate = DateUtils.GetDatabaseUtcTime();
                            }

                            try
                            {
                                service.ExportData(exportJob, exportDto);
                            }
                            finally
                            {
                                this.AddLogsToDatabase(exportJob.JobId, result.CompleteLog);
                            }

                            scheduleHistoryItem.AddLogNote("<br/>Exported: " + service.Category);
                        }
                    }

                    firstIteration = false;
                    parentServices = new List <BasePortableService>(nextLevelServices);
                    nextLevelServices.Clear();
                    if (implementors.Count > 0 && parentServices.Count == 0)
                    {
                        // WARN: this is a case where there is a broken parent-children hierarchy
                        //      and/or there are BasePortableService implementations without a known parent.
                        parentServices = implementors;
                        implementors.Clear();
                        scheduleHistoryItem.AddLogNote(
                            "<br/><b>Orphaned services:</b> " + string.Join(",", parentServices.Select(x => x.Category)));
                    }
                }while (parentServices.Count > 0 && !this.TimeIsUp);

                RemoveTokenFromCache(exportJob);
            }

            if (this.TimeIsUp)
            {
                result.AddSummary(
                    $"Job time slot ({this.timeoutSeconds} sec) expired",
                    "Job will resume in the next scheduler iteration");
            }
            else if (exportJob.JobStatus == JobStatus.InProgress)
            {
                // Create Export Summary for manifest file.
                var summary = new ImportExportSummary();
                using (var ctx = new ExportImportRepository(dbName))
                {
                    BaseController.BuildJobSummary(exportJob.Directory, ctx, summary);
                }

                DoPacking(exportJob, dbName);

                // Complete the job.
                exportJob.JobStatus = JobStatus.Successful;
                SetLastJobStartTime(scheduleHistoryItem.ScheduleID, exportJob.CreatedOnDate);

                var exportController = new ExportController();
                var exportFileInfo   = new ExportFileInfo
                {
                    ExportPath = exportJob.Directory,
                    ExportSize = Util.FormatSize(GetExportSize(Path.Combine(ExportFolder, exportJob.Directory))),
                };

                summary.ExportFileInfo = exportFileInfo;
                exportController.CreatePackageManifest(exportJob, exportFileInfo, summary);
            }
        }