commit
f636ffcdba
|
@ -139,19 +139,19 @@ else
|
|||
switch (function)
|
||||
{
|
||||
case "Create":
|
||||
classname = "table-primary";
|
||||
classname = "table-success";
|
||||
break;
|
||||
case "Read":
|
||||
classname = "table-secondary";
|
||||
classname = "table-primary";
|
||||
break;
|
||||
case "Update":
|
||||
classname = "table-success";
|
||||
classname = "table-warning";
|
||||
break;
|
||||
case "Delete":
|
||||
classname = "table-danger";
|
||||
break;
|
||||
case "Security":
|
||||
classname = "table-warning";
|
||||
classname = "table-secondary";
|
||||
break;
|
||||
default:
|
||||
classname = "";
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace Oqtane.Services
|
|||
log.Level = Enum.GetName(typeof(LogLevel), level);
|
||||
if (exception != null)
|
||||
{
|
||||
log.Exception = JsonSerializer.Serialize(exception);
|
||||
log.Exception = exception.ToString();
|
||||
}
|
||||
log.Message = message;
|
||||
log.MessageTemplate = "";
|
||||
|
|
92
Oqtane.Server/Infrastructure/HostedServiceBase.cs
Normal file
92
Oqtane.Server/Infrastructure/HostedServiceBase.cs
Normal file
|
@ -0,0 +1,92 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Repository;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public abstract class HostedServiceBase : IHostedService, IDisposable
|
||||
{
|
||||
private Task ExecutingTask;
|
||||
private readonly CancellationTokenSource CancellationTokenSource = new CancellationTokenSource();
|
||||
private readonly IServiceScopeFactory ServiceScopeFactory;
|
||||
|
||||
public HostedServiceBase(IServiceScopeFactory ServiceScopeFactory)
|
||||
{
|
||||
this.ServiceScopeFactory = ServiceScopeFactory;
|
||||
}
|
||||
|
||||
// abstract method must be overridden by job
|
||||
public abstract void ExecuteJob(IServiceProvider provider);
|
||||
|
||||
|
||||
protected async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
// allows consumption of scoped services
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
string JobType = Utilities.GetFullTypeName(this.GetType().AssemblyQualifiedName);
|
||||
IScheduleRepository ScheduleRepository = scope.ServiceProvider.GetRequiredService<IScheduleRepository>();
|
||||
List<Schedule> schedules = ScheduleRepository.GetSchedules().ToList();
|
||||
Schedule schedule = schedules.Where(item => item.JobType == JobType).FirstOrDefault();
|
||||
if (schedule != null && schedule.IsActive)
|
||||
{
|
||||
ExecuteJob(scope.ServiceProvider);
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// can occur during the initial installation as there is no DBContext
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
ExecutingTask = ExecuteAsync(CancellationTokenSource.Token);
|
||||
|
||||
if (ExecutingTask.IsCompleted)
|
||||
{
|
||||
return ExecutingTask;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken CancellationToken)
|
||||
{
|
||||
if (ExecutingTask == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
CancellationTokenSource.Cancel();
|
||||
}
|
||||
finally
|
||||
{
|
||||
await Task.WhenAny(ExecutingTask, Task.Delay(Timeout.Infinite, CancellationToken));
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
CancellationTokenSource.Cancel();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -62,11 +62,18 @@ namespace Oqtane.Infrastructure
|
|||
log.Level = Enum.GetName(typeof(LogLevel), Level);
|
||||
if (Exception != null)
|
||||
{
|
||||
log.Exception = JsonSerializer.Serialize(Exception.ToString());
|
||||
log.Exception = Exception.ToString();
|
||||
}
|
||||
log.Message = Message;
|
||||
log.MessageTemplate = "";
|
||||
log.Properties = JsonSerializer.Serialize(Args);
|
||||
try
|
||||
{
|
||||
log.Properties = JsonSerializer.Serialize(Args);
|
||||
}
|
||||
catch // serialization error occurred
|
||||
{
|
||||
log.Properties = "";
|
||||
}
|
||||
Log(log);
|
||||
}
|
||||
|
||||
|
|
21
Oqtane.Server/Infrastructure/TestJob.cs
Normal file
21
Oqtane.Server/Infrastructure/TestJob.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Infrastructure
|
||||
{
|
||||
public class TestJob : HostedServiceBase
|
||||
{
|
||||
public TestJob(IServiceScopeFactory ServiceScopeFactory) : base(ServiceScopeFactory) {}
|
||||
|
||||
public override void ExecuteJob(IServiceProvider provider)
|
||||
{
|
||||
var Tenants = provider.GetRequiredService<ITenantRepository>();
|
||||
foreach(Tenant tenant in Tenants.GetTenants())
|
||||
{
|
||||
// is it possible to set the HttpContext so that DbContextBase will resolve properly for tenants?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,6 +44,10 @@ namespace Oqtane.Repository
|
|||
moduledef = new ModuleDefinition { ModuleDefinitionName = moduledefinition.ModuleDefinitionName };
|
||||
db.ModuleDefinition.Add(moduledef);
|
||||
db.SaveChanges();
|
||||
if (moduledefinition.Permissions != "")
|
||||
{
|
||||
Permissions.UpdatePermissions(SiteId, "ModuleDefinition", moduledef.ModuleDefinitionId, moduledefinition.Permissions);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -123,7 +127,8 @@ namespace Oqtane.Repository
|
|||
ServerAssemblyName = GetProperty(properties, "ServerAssemblyName"),
|
||||
ControlTypeTemplate = ModuleType + "." + Constants.ActionToken + ", " + typename[1],
|
||||
ControlTypeRoutes = "",
|
||||
AssemblyName = assembly.FullName.Split(",")[0]
|
||||
AssemblyName = assembly.FullName.Split(",")[0],
|
||||
Permissions = ""
|
||||
};
|
||||
}
|
||||
else
|
||||
|
@ -144,7 +149,8 @@ namespace Oqtane.Repository
|
|||
ServerAssemblyName = "",
|
||||
ControlTypeTemplate = ModuleType + "." + Constants.ActionToken + ", " + typename[1],
|
||||
ControlTypeRoutes = "",
|
||||
AssemblyName = assembly.FullName.Split(",")[0]
|
||||
AssemblyName = assembly.FullName.Split(",")[0],
|
||||
Permissions = ((QualifiedModuleType.StartsWith("Oqtane.Modules.Admin.")) ? "[{\"PermissionName\":\"Utilize\",\"Permissions\":\"Administrators\"}]" : "")
|
||||
};
|
||||
}
|
||||
moduledefinitions.Add(moduledefinition);
|
||||
|
|
|
@ -52,12 +52,14 @@ GO
|
|||
|
||||
CREATE TABLE [dbo].[Schedule] (
|
||||
[ScheduleId] [int] IDENTITY(1,1) NOT NULL,
|
||||
[Name] [nvarchar](200) NULL,
|
||||
[Name] [nvarchar](200) NOT NULL,
|
||||
[JobType] [nvarchar](200) NOT NULL,
|
||||
[Period] [int] NOT NULL,
|
||||
[Frequency] [char](1) NOT NULL,
|
||||
[StartDate] [datetime] NULL,
|
||||
[IsActive] [bit] NOT NULL,
|
||||
[IsExecuting] [bit] NOT NULL,
|
||||
[NextExecution] [datetime] NULL,
|
||||
[RetentionHistory] [int] NOT NULL,
|
||||
[CreatedBy] [nvarchar](256) NULL,
|
||||
[CreatedOn] [datetime] NULL,
|
||||
|
@ -77,7 +79,6 @@ CREATE TABLE [dbo].[ScheduleLog] (
|
|||
[FinishDate] [datetime] NULL,
|
||||
[Succeeded] [bit] NULL,
|
||||
[Notes] [nvarchar](max) NULL,
|
||||
[NextExecution] [datetime] NULL,
|
||||
CONSTRAINT [PK_ScheduleLog] PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[ScheduleLogId] ASC
|
||||
|
|
|
@ -38,10 +38,17 @@ namespace Oqtane.Security
|
|||
foreach (UserRole userrole in userroles)
|
||||
{
|
||||
id.AddClaim(new Claim(options.ClaimsIdentity.RoleClaimType, userrole.Role.Name));
|
||||
// host users are admins of every site
|
||||
if (userrole.Role.Name == Constants.HostRole && userroles.Where(item => item.Role.Name == Constants.AdminRole).FirstOrDefault() == null)
|
||||
// host users are members of every site
|
||||
if (userrole.Role.Name == Constants.HostRole)
|
||||
{
|
||||
id.AddClaim(new Claim(options.ClaimsIdentity.RoleClaimType, Constants.AdminRole));
|
||||
if (userroles.Where(item => item.Role.Name == Constants.RegisteredRole).FirstOrDefault() == null)
|
||||
{
|
||||
id.AddClaim(new Claim(options.ClaimsIdentity.RoleClaimType, Constants.RegisteredRole));
|
||||
}
|
||||
if (userroles.Where(item => item.Role.Name == Constants.AdminRole).FirstOrDefault() == null)
|
||||
{
|
||||
id.AddClaim(new Claim(options.ClaimsIdentity.RoleClaimType, Constants.AdminRole));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,10 +154,6 @@ namespace Oqtane.Server
|
|||
services.AddSingleton<IConfigurationRoot>(Configuration);
|
||||
services.AddSingleton<IInstallationManager, InstallationManager>();
|
||||
|
||||
//ServiceProvider sp = services.BuildServiceProvider();
|
||||
//var InstallationManager = sp.GetRequiredService<IInstallationManager>();
|
||||
//InstallationManager.InstallPackages("Modules,Themes");
|
||||
|
||||
// register transient scoped core services
|
||||
services.AddTransient<IModuleDefinitionRepository, ModuleDefinitionRepository>();
|
||||
services.AddTransient<IThemeRepository, ThemeRepository>();
|
||||
|
@ -235,6 +231,21 @@ namespace Oqtane.Server
|
|||
}
|
||||
}
|
||||
|
||||
// dynamically register hosted services
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
Type[] servicetypes = assembly.GetTypes()
|
||||
.Where(item => item.GetInterfaces().Contains(typeof(IHostedService)))
|
||||
.ToArray();
|
||||
foreach (Type servicetype in servicetypes)
|
||||
{
|
||||
if (servicetype.Name != "HostedServiceBase")
|
||||
{
|
||||
services.AddSingleton(typeof(IHostedService), servicetype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Oqtane", Version = "v1" });
|
||||
|
|
|
@ -11,6 +11,8 @@ namespace Oqtane.Models
|
|||
public string Frequency { get; set; }
|
||||
public DateTime? StartDate { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public bool IsExecuting { get; set; }
|
||||
public DateTime? NextExecution { get; set; }
|
||||
public int RetentionHistory { get; set; }
|
||||
|
||||
public string CreatedBy { get; set; }
|
||||
|
|
|
@ -10,6 +10,5 @@ namespace Oqtane.Models
|
|||
public DateTime? FinishDate { get; set; }
|
||||
public bool? Succeeded { get; set; }
|
||||
public string Notes { get; set; }
|
||||
public DateTime? NextExecution { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,6 +70,18 @@ namespace Oqtane.Shared
|
|||
}
|
||||
}
|
||||
|
||||
public static string GetFullTypeName(string fullyqualifiedtypename)
|
||||
{
|
||||
if (fullyqualifiedtypename.Contains(", Version="))
|
||||
{
|
||||
return fullyqualifiedtypename.Substring(0, fullyqualifiedtypename.IndexOf(", Version="));
|
||||
}
|
||||
else
|
||||
{
|
||||
return fullyqualifiedtypename;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetTypeNameLastSegment(string typename, int segment)
|
||||
{
|
||||
if (typename.Contains(","))
|
||||
|
|
Loading…
Reference in New Issue
Block a user