Skip to content

Commit

Permalink
Merge pull request #354 from shesha-io/d/user/jonathan_sra_changes
Browse files Browse the repository at this point in the history
Added file import and new attribute on import results
  • Loading branch information
jonathan-boxfusion committed Jul 3, 2023
2 parents 41eb541 + b377e8a commit 2f0d845
Show file tree
Hide file tree
Showing 7 changed files with 525 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,8 @@ public class ImportResult : FullPowerEntity
/// Type of the data source
/// </summary>
public virtual RefListImportSourceType? SourceType { get; set; }

[StringLength(300)]
public virtual string LogFilePath { get; set; }
}
}
19 changes: 19 additions & 0 deletions shesha-core/src/Shesha.Framework/Migrations/M20230629205600.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using FluentMigrator;
using Shesha.FluentMigrator;

namespace Shesha.Migrations
{
[Migration(20230629205600)]
public class M20230629205600 : Migration
{
public override void Down()
{
throw new System.NotImplementedException();
}

public override void Up()
{
Alter.Table("Frwk_ImportResults").AddColumn("LogFilePath").AsString(300).Nullable();
}
}
}
9 changes: 9 additions & 0 deletions shesha-core/src/Shesha.Import/Dto/StartImportInput.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Microsoft.AspNetCore.Http;

namespace Shesha.Import.Dto
{
public class StartImportInput
{
public IFormFile File { get; set; }
}
}
11 changes: 11 additions & 0 deletions shesha-core/src/Shesha.Import/IImport.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
using System.Threading;
using Shesha.Domain;

namespace Shesha.Import
{
public interface IImport<T> where T : ImportResult
{
void Import(Guid importResultId, CancellationToken cancellationToken);
}
}
122 changes: 122 additions & 0 deletions shesha-core/src/Shesha.Import/ImportApplicationService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Transactions;
using Abp.Application.Services;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Runtime.Validation;
using Hangfire;
using Microsoft.AspNetCore.Mvc;
using Shesha.Domain;
using Shesha.Domain.Enums;
using Shesha.Exceptions;
using Shesha.Import.Dto;
using Shesha.Services;
using Shesha.Utilities;

namespace Shesha.Import
{
public abstract class ImportApplicationService<TImport, TResult> : ApplicationService
where TResult : ImportResult, new()
where TImport : IImport<TResult>
{
protected IStoredFileService _fileService;
protected IRepository<TResult, Guid> _importResultsRepository;
protected readonly IUnitOfWorkManager _unitOfWorkManager;

protected ImportApplicationService(IStoredFileService fileService, IRepository<TResult, Guid> importResultsRepository, IUnitOfWorkManager unitOfWorkManager)
{
_fileService = fileService;
_importResultsRepository = importResultsRepository;
_unitOfWorkManager = unitOfWorkManager;
}

[HttpPost]
[Consumes("multipart/form-data")]
[DisableRequestSizeLimit]
public virtual async Task<bool> StartImportAsync([FromForm] StartImportInput input)
{
try
{
var validationResults = new List<ValidationResult>();

if (input.File == null)
validationResults.Add(new ValidationResult("File not selected"));

if (validationResults.Any())
throw new AbpValidationException("Failed to start import", validationResults);

var fileName = input.File.FileName.CleanupFileName();
await using (var fileStream = input.File.OpenReadStream())
{
var startResult = await StartAsync(fileName, fileStream);
return startResult.IsSuccess;
}
}
catch (Exception e)
{
Logger.Error(e.Message, e);
throw;
}
}

protected async Task<ImportStartResult> StartAsync(string fileName, Stream stream)
{
var result = new ImportStartResult();
/*
todo: implement `in progress` check
note: it should support multitenancy
if (SchedulerUtility.IsJobInProgress(typeof(TJ)))
{
errorMessage = "Import already in progress";
return false;
}
*/

// Create log file
var logFileName = Path.ChangeExtension(fileName, ".log");

var importResultId = Guid.NewGuid();

// Save info about the import to the DB (including imported file and log file)
using (var uow = _unitOfWorkManager.Begin(TransactionScopeOption.RequiresNew))
{
var importResult = Activator.CreateInstance<TResult>();
importResult.Id = importResultId;
importResult.SourceType = RefListImportSourceType.File;
importResult.StartedOn = DateTime.Now;
importResult.ImportedFile = await _fileService.SaveFileAsync(stream, fileName);
importResult.ImportedFileMD5 = FileHelper.GetMD5(stream);
//importResult.LogFile = logFileName;

await _importResultsRepository.InsertAsync(importResult);
await uow.CompleteAsync();
}

try
{
BackgroundJob.Enqueue<TImport>(i => i.Import(importResultId, CancellationToken.None));

result.IsSuccess = true;
}
catch (Exception e)
{
result.ErrorMessage = e.FullMessage();
result.IsSuccess = false;
}

return result;
}
}

public class ImportStartResult
{
public bool IsSuccess { get; set; }
public string ErrorMessage { get; set; }
}
}
69 changes: 69 additions & 0 deletions shesha-core/src/Shesha.Import/ImportJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Microsoft.AspNetCore.SignalR;
using Shesha.Domain;
using Shesha.Exceptions;
using Shesha.Scheduler;
using Shesha.Scheduler.Domain;
using Shesha.Scheduler.SignalR;
using Shesha.Services;

namespace Shesha.Import
{
//public class ImportJob<TI, TR> : ScheduledJobBase where TI : IImport<TR> where TR : ImportResult
//{
// private readonly IIocResolver _iocResolver;
// protected readonly IRepository<TR, Guid> _resultRepository;
// protected readonly IStoredFileService _fileService;

// public ImportJob(IIocResolver iocResolver, IRepository<ScheduledJob, Guid> jobRepository, IRepository<ScheduledJobTrigger, Guid> triggerRepository, IRepository<ScheduledJobExecution, Guid> jobExecutionRepository, IStoredFileService fileService, IHubContext<SignalrAppenderHub> hubContext, IUnitOfWorkManager unitOfWorkManager, IRepository<TR, Guid> resultRepository) : base(jobRepository, triggerRepository, jobExecutionRepository, fileService, hubContext, unitOfWorkManager)
// {
// _iocResolver = iocResolver;
// _resultRepository = resultRepository;
// _fileService = fileService;
// }

// public override void DoExecuteAsync(CancellationToken cancellationToken)
// {
// try
// {
// Log.Info("Import job started");

// Guid? importResultId = null;

// var result = importResultId != null
// ? _resultRepository.Get(importResultId.Value)
// : null;
// if (result == null)
// throw new Exception($"Import results record not found. id = {importResultId}");

// var importer = _iocResolver.Resolve<TI>(new {logger = Log, logGroupName = Name});

// /*
// importer.Import(result, CancellationToken, out var errorMessage);

// if (string.IsNullOrWhiteSpace(errorMessage))
// Log.Info("Import successfully started");
// else
// Log.Warn("Import process has not been started: " + errorMessage);
// */
// }
// catch (Exception e)
// {
// e.LogToElmah();
// Log.FatalFormat("Fatal Error was occured during import process: {0}", e.Message);
// }
// }

// protected static List<string> GetLocalFiles(string path, string wildcard, bool scanSubfolders)
// {
// return Directory.GetFiles(path, wildcard, scanSubfolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).ToList();
// }
//}
}
Loading

0 comments on commit 2f0d845

Please sign in to comment.