add Job Tasks to enable the execution of adhoc asynchronous site-based workloads
This commit is contained in:
63
Oqtane.Server/Controllers/JobTaskController.cs
Normal file
63
Oqtane.Server/Controllers/JobTaskController.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.Infrastructure;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Repository;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route(ControllerRoutes.ApiRoute)]
|
||||
public class JobTaskController : Controller
|
||||
{
|
||||
private readonly IJobTaskRepository _jobTasks;
|
||||
private readonly ILogManager _logger;
|
||||
private readonly Alias _alias;
|
||||
|
||||
public JobTaskController(IJobTaskRepository jobTasks, ILogManager logger, ITenantManager tenantManager)
|
||||
{
|
||||
_jobTasks = jobTasks;
|
||||
_logger = logger;
|
||||
_alias = tenantManager.GetAlias();
|
||||
}
|
||||
|
||||
// GET api/<controller>/5
|
||||
[HttpGet("{id}")]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public JobTask Get(int id)
|
||||
{
|
||||
var jobTask = _jobTasks.GetJobTask(id);
|
||||
if (jobTask.SiteId == _alias.SiteId)
|
||||
{
|
||||
return jobTask;
|
||||
}
|
||||
else
|
||||
{
|
||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// POST api/<controller>
|
||||
[HttpPost]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public JobTask Post([FromBody] JobTask jobTask)
|
||||
{
|
||||
if (ModelState.IsValid && jobTask.SiteId == _alias.SiteId)
|
||||
{
|
||||
jobTask.IsCompleted = false;
|
||||
jobTask = _jobTasks.AddJobTask(jobTask);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Job Task Added {JobTask}", jobTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Job Task Post Attempt {JobTask}", jobTask);
|
||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
jobTask = null;
|
||||
}
|
||||
return jobTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -418,42 +418,6 @@ namespace Oqtane.Controllers
|
||||
return requirements;
|
||||
}
|
||||
|
||||
// POST api/<controller>/import?siteid=x&fileid=y¬ify=z
|
||||
[HttpPost("import")]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public async Task<Dictionary<string, string>> Import(string siteid, string fileid, string notify)
|
||||
{
|
||||
if (int.TryParse(siteid, out int SiteId) && SiteId == _tenantManager.GetAlias().SiteId && int.TryParse(fileid, out int FileId) && bool.TryParse(notify, out bool Notify))
|
||||
{
|
||||
var file = _files.GetFile(FileId);
|
||||
if (file != null)
|
||||
{
|
||||
if (_userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.PermissionList))
|
||||
{
|
||||
return await _userManager.ImportUsers(SiteId, _files.GetFilePath(file), Notify);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized User Import Attempt {SiteId} {FileId}", siteid, fileid);
|
||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Import File Does Not Exist {SiteId} {FileId}", siteid, fileid);
|
||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized User Import Attempt {SiteId} {FileId}", siteid, fileid);
|
||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// GET: api/<controller>/passkey?id=x
|
||||
[HttpGet("passkey")]
|
||||
[Authorize]
|
||||
|
||||
@@ -214,6 +214,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||
services.AddScoped<ILogService, LogService>();
|
||||
services.AddScoped<IJobService, JobService>();
|
||||
services.AddScoped<IJobLogService, JobLogService>();
|
||||
services.AddScoped<IJobTaskService, JobTaskService>();
|
||||
services.AddScoped<INotificationService, Oqtane.Services.NotificationService>();
|
||||
services.AddScoped<IFolderService, FolderService>();
|
||||
services.AddScoped<IFileService, FileService>();
|
||||
@@ -274,6 +275,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||
services.AddTransient<ILogRepository, LogRepository>();
|
||||
services.AddTransient<IJobRepository, JobRepository>();
|
||||
services.AddTransient<IJobLogRepository, JobLogRepository>();
|
||||
services.AddTransient<IJobTaskRepository, JobTaskRepository>();
|
||||
services.AddTransient<INotificationRepository, NotificationRepository>();
|
||||
services.AddTransient<IFolderRepository, FolderRepository>();
|
||||
services.AddTransient<IFileRepository, FileRepository>();
|
||||
|
||||
13
Oqtane.Server/Infrastructure/Interfaces/IJobTask.cs
Normal file
13
Oqtane.Server/Infrastructure/Interfaces/IJobTask.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public interface IJobTask
|
||||
{
|
||||
string ExecuteTask(IServiceProvider provider, Site site, string parameters);
|
||||
|
||||
Task<string> ExecuteTaskAsync(IServiceProvider provider, Site site, string parameters);
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Modules;
|
||||
using Oqtane.Repository;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public class GlobalReplaceJob : HostedServiceBase
|
||||
{
|
||||
public GlobalReplaceJob(IServiceScopeFactory serviceScopeFactory) : base(serviceScopeFactory)
|
||||
{
|
||||
Name = "Global Replace Job";
|
||||
Frequency = "m"; // run every minute.
|
||||
Interval = 1;
|
||||
IsEnabled = true;
|
||||
}
|
||||
|
||||
public override async Task<string> ExecuteJobAsync(IServiceProvider provider)
|
||||
{
|
||||
string log = "";
|
||||
|
||||
// get services
|
||||
var siteRepository = provider.GetRequiredService<ISiteRepository>();
|
||||
var settingRepository = provider.GetRequiredService<ISettingRepository>();
|
||||
var tenantManager = provider.GetRequiredService<ITenantManager>();
|
||||
var pageRepository = provider.GetRequiredService<IPageRepository>();
|
||||
var pageModuleRepository = provider.GetRequiredService<IPageModuleRepository>();
|
||||
|
||||
var sites = siteRepository.GetSites().ToList();
|
||||
foreach (var site in sites.Where(item => !item.IsDeleted))
|
||||
{
|
||||
log += $"Processing Site: {site.Name}<br />";
|
||||
|
||||
// get global replace items in order by date/time submitted
|
||||
var globalReplaceSettings = settingRepository.GetSettings(EntityNames.Site, site.SiteId)
|
||||
.Where(item => item.SettingName.StartsWith("GlobalReplace_"))
|
||||
.OrderBy(item => item.SettingName);
|
||||
|
||||
if (globalReplaceSettings != null && globalReplaceSettings.Any())
|
||||
{
|
||||
// get first item
|
||||
var globalReplace = JsonSerializer.Deserialize<GlobalReplace>(globalReplaceSettings.First().SettingValue);
|
||||
|
||||
var find = globalReplace.Find;
|
||||
var replace = globalReplace.Replace;
|
||||
var comparisonType = (globalReplace.CaseSensitive) ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
|
||||
|
||||
log += $"Replacing: '{find}' With: '{replace}' Case Sensitive: {globalReplace.CaseSensitive}<br />";
|
||||
|
||||
var tenantId = tenantManager.GetTenant().TenantId;
|
||||
tenantManager.SetAlias(tenantId, site.SiteId);
|
||||
|
||||
var changed = false;
|
||||
if (site.Name != null && site.Name.Contains(find, comparisonType))
|
||||
{
|
||||
site.Name = site.Name.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (site.HeadContent != null && site.HeadContent.Contains(find, comparisonType))
|
||||
{
|
||||
site.HeadContent = site.HeadContent.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (site.BodyContent != null && site.BodyContent.Contains(find, comparisonType))
|
||||
{
|
||||
site.BodyContent = site.BodyContent.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (changed && globalReplace.Site)
|
||||
{
|
||||
siteRepository.UpdateSite(site);
|
||||
log += $"Site Updated<br />";
|
||||
}
|
||||
|
||||
var pages = pageRepository.GetPages(site.SiteId);
|
||||
var pageModules = pageModuleRepository.GetPageModules(site.SiteId);
|
||||
|
||||
// iterate pages
|
||||
foreach (var page in pages)
|
||||
{
|
||||
// page properties
|
||||
changed = false;
|
||||
if (page.Name != null && page.Name.Contains(find, comparisonType))
|
||||
{
|
||||
page.Name = page.Name.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (page.Title != null && page.Title.Contains(find, comparisonType))
|
||||
{
|
||||
page.Title = page.Title.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (page.HeadContent != null && page.HeadContent.Contains(find, comparisonType))
|
||||
{
|
||||
page.HeadContent = page.HeadContent.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (page.BodyContent != null && page.BodyContent.Contains(find, comparisonType))
|
||||
{
|
||||
page.BodyContent = page.BodyContent.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (changed && globalReplace.Pages)
|
||||
{
|
||||
pageRepository.UpdatePage(page);
|
||||
log += $"Page Updated: /{page.Path}<br />";
|
||||
}
|
||||
|
||||
foreach (var pageModule in pageModules.Where(item => item.PageId == page.PageId))
|
||||
{
|
||||
// pagemodule properties
|
||||
changed = false;
|
||||
if (pageModule.Title != null && pageModule.Title.Contains(find, comparisonType))
|
||||
{
|
||||
pageModule.Title = pageModule.Title.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (pageModule.Header != null && pageModule.Header.Contains(find, comparisonType))
|
||||
{
|
||||
pageModule.Header = pageModule.Header.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (pageModule.Footer != null && pageModule.Footer.Contains(find, comparisonType))
|
||||
{
|
||||
pageModule.Footer = pageModule.Footer.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (changed && globalReplace.Modules)
|
||||
{
|
||||
pageModuleRepository.UpdatePageModule(pageModule);
|
||||
log += $"Module Updated: {pageModule.Title} - /{page.Path}<br />";
|
||||
}
|
||||
|
||||
// module content
|
||||
if (pageModule.Module.ModuleDefinition != null && pageModule.Module.ModuleDefinition.ServerManagerType != "")
|
||||
{
|
||||
Type moduleType = Type.GetType(pageModule.Module.ModuleDefinition.ServerManagerType);
|
||||
if (moduleType != null && moduleType.GetInterface(nameof(IPortable)) != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// module content
|
||||
var moduleObject = ActivatorUtilities.CreateInstance(provider, moduleType);
|
||||
var moduleContent = ((IPortable)moduleObject).ExportModule(pageModule.Module);
|
||||
if (!string.IsNullOrEmpty(moduleContent) && moduleContent.Contains(find, comparisonType) && globalReplace.Content)
|
||||
{
|
||||
moduleContent = moduleContent.Replace(find, replace, comparisonType);
|
||||
((IPortable)moduleObject).ImportModule(pageModule.Module, moduleContent, pageModule.Module.ModuleDefinition.Version);
|
||||
log += $"Module Content Updated: {pageModule.Title} - /{page.Path}<br />";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log += $"Error Processing Module {pageModule.Module.ModuleDefinition.Name} - {ex.Message}<br />";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove global replace setting to prevent reprocessing
|
||||
settingRepository.DeleteSetting(EntityNames.Site, globalReplaceSettings.First().SettingId);
|
||||
}
|
||||
else
|
||||
{
|
||||
log += $"No Criteria Provided<br />";
|
||||
}
|
||||
}
|
||||
|
||||
return log;
|
||||
}
|
||||
}
|
||||
}
|
||||
83
Oqtane.Server/Infrastructure/Jobs/TaskJob.cs
Normal file
83
Oqtane.Server/Infrastructure/Jobs/TaskJob.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public class TaskJob : HostedServiceBase
|
||||
{
|
||||
public TaskJob(IServiceScopeFactory serviceScopeFactory) : base(serviceScopeFactory)
|
||||
{
|
||||
Name = "Task Job";
|
||||
Frequency = "m"; // run every minute
|
||||
Interval = 1;
|
||||
IsEnabled = true;
|
||||
}
|
||||
|
||||
// job is executed for each tenant in installation
|
||||
public override async Task<string> ExecuteJobAsync(IServiceProvider provider)
|
||||
{
|
||||
var log = "";
|
||||
|
||||
var tenantManager = provider.GetRequiredService<ITenantManager>();
|
||||
var tenant = tenantManager.GetTenant();
|
||||
|
||||
// iterate through sites for current tenant
|
||||
var siteRepository = provider.GetRequiredService<ISiteRepository>();
|
||||
var sites = siteRepository.GetSites().ToList();
|
||||
foreach (var site in sites.Where(item => !item.IsDeleted))
|
||||
{
|
||||
log += $"Processing Site: {site.Name}<br />";
|
||||
|
||||
// get incomplete tasks for site
|
||||
var jobTaskRepository = provider.GetRequiredService<IJobTaskRepository>();
|
||||
var tasks = jobTaskRepository.GetJobTasks(site.SiteId).ToList();
|
||||
if (tasks != null && tasks.Any())
|
||||
{
|
||||
foreach (var task in tasks)
|
||||
{
|
||||
log += $"Executing Task: {task.Name}<br />";
|
||||
|
||||
Type taskType = Type.GetType(task.Type);
|
||||
if (taskType != null && taskType.GetInterface(nameof(IJobTask)) != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
tenantManager.SetAlias(tenant.TenantId, site.SiteId);
|
||||
|
||||
var taskObject = ActivatorUtilities.CreateInstance(provider, taskType);
|
||||
var taskLog = ((IJobTask)taskObject).ExecuteTask(provider, site, task.Parameters);
|
||||
taskLog += await ((IJobTask)taskObject).ExecuteTaskAsync(provider, site, task.Parameters);
|
||||
|
||||
task.Status = taskLog;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
task.Status = "Error: " + ex.Message;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
task.Status = $"Error: Task {task.Name} Has An Invalid Type {task.Type}<br />";
|
||||
}
|
||||
|
||||
// update task
|
||||
task.IsCompleted = true;
|
||||
jobTaskRepository.UpdateJobTask(task);
|
||||
|
||||
log += task.Status + "<br />";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log += "No Tasks To Execute<br />";
|
||||
}
|
||||
}
|
||||
|
||||
return log;
|
||||
}
|
||||
}
|
||||
}
|
||||
150
Oqtane.Server/Infrastructure/Tasks/GlobalReplaceTask.cs
Normal file
150
Oqtane.Server/Infrastructure/Tasks/GlobalReplaceTask.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Modules;
|
||||
using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public class GlobalReplaceTask : JobTaskBase
|
||||
{
|
||||
public override string ExecuteTask(IServiceProvider provider, Site site, string parameters)
|
||||
{
|
||||
string log = "";
|
||||
|
||||
// get services
|
||||
var siteRepository = provider.GetRequiredService<ISiteRepository>();
|
||||
var pageRepository = provider.GetRequiredService<IPageRepository>();
|
||||
var pageModuleRepository = provider.GetRequiredService<IPageModuleRepository>();
|
||||
|
||||
if (!string.IsNullOrEmpty(parameters))
|
||||
{
|
||||
// get parameters
|
||||
var globalReplace = JsonSerializer.Deserialize<GlobalReplace>(parameters);
|
||||
|
||||
var find = globalReplace.Find;
|
||||
var replace = globalReplace.Replace;
|
||||
var comparisonType = (globalReplace.CaseSensitive) ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
|
||||
|
||||
log += $"Replacing: '{find}' With: '{replace}' Case Sensitive: {globalReplace.CaseSensitive}<br />";
|
||||
|
||||
// site properties
|
||||
site = siteRepository.GetSite(site.SiteId);
|
||||
var changed = false;
|
||||
if (site.Name != null && site.Name.Contains(find, comparisonType))
|
||||
{
|
||||
site.Name = site.Name.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (site.HeadContent != null && site.HeadContent.Contains(find, comparisonType))
|
||||
{
|
||||
site.HeadContent = site.HeadContent.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (site.BodyContent != null && site.BodyContent.Contains(find, comparisonType))
|
||||
{
|
||||
site.BodyContent = site.BodyContent.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (changed && globalReplace.Site)
|
||||
{
|
||||
siteRepository.UpdateSite(site);
|
||||
log += $"Site Updated<br />";
|
||||
}
|
||||
|
||||
var pages = pageRepository.GetPages(site.SiteId).ToList();
|
||||
var pageModules = pageModuleRepository.GetPageModules(site.SiteId).ToList();
|
||||
|
||||
// iterate pages
|
||||
foreach (var page in pages)
|
||||
{
|
||||
// page properties
|
||||
changed = false;
|
||||
if (page.Name != null && page.Name.Contains(find, comparisonType))
|
||||
{
|
||||
page.Name = page.Name.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (page.Title != null && page.Title.Contains(find, comparisonType))
|
||||
{
|
||||
page.Title = page.Title.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (page.HeadContent != null && page.HeadContent.Contains(find, comparisonType))
|
||||
{
|
||||
page.HeadContent = page.HeadContent.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (page.BodyContent != null && page.BodyContent.Contains(find, comparisonType))
|
||||
{
|
||||
page.BodyContent = page.BodyContent.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (changed && globalReplace.Pages)
|
||||
{
|
||||
pageRepository.UpdatePage(page);
|
||||
log += $"Page Updated: /{page.Path}<br />";
|
||||
}
|
||||
|
||||
foreach (var pageModule in pageModules.Where(item => item.PageId == page.PageId))
|
||||
{
|
||||
// module properties
|
||||
changed = false;
|
||||
if (pageModule.Title != null && pageModule.Title.Contains(find, comparisonType))
|
||||
{
|
||||
pageModule.Title = pageModule.Title.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (pageModule.Header != null && pageModule.Header.Contains(find, comparisonType))
|
||||
{
|
||||
pageModule.Header = pageModule.Header.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (pageModule.Footer != null && pageModule.Footer.Contains(find, comparisonType))
|
||||
{
|
||||
pageModule.Footer = pageModule.Footer.Replace(find, replace, comparisonType);
|
||||
changed = true;
|
||||
}
|
||||
if (changed && globalReplace.Modules)
|
||||
{
|
||||
pageModuleRepository.UpdatePageModule(pageModule);
|
||||
log += $"Module Updated: {pageModule.Title} - /{page.Path}<br />";
|
||||
}
|
||||
|
||||
// module content
|
||||
if (pageModule.Module.ModuleDefinition != null && pageModule.Module.ModuleDefinition.ServerManagerType != "")
|
||||
{
|
||||
Type moduleType = Type.GetType(pageModule.Module.ModuleDefinition.ServerManagerType);
|
||||
if (moduleType != null && moduleType.GetInterface(nameof(IPortable)) != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var moduleObject = ActivatorUtilities.CreateInstance(provider, moduleType);
|
||||
var moduleContent = ((IPortable)moduleObject).ExportModule(pageModule.Module);
|
||||
if (!string.IsNullOrEmpty(moduleContent) && moduleContent.Contains(find, comparisonType) && globalReplace.Content)
|
||||
{
|
||||
moduleContent = moduleContent.Replace(find, replace, comparisonType);
|
||||
((IPortable)moduleObject).ImportModule(pageModule.Module, moduleContent, pageModule.Module.ModuleDefinition.Version);
|
||||
log += $"Module Content Updated: {pageModule.Title} - /{page.Path}<br />";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log += $"Error Processing Module {pageModule.Module.ModuleDefinition.Name} - {ex.Message}<br />";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log += $"No Criteria Provided<br />";
|
||||
}
|
||||
|
||||
return log;
|
||||
}
|
||||
}
|
||||
}
|
||||
48
Oqtane.Server/Infrastructure/Tasks/ImportUsersTask.cs
Normal file
48
Oqtane.Server/Infrastructure/Tasks/ImportUsersTask.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Oqtane.Managers;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public class ImportUsersTask : JobTaskBase
|
||||
{
|
||||
public override async Task<string> ExecuteTaskAsync(IServiceProvider provider, Site site, string parameters)
|
||||
{
|
||||
string log = "";
|
||||
|
||||
if (!string.IsNullOrEmpty(parameters) && parameters.Contains(":"))
|
||||
{
|
||||
var fileId = int.Parse(parameters.Split(':')[0]);
|
||||
var notify = bool.Parse(parameters.Split(':')[1]);
|
||||
|
||||
var fileRepository = provider.GetRequiredService<IFileRepository>();
|
||||
var userManager = provider.GetRequiredService<IUserManager>();
|
||||
|
||||
var file = fileRepository.GetFile(fileId);
|
||||
if (file != null)
|
||||
{
|
||||
var filePath = fileRepository.GetFilePath(file);
|
||||
log += $"Importing Users From {filePath}<br />";
|
||||
var result = await userManager.ImportUsers(site.SiteId, filePath, notify);
|
||||
if (result["Success"] == "True")
|
||||
{
|
||||
log += $"{result["Users"]} Users Imported<br />";
|
||||
}
|
||||
else
|
||||
{
|
||||
log += $"User Import Failed<br />";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log += $"Import Users FileId {fileId} Does Not Exist<br />";
|
||||
}
|
||||
}
|
||||
|
||||
return log;
|
||||
}
|
||||
}
|
||||
}
|
||||
19
Oqtane.Server/Infrastructure/Tasks/JobTaskBase.cs
Normal file
19
Oqtane.Server/Infrastructure/Tasks/JobTaskBase.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public class JobTaskBase : IJobTask
|
||||
{
|
||||
public virtual string ExecuteTask(IServiceProvider provider, Site site, string parameters)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public virtual Task<string> ExecuteTaskAsync(IServiceProvider provider, Site site, string parameters)
|
||||
{
|
||||
return Task.FromResult(string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Migrations.Operations;
|
||||
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
|
||||
using Oqtane.Databases.Interfaces;
|
||||
using Oqtane.Interfaces;
|
||||
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
|
||||
namespace Oqtane.Migrations.EntityBuilders
|
||||
{
|
||||
public class JobTaskEntityBuilder : AuditableBaseEntityBuilder<JobTaskEntityBuilder>
|
||||
{
|
||||
private const string _entityTableName = "JobTask";
|
||||
private readonly PrimaryKey<JobTaskEntityBuilder> _primaryKey = new("PK_JobTask", x => x.JobTaskId);
|
||||
private readonly ForeignKey<JobTaskEntityBuilder> _siteForeignKey = new("FK_JobTask_Site", x => x.SiteId, "Site", "SiteId", ReferentialAction.Cascade);
|
||||
|
||||
public JobTaskEntityBuilder(MigrationBuilder migrationBuilder, IDatabase database) : base(migrationBuilder, database)
|
||||
{
|
||||
EntityTableName = _entityTableName;
|
||||
PrimaryKey = _primaryKey;
|
||||
ForeignKeys.Add(_siteForeignKey);
|
||||
}
|
||||
|
||||
protected override JobTaskEntityBuilder BuildTable(ColumnsBuilder table)
|
||||
{
|
||||
JobTaskId = AddAutoIncrementColumn(table,"JobTaskId");
|
||||
SiteId = AddIntegerColumn(table,"SiteId");
|
||||
Name = AddStringColumn(table, "Name", 200);
|
||||
Type = AddStringColumn(table, "Type", 200);
|
||||
Parameters = AddMaxStringColumn(table, "Parameters", true);
|
||||
IsCompleted = AddBooleanColumn(table, "IsCompleted", true);
|
||||
Status = AddMaxStringColumn(table, "Status", true);
|
||||
|
||||
AddAuditableColumns(table);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public OperationBuilder<AddColumnOperation> JobTaskId { get; private set; }
|
||||
|
||||
public OperationBuilder<AddColumnOperation> SiteId { get; private set; }
|
||||
|
||||
public OperationBuilder<AddColumnOperation> Name { get; private set; }
|
||||
|
||||
public OperationBuilder<AddColumnOperation> Type { get; private set; }
|
||||
|
||||
public OperationBuilder<AddColumnOperation> Parameters { get; private set; }
|
||||
|
||||
public OperationBuilder<AddColumnOperation> IsCompleted { get; private set; }
|
||||
|
||||
public OperationBuilder<AddColumnOperation> Status { get; private set; }
|
||||
}
|
||||
}
|
||||
28
Oqtane.Server/Migrations/Tenant/10010004_AddJobTasks.cs
Normal file
28
Oqtane.Server/Migrations/Tenant/10010004_AddJobTasks.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Oqtane.Databases.Interfaces;
|
||||
using Oqtane.Migrations.EntityBuilders;
|
||||
using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Migrations.Tenant
|
||||
{
|
||||
[DbContext(typeof(TenantDBContext))]
|
||||
[Migration("Tenant.10.01.00.04")]
|
||||
public class AddJobTasks : MultiDatabaseMigration
|
||||
{
|
||||
public AddJobTasks(IDatabase database) : base(database)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
var jobTaskEntityBuilder = new JobTaskEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||
jobTaskEntityBuilder.Create();
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// not implemented
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,5 +136,6 @@ namespace Oqtane.Repository
|
||||
public virtual DbSet<MigrationHistory> MigrationHistory { get; set; }
|
||||
public virtual DbSet<SiteGroup> SiteGroup { get; set; }
|
||||
public virtual DbSet<SiteGroupMember> SiteGroupMember { get; set; }
|
||||
public virtual DbSet<JobTask> JobTask { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ namespace Oqtane.Repository
|
||||
|
||||
public void DeleteJobLog(int jobLogId)
|
||||
{
|
||||
JobLog joblog = _db.JobLog.Find(jobLogId);
|
||||
_db.JobLog.Remove(joblog);
|
||||
JobLog jobLog = _db.JobLog.Find(jobLogId);
|
||||
_db.JobLog.Remove(jobLog);
|
||||
_db.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
56
Oqtane.Server/Repository/JobTaskRepository.cs
Normal file
56
Oqtane.Server/Repository/JobTaskRepository.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
{
|
||||
public interface IJobTaskRepository
|
||||
{
|
||||
IEnumerable<JobTask> GetJobTasks(int siteId);
|
||||
JobTask GetJobTask(int jobTaskId);
|
||||
JobTask AddJobTask(JobTask jobTask);
|
||||
JobTask UpdateJobTask(JobTask jobTask);
|
||||
void DeleteJobTask(int jobTaskId);
|
||||
}
|
||||
|
||||
public class JobTaskRepository : IJobTaskRepository
|
||||
{
|
||||
private TenantDBContext _db;
|
||||
|
||||
public JobTaskRepository(TenantDBContext context)
|
||||
{
|
||||
_db = context;
|
||||
}
|
||||
|
||||
public IEnumerable<JobTask> GetJobTasks(int siteId)
|
||||
{
|
||||
return _db.JobTask.Where(item => item.SiteId == siteId && !item.IsCompleted).OrderBy(item => item.CreatedOn);
|
||||
}
|
||||
|
||||
public JobTask GetJobTask(int jobTaskId)
|
||||
{
|
||||
return _db.JobTask.SingleOrDefault(item => item.JobTaskId == jobTaskId);
|
||||
}
|
||||
|
||||
public JobTask AddJobTask(JobTask jobTask)
|
||||
{
|
||||
_db.JobTask.Add(jobTask);
|
||||
_db.SaveChanges();
|
||||
return jobTask;
|
||||
}
|
||||
public JobTask UpdateJobTask(JobTask jobTask)
|
||||
{
|
||||
_db.Entry(jobTask).State = EntityState.Modified;
|
||||
_db.SaveChanges();
|
||||
return jobTask;
|
||||
}
|
||||
|
||||
public void DeleteJobTask(int jobTaskId)
|
||||
{
|
||||
JobTask jobTask = _db.JobTask.Find(jobTaskId);
|
||||
_db.JobTask.Remove(jobTask);
|
||||
_db.SaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user