Beispiel #1
0
        public void ExportBackground(ExportDataRequest request, ExportPushNotification notification, IJobCancellationToken cancellationToken, PerformContext context)
        {
            void progressCallback(ExportProgressInfo x)
            {
                notification.Patch(x);
                notification.JobId = context.BackgroundJob.Id;
                _pushNotificationManager.Upsert(notification);
            }

            try
            {
                var localTmpFolder = HostingEnvironment.MapPath(_defaultExportFolder);
                var fileName       = Path.Combine(localTmpFolder, string.Format(FileNameTemplate, DateTime.UtcNow));

                // Do not like provider creation here to get file extension, maybe need to pass created provider to Exporter.
                // Create stream inside Exporter is not good as it is not Exporter resposibility to decide where to write.
                var provider = _exportProviderFactory.CreateProvider(request);

                if (!string.IsNullOrEmpty(provider.ExportedFileExtension))
                {
                    fileName = Path.ChangeExtension(string.Format(FileNameTemplate, DateTime.UtcNow), provider.ExportedFileExtension);
                }

                var localTmpPath = Path.Combine(localTmpFolder, fileName);

                if (!Directory.Exists(localTmpFolder))
                {
                    Directory.CreateDirectory(localTmpFolder);
                }

                if (File.Exists(localTmpPath))
                {
                    File.Delete(localTmpPath);
                }

                //Import first to local tmp folder because Azure blob storage doesn't support some special file access mode
                using (var stream = File.OpenWrite(localTmpPath))
                {
                    _dataExporter.Export(stream, request, progressCallback, new JobCancellationTokenWrapper(cancellationToken));
                    notification.DownloadUrl = $"api/export/download/{fileName}";
                }
            }
            catch (JobAbortedException)
            {
                //do nothing
            }
            catch (Exception ex)
            {
                notification.Errors.Add(ex.ExpandExceptionMessage());
            }
            finally
            {
                notification.Description = "Export finished";
                notification.Finished    = DateTime.UtcNow;
                _pushNotificationManager.Upsert(notification);
            }
        }
        public async Task ExportBackgroundAsync(ExportDataRequest request, ExportPushNotification notification, IJobCancellationToken cancellationToken, PerformContext context)
        {
            void progressCallback(ExportProgressInfo x)
            {
                notification.Patch(x);
                notification.JobId = context.BackgroundJob.Id;
                _pushNotificationManager.Send(notification);
            }

            try
            {
                if (string.IsNullOrEmpty(_platformOptions.DefaultExportFolder))
                {
                    throw new PlatformException($"{nameof(_platformOptions.DefaultExportFolder)} should be set.");
                }

                var fileName = string.Format(FileNameTemplate, DateTime.UtcNow);

                // Do not like provider creation here to get file extension, maybe need to pass created provider to Exporter.
                // Create stream inside Exporter is not good as it is not Exporter resposibility to decide where to write.
                var provider = _exportProviderFactory.CreateProvider(request);

                if (!string.IsNullOrEmpty(provider.ExportedFileExtension))
                {
                    fileName = Path.ChangeExtension(fileName, provider.ExportedFileExtension);
                }

                var url = UrlHelperExtensions.Combine(_platformOptions.DefaultExportFolder, fileName);
                using (var blobStream = _blobStorageProvider.OpenWrite(url))
                {
                    _dataExporter.Export(blobStream, request, progressCallback, new JobCancellationTokenWrapper(cancellationToken));
                }

                notification.DownloadUrl = _blobUrlResolver.GetAbsoluteUrl(url);
            }
            catch (JobAbortedException)
            {
                //do nothing
            }
            catch (Exception ex)
            {
                notification.Errors.Add(ex.ExpandExceptionMessage());
            }
            finally
            {
                notification.Description = "Export finished";
                notification.Finished    = DateTime.UtcNow;
                await _pushNotificationManager.SendAsync(notification);
            }
        }
        public void Export(Stream stream, ExportDataRequest request, Action <ExportProgressInfo> progressCallback, ICancellationToken token)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            token.ThrowIfCancellationRequested();

            var exportedTypeDefinition = _exportTypesResolver.ResolveExportedTypeDefinition(request.ExportTypeName);
            var pagedDataSource        = (exportedTypeDefinition.DataSourceFactory ?? throw new ArgumentNullException(nameof(ExportedTypeDefinition.DataSourceFactory))).Create(request.DataQuery);

            var completedMessage = $"Export completed";
            var totalCount       = pagedDataSource.GetTotalCount();
            var exportedCount    = 0;
            var exportProgress   = new ExportProgressInfo()
            {
                ProcessedCount = 0,
                TotalCount     = totalCount,
                Description    = "Export has started",
            };

            progressCallback(exportProgress);

            try
            {
                exportProgress.Description = "Creating provider…";
                progressCallback(exportProgress);

                using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true)
                {
                    AutoFlush = true
                })
                    using (var exportProvider = _exportProviderFactory.CreateProvider(request))
                    {
                        var needTabularData = exportProvider.IsTabular;

                        if (needTabularData && !exportedTypeDefinition.IsTabularExportSupported)
                        {
                            throw new NotSupportedException($"Provider \"{exportProvider.TypeName}\" does not support tabular export.");
                        }

                        exportProgress.Description = "Fetching…";
                        progressCallback(exportProgress);

                        while (pagedDataSource.Fetch())
                        {
                            token.ThrowIfCancellationRequested();

                            var objectBatch = pagedDataSource.Items;

                            foreach (var obj in objectBatch)
                            {
                                try
                                {
                                    var preparedObject = obj.Clone() as IExportable;

                                    request.DataQuery.FilterProperties(preparedObject);

                                    if (needTabularData)
                                    {
                                        preparedObject = (preparedObject as ITabularConvertible)?.ToTabular() ??
                                                         throw new NotSupportedException($"Object should be {nameof(ITabularConvertible)} to be exported using tabular provider.");
                                    }

                                    exportProvider.WriteRecord(writer, preparedObject);
                                }
                                catch (Exception e)
                                {
                                    exportProgress.Errors.Add(e.Message);
                                    progressCallback(exportProgress);
                                }
                                exportedCount++;
                            }

                            exportProgress.ProcessedCount = exportedCount;

                            if (exportedCount != totalCount)
                            {
                                exportProgress.Description = $"{exportedCount} out of {totalCount} have been exported.";
                                progressCallback(exportProgress);
                            }
                        }
                    }
            }
            catch (Exception e)
            {
                exportProgress.Errors.Add(e.Message);
            }
            finally
            {
                if (exportProgress.Errors.Count > 0)
                {
                    completedMessage = $"Export completed with errors";
                }

                exportProgress.Description = $"{completedMessage}: {exportedCount} out of {totalCount} have been exported.";
                progressCallback(exportProgress);
            }
        }