16-12-2022

This commit is contained in:
Jonathan Jenne 2022-12-16 15:59:26 +01:00
parent 63edd9e542
commit 45f8dd2aad
32 changed files with 431 additions and 276 deletions

View File

@ -7,5 +7,12 @@ namespace ECM.JobRunner.Web.Data
public DateTime heartbeat = DateTime.MinValue; public DateTime heartbeat = DateTime.MinValue;
public List<HistoryItem> jobHistory = new(); public List<HistoryItem> jobHistory = new();
public List<StatusItem> jobStatus = new(); public List<StatusItem> jobStatus = new();
public List<HistoryItem> GetHistoryForLastMinutes(int pMinutes)
{
return jobHistory.
Where(h => (DateTime.Now - h.CreatedAt) < new TimeSpan(0, pMinutes, 0)).
ToList();
}
} }
} }

View File

@ -9,53 +9,39 @@ namespace ECM.JobRunner.Web.Data
private readonly Common.JobRunnerReference.IEDMIServiceChannel channel; private readonly Common.JobRunnerReference.IEDMIServiceChannel channel;
private Logger logger; private Logger logger;
private System.Timers.Timer pollingTimer = new(); private readonly System.Timers.Timer pollingTimer = new();
public event EventHandler<DashboardResponse> DataUpdated; public event EventHandler<DashboardResponse>? DataUpdated;
public DashboardService(LoggingService Logging, WcfService Wcf) public DashboardService(LoggingService Logging, WcfService Wcf)
{ {
logger = Logging.LogConfig.GetLogger(); logger = Logging.LogConfig.GetLogger();
channel = Wcf.Channel; channel = Wcf.Channel;
pollingTimer.Elapsed += PollingTimer_Elapsed; pollingTimer.Elapsed += PollingTimer_Elapsed;
pollingTimer.Interval = 1000;
pollingTimer.Start();
} }
protected virtual void OnDataUpdated(DashboardResponse e) protected virtual void OnDataUpdated(DashboardResponse e)
{ {
EventHandler<DashboardResponse> handler = DataUpdated; DataUpdated?.Invoke(this, e);
if (handler != null)
{
handler(this, e);
}
} }
private async void PollingTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) private async void PollingTimer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
{ {
OnDataUpdated(await GetData()); OnDataUpdated(await GetData());
} }
public async Task<DashboardResponse> GetData() public async Task<DashboardResponse> GetData()
{ {
DateTime heartbeat = await GetHeartbeat();
List<Common.JobRunnerReference.HistoryItem> jobHistory = await GetHistoryItems(); List<Common.JobRunnerReference.HistoryItem> jobHistory = await GetHistoryItems();
List<Common.JobRunnerReference.StatusItem> jobStatus = await GetStatusItems(); List<Common.JobRunnerReference.StatusItem> jobStatus = await GetStatusItems();
return new DashboardResponse() return new DashboardResponse()
{ {
heartbeat = heartbeat, jobHistory = jobHistory.OrderByDescending(e => e.CreatedAt).ToList(),
jobHistory = jobHistory.OrderByDescending(e => e.CreatedAt).Take(10).ToList(), jobStatus = jobStatus.OrderByDescending(e => e.StartTime).ToList()
jobStatus = jobStatus.OrderByDescending(e => e.StartTime).Take(10).ToList()
}; };
} }
private async Task<DateTime> GetHeartbeat()
{
return await channel.GetHeartbeatAsync();
}
private async Task<List<Common.JobRunnerReference.HistoryItem>> GetHistoryItems() private async Task<List<Common.JobRunnerReference.HistoryItem>> GetHistoryItems()
{ {
try try

View File

@ -0,0 +1,40 @@
using DigitalData.Modules.Logging;
using ECM.JobRunner.Common.JobRunnerReference;
namespace ECM.JobRunner.Web.Data
{
public class HelperService
{
private readonly Logger logger;
private readonly IEDMIServiceChannel channel;
public HelperService(LoggingService Logging, WcfService Wcf)
{
logger = Logging.LogConfig.GetLogger();
channel = Wcf.Channel;
}
public DateTime GetNextExecutionTime(string pCronExpression)
{
Quartz.CronExpression expression = new(pCronExpression);
if (expression != null)
{
var next = expression.GetNextValidTimeAfter(DateTimeOffset.Now);
if (next != null)
{
return ((DateTimeOffset)next).DateTime;
}
else
{
return DateTime.MinValue;
}
}
else
{
return DateTime.MinValue;
}
}
}
}

View File

@ -0,0 +1,93 @@
using DigitalData.Modules.Logging;
using ECM.JobRunner.Common.JobRunnerReference;
namespace ECM.JobRunner.Web.Data
{
public class ImportProfileService
{
private readonly Logger logger;
private readonly IEDMIServiceChannel channel;
public ImportProfileService(LoggingService Logging, WcfService Wcf)
{
logger = Logging.LogConfig.GetLogger();
channel = Wcf.Channel;
}
public async Task<List<ImportProfile>> GetProfiles()
{
try
{
var resp = await channel.GetJobConfigAsync();
if (resp == null) return new();
if (resp.OK == false) return new();
var profiles = resp.ProfileDefinitions.ImportProfiles.ToList();
return profiles;
}
catch (Exception ex)
{
logger.Error(ex);
return new();
}
}
public async Task<ImportProfile?> GetProfile(int pProfileId)
{
try
{
var resp = await channel.GetJobConfigAsync();
if (resp == null) return null;
if (resp.OK == false) return null;
var jobs = resp.JobDefinitions.ToList();
var profiles = resp.ProfileDefinitions.ImportProfiles.ToList();
return profiles.
Where(p => p.Id == pProfileId).
SingleOrDefault();
}
catch (Exception ex)
{
logger.Error(ex);
return null;
}
}
public async Task<bool> CreateProfile(ImportProfile profile) =>
await DoUpdateProfile(profile, UpdateProfileUpdateProfileRequest.UpdateProfileAction.Create);
public async Task<bool> UpdateProfile(ImportProfile profile) =>
await DoUpdateProfile(profile, UpdateProfileUpdateProfileRequest.UpdateProfileAction.Update);
public async Task<bool> DeleteProfile(ImportProfile profile) =>
await DoUpdateProfile(profile, UpdateProfileUpdateProfileRequest.UpdateProfileAction.Delete);
private async Task<bool> DoUpdateProfile(ImportProfile profile, UpdateProfileUpdateProfileRequest.UpdateProfileAction action)
{
try
{
var req = new UpdateProfileUpdateProfileRequest()
{
ImportProfile = profile,
Action = action
};
var resp = await channel.UpdateProfileAsync(req);
if (resp == null) return false;
if (resp.OK == false) return false;
return true;
}
catch (Exception ex)
{
logger.Error(ex);
return false;
}
}
}
}

View File

@ -1,67 +0,0 @@
using DigitalData.Modules.Logging;
using ECM.JobRunner.Common.JobRunnerReference;
namespace ECM.JobRunner.Web.Data
{
public class ImportService
{
private readonly Logger logger;
private readonly IEDMIServiceChannel channel;
public ImportService(LoggingService Logging, WcfService Wcf)
{
logger = Logging.LogConfig.GetLogger();
channel = Wcf.Channel;
}
public async Task<List<ImportProfile>> GetProfiles()
{
var resp = await channel.GetJobConfigAsync();
if (resp == null) return new();
if (resp.OK == false) return new();
var profiles = resp.ProfileDefinitions.ImportProfiles.ToList();
return profiles;
}
public async Task<ImportProfile?> GetProfile(int pProfileId)
{
var resp = await channel.GetJobConfigAsync();
if (resp == null) return new();
if (resp.OK == false) return new();
var jobs = resp.JobDefinitions.ToList();
var profiles = resp.ProfileDefinitions.ImportProfiles.ToList();
return profiles.
Where(p => p.Id == pProfileId).
SingleOrDefault();
}
public async Task<bool> CreateProfile(ImportProfile profile) =>
await DoUpdateProfile(profile, UpdateProfileUpdateProfileRequest.UpdateProfileAction.Create);
public async Task<bool> UpdateProfile(ImportProfile profile) =>
await DoUpdateProfile(profile, UpdateProfileUpdateProfileRequest.UpdateProfileAction.Update);
public async Task<bool> DeleteProfile(ImportProfile profile) =>
await DoUpdateProfile(profile, UpdateProfileUpdateProfileRequest.UpdateProfileAction.Delete);
private async Task<bool> DoUpdateProfile(ImportProfile profile, UpdateProfileUpdateProfileRequest.UpdateProfileAction action)
{
var req = new UpdateProfileUpdateProfileRequest()
{
ImportProfile = profile,
Action = action
};
var resp = await channel.UpdateProfileAsync(req);
if (resp == null) return false;
if (resp.OK == false) return false;
return true;
}
}
}

View File

@ -1,131 +0,0 @@
using DigitalData.Modules.Logging;
using ECM.JobRunner.Common.JobRunnerReference;
namespace ECM.JobRunner.Web.Data
{
public class JobService
{
private readonly Logger logger;
private readonly IEDMIServiceChannel channel;
public JobService(LoggingService Logging, WcfService Wcf)
{
logger = Logging.LogConfig.GetLogger();
channel = Wcf.Channel;
}
public async Task<List<JobDefinition>> GetJobs()
{
var resp = await channel.GetJobConfigAsync();
if (resp == null) return new();
if (resp.OK == false) return new();
return resp.JobDefinitions.ToList();
}
public async Task<List<ObjectType>> GetObjectTypes()
{
var resp = await channel.GetJobConfigAsync();
if (resp == null) return new();
if (resp.OK == false) return new();
return resp.WindreamObjectTypes.ToList();
}
public async Task<List<JobType>> GetJobTypes()
{
var resp = await channel.GetJobConfigAsync();
if (resp == null) return new();
if (resp.OK == false) return new();
return resp.JobTypes.ToList();
}
public async Task<JobDefinition?> GetJob(int pJobId)
{
var resp = await channel.GetJobConfigAsync();
if (resp == null) return null;
if (resp.OK == false) return null;
return resp.JobDefinitions.
Where(j => j.Id == pJobId).
FirstOrDefault();
}
public async Task<bool> UpdateJob(JobDefinition job)
{
var resp = await channel.UpdateJobAsync(new UpdateJobUpdateJobRequest {
Job = job,
Action = UpdateJobUpdateJobRequest.UpdateJobAction.Update
});
if (resp == null) return false;
if (resp.OK == false) return false;
return true;
}
public async Task<bool> CreateJob(JobDefinition job)
{
var resp = await channel.UpdateJobAsync(new UpdateJobUpdateJobRequest
{
Job = job,
Action = UpdateJobUpdateJobRequest.UpdateJobAction.Create
});
if (resp != null && resp.OK)
{
return true;
}
else
{
return false;
}
}
public async Task<bool> DeleteJob(JobDefinition job)
{
var resp = await channel.UpdateJobAsync(new UpdateJobUpdateJobRequest
{
Job = job,
Action = UpdateJobUpdateJobRequest.UpdateJobAction.Delete
});
if (resp != null && resp.OK)
{
return true;
}
else
{
return false;
}
}
public DateTime GetNextExecutionTime(string pCronExpression)
{
Quartz.CronExpression expression = new(pCronExpression);
if (expression != null)
{
var next = expression.GetNextValidTimeAfter(DateTimeOffset.Now);
if (next != null)
{
return ((DateTimeOffset)next).DateTime;
}
else
{
return DateTime.MinValue;
}
}
else
{
return DateTime.MinValue;
}
}
}
}

View File

@ -10,7 +10,8 @@ namespace ECM.JobRunner.Web.Data
{ {
LogConfig = new LogConfig(LogConfig.PathType.CustomPath, Config["Config:LogPath"], null, "Digital Data", "ECM.JobRunner.Web") LogConfig = new LogConfig(LogConfig.PathType.CustomPath, Config["Config:LogPath"], null, "Digital Data", "ECM.JobRunner.Web")
{ {
Debug = bool.Parse(Config["Config:LogDebug"]) Debug = bool.Parse(Config["Config:LogDebug"]),
EnableJsonLog = bool.Parse(Config["Config:LogJson"])
}; };
} }
} }

View File

@ -1,22 +1,77 @@
using DigitalData.Modules.Messaging.WCF; using DigitalData.Modules.Messaging.WCF;
using System.Net; using ECM.JobRunner.Common.JobRunnerReference;
using System.Timers;
namespace ECM.JobRunner.Web.Data namespace ECM.JobRunner.Web.Data
{ {
public class WcfService public class WcfService
{ {
private readonly Channel<Common.JobRunnerReference.IEDMIServiceChannel> channelManager; private readonly Channel<IEDMIServiceChannel> _channelManager;
private ServerAddress address; private ServerAddress _address;
private bool _connected = false;
private System.Timers.Timer heartbeatTimer = new();
public readonly Common.JobRunnerReference.IEDMIServiceChannel Channel; private IEDMIServiceChannel _channel;
public IEDMIServiceChannel Channel { get { return _channel; } }
public event EventHandler<bool>? ConnectedChanged;
public bool Connected { get { return _connected; } }
public WcfService(LoggingService Logging) public WcfService(LoggingService Logging)
{ {
address.Host = "172.24.12.39"; _address.Host = "172.24.12.39";
address.Port = 9001; _address.Port = 9001;
channelManager = new Channel<Common.JobRunnerReference.IEDMIServiceChannel>(Logging.LogConfig, address, "JobRunner"); _channelManager = new Channel<IEDMIServiceChannel>(Logging.LogConfig, _address, "JobRunner");
Channel = channelManager.GetChannel(); _channel = _channelManager.GetChannel();
_connected = true;
heartbeatTimer.Elapsed += HeartbeatTimer_Elapsed;
heartbeatTimer.Interval = 1000;
heartbeatTimer.Start();
}
private void CallConnectedChanged(bool pConnected)
{
if (ConnectedChanged != null && pConnected != _connected)
{
_connected = pConnected;
ConnectedChanged(this, pConnected);
}
}
private async void HeartbeatTimer_Elapsed(object? sender, ElapsedEventArgs e)
{
try
{
await _channel.GetHeartbeatAsync();
CallConnectedChanged(true);
}
catch (Exception)
{
CallConnectedChanged(false);
}
}
public async Task<List<ObjectType>> GetObjectTypes()
{
var resp = await _channel.GetJobConfigAsync();
if (resp == null) return new();
if (resp.OK == false) return new();
return resp.WindreamObjectTypes.ToList();
}
public async Task<List<JobType>> GetJobTypes()
{
var resp = await _channel.GetJobConfigAsync();
if (resp == null) return new();
if (resp.OK == false) return new();
return resp.JobTypes.ToList();
} }
} }
} }

View File

@ -25,7 +25,7 @@ else
{ {
<ul class="list-group mb-3"> <ul class="list-group mb-3">
<li class="list-group-item bg-light bg-gradient d-flex justify-content-between align-items-start"> <li class="list-group-item bg-light bg-gradient d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto"> <div class="me-auto">
<div class="fw-bold"> <div class="fw-bold">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-circle text-success" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-circle text-success" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" /> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />

View File

@ -3,7 +3,7 @@
@using ECM.JobRunner.Web.Data; @using ECM.JobRunner.Web.Data;
@using ECM.JobRunner.Web.Pages.ImportStep; @using ECM.JobRunner.Web.Pages.ImportStep;
@inject NavigationManager Navigation; @inject NavigationManager Navigation;
@inject ImportService Profile; @inject ImportProfileService Profile;
<PageTitle>Job bearbeiten</PageTitle> <PageTitle>Job bearbeiten</PageTitle>

View File

@ -2,7 +2,7 @@
@using ECM.JobRunner.Common.JobRunnerReference; @using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data; @using ECM.JobRunner.Web.Data;
@inject NavigationManager Navigation; @inject NavigationManager Navigation;
@inject ImportService Import; @inject ImportProfileService Import;
<PageTitle>Job erstellen</PageTitle> <PageTitle>Job erstellen</PageTitle>

View File

@ -1,7 +1,8 @@
@using ECM.JobRunner.Common.JobRunnerReference; @using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data; @using ECM.JobRunner.Web.Data;
@inject ImportService Import; @inject ImportProfileService Import;
@inject JobService Jobs; @inject HelperService Jobs;
@inject WcfService Service;
@if (profile == null) @if (profile == null)
{ {
@ -196,8 +197,8 @@ else
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
jobTypes = await Jobs.GetJobTypes(); jobTypes = await Service.GetJobTypes();
objectTypes = await Jobs.GetObjectTypes(); objectTypes = await Service.GetObjectTypes();
if (ProfileId == Constants.ENTITY_ID_NEW) if (ProfileId == Constants.ENTITY_ID_NEW)
{ {

View File

@ -1,8 +1,8 @@
@page "/profiles/import" @page "/profiles/import"
@using ECM.JobRunner.Common.JobRunnerReference; @using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data; @using ECM.JobRunner.Web.Data;
@inject JobService Jobs @inject HelperService Jobs
@inject ImportService Import; @inject ImportProfileService Import;
<PageTitle>Import Profiles</PageTitle> <PageTitle>Import Profiles</PageTitle>
@ -34,7 +34,7 @@ else
@foreach (var profile in filteredProfiles) @foreach (var profile in filteredProfiles)
{ {
<a href="/profiles/import/@profile.Id" class="list-group-item list-group-item-action d-flex justify-content-between align-items-start"> <a href="/profiles/import/@profile.Id" class="list-group-item list-group-item-action d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto"> <div class="me-auto">
<div class="fw-bold"> <div class="fw-bold">
<span> <span>
@if (profile.Active) @if (profile.Active)

View File

@ -4,8 +4,8 @@
@inject NavigationManager Navigation; @inject NavigationManager Navigation;
@inject IJSRuntime JsRuntime; @inject IJSRuntime JsRuntime;
@inject JobService Jobs; @inject HelperService Helper;
@inject ImportService Import; @inject ImportProfileService Import;
<PageTitle>Profile</PageTitle> <PageTitle>Profile</PageTitle>
@ -39,7 +39,7 @@ else
<ul class="list-group mb-3"> <ul class="list-group mb-3">
<li class="list-group-item d-flex justify-content-between align-items-start"> <li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto"> <div class="me-auto">
<div class="fw-bold"> <div class="fw-bold">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-right" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M10 12.5a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v2a.5.5 0 0 0 1 0v-2A1.5 1.5 0 0 0 9.5 2h-8A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-2a.5.5 0 0 0-1 0v2z" /> <path fill-rule="evenodd" d="M10 12.5a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v2a.5.5 0 0 0 1 0v-2A1.5 1.5 0 0 0 9.5 2h-8A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-2a.5.5 0 0 0-1 0v2z" />
@ -50,7 +50,7 @@ else
</div> </div>
</li> </li>
<li class="list-group-item d-flex justify-content-between align-items-start"> <li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto"> <div class="me-auto">
<div class="fw-bold"> <div class="fw-bold">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-in-right" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-in-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M6 3.5a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v9a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-2a.5.5 0 0 0-1 0v2A1.5 1.5 0 0 0 6.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2h-8A1.5 1.5 0 0 0 5 3.5v2a.5.5 0 0 0 1 0v-2z" /> <path fill-rule="evenodd" d="M6 3.5a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v9a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-2a.5.5 0 0 0-1 0v2A1.5 1.5 0 0 0 6.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-9A1.5 1.5 0 0 0 14.5 2h-8A1.5 1.5 0 0 0 5 3.5v2a.5.5 0 0 0 1 0v-2z" />
@ -61,7 +61,7 @@ else
</div> </div>
</li> </li>
<li class="list-group-item d-flex justify-content-between align-items-start"> <li class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto"> <div class="me-auto">
<div class="fw-bold"> <div class="fw-bold">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-hourglass" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-hourglass" viewBox="0 0 16 16">
<path d="M2 1.5a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-1v1a4.5 4.5 0 0 1-2.557 4.06c-.29.139-.443.377-.443.59v.7c0 .213.154.451.443.59A4.5 4.5 0 0 1 12.5 13v1h1a.5.5 0 0 1 0 1h-11a.5.5 0 1 1 0-1h1v-1a4.5 4.5 0 0 1 2.557-4.06c.29-.139.443-.377.443-.59v-.7c0-.213-.154-.451-.443-.59A4.5 4.5 0 0 1 3.5 3V2h-1a.5.5 0 0 1-.5-.5zm2.5.5v1a3.5 3.5 0 0 0 1.989 3.158c.533.256 1.011.791 1.011 1.491v.702c0 .7-.478 1.235-1.011 1.491A3.5 3.5 0 0 0 4.5 13v1h7v-1a3.5 3.5 0 0 0-1.989-3.158C8.978 9.586 8.5 9.052 8.5 8.351v-.702c0-.7.478-1.235 1.011-1.491A3.5 3.5 0 0 0 11.5 3V2h-7z" /> <path d="M2 1.5a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-1v1a4.5 4.5 0 0 1-2.557 4.06c-.29.139-.443.377-.443.59v.7c0 .213.154.451.443.59A4.5 4.5 0 0 1 12.5 13v1h1a.5.5 0 0 1 0 1h-11a.5.5 0 1 1 0-1h1v-1a4.5 4.5 0 0 1 2.557-4.06c.29-.139.443-.377.443-.59v-.7c0-.213-.154-.451-.443-.59A4.5 4.5 0 0 1 3.5 3V2h-1a.5.5 0 0 1-.5-.5zm2.5.5v1a3.5 3.5 0 0 0 1.989 3.158c.533.256 1.011.791 1.011 1.491v.702c0 .7-.478 1.235-1.011 1.491A3.5 3.5 0 0 0 4.5 13v1h7v-1a3.5 3.5 0 0 0-1.989-3.158C8.978 9.586 8.5 9.052 8.5 8.351v-.702c0-.7.478-1.235 1.011-1.491A3.5 3.5 0 0 0 11.5 3V2h-7z" />
@ -111,7 +111,7 @@ else
if (profile != null) if (profile != null)
{ {
nextExecution = Jobs.GetNextExecutionTime(profile.Job.CronSchedule); nextExecution = Helper.GetNextExecutionTime(profile.Job.CronSchedule);
StateHasChanged(); StateHasChanged();
} }
} }

View File

@ -2,7 +2,7 @@
@using ECM.JobRunner.Common.JobRunnerReference; @using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data; @using ECM.JobRunner.Web.Data;
@inject NavigationManager Navigation; @inject NavigationManager Navigation;
@inject ImportService Profile; @inject ImportProfileService Profile;
<PageTitle>Schritt bearbeiten</PageTitle> <PageTitle>Schritt bearbeiten</PageTitle>
@ -21,9 +21,12 @@
private async void OnFormSubmit(EditContext ctx) private async void OnFormSubmit(EditContext ctx)
{ {
ImportProfile profile = await Profile.GetProfile(ProfileId); ImportProfile? profile = await Profile.GetProfile(ProfileId);
ImportProfileStep step = (ImportProfileStep)ctx.Model; ImportProfileStep step = (ImportProfileStep)ctx.Model;
if (profile == null)
return;
// TODO: This is ugly and manual and needs to be abstracted. // TODO: This is ugly and manual and needs to be abstracted.
var index = profile.Steps.ToList().FindIndex(s => s.Id == StepId); var index = profile.Steps.ToList().FindIndex(s => s.Id == StepId);
profile.Steps[index] = step; profile.Steps[index] = step;

View File

@ -2,11 +2,11 @@
@using ECM.JobRunner.Common.JobRunnerReference; @using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data; @using ECM.JobRunner.Web.Data;
@inject NavigationManager Navigation; @inject NavigationManager Navigation;
@inject ImportService Profile; @inject ImportProfileService Profile;
<PageTitle>Schritt bearbeiten</PageTitle> <PageTitle>Neuen Schritt erstellen</PageTitle>
<h3>Schritt bearbeiten</h3> <h3>Neuen Schritt erstellen</h3>
<StepForm ProfileId="ProfileId" StepId="-1" OnValidSubmit="OnFormSubmit" /> <StepForm ProfileId="ProfileId" StepId="-1" OnValidSubmit="OnFormSubmit" />
@ -21,9 +21,12 @@
private async void OnFormSubmit(EditContext ctx) private async void OnFormSubmit(EditContext ctx)
{ {
ImportProfile profile = await Profile.GetProfile(ProfileId); ImportProfile? profile = await Profile.GetProfile(ProfileId);
ImportProfileStep step = (ImportProfileStep)ctx.Model; ImportProfileStep step = (ImportProfileStep)ctx.Model;
if (profile == null)
return;
// TODO: This is ugly and manual and needs to be abstracted. // TODO: This is ugly and manual and needs to be abstracted.
var steps = profile.Steps.ToList(); var steps = profile.Steps.ToList();
steps.Add(step); steps.Add(step);

View File

@ -4,8 +4,8 @@
@inject NavigationManager Navigation; @inject NavigationManager Navigation;
@inject IJSRuntime JsRuntime; @inject IJSRuntime JsRuntime;
@inject JobService Jobs; @inject HelperService Jobs;
@inject ImportService Import; @inject ImportProfileService Import;
<PageTitle>Profilschritt</PageTitle> <PageTitle>Profilschritt</PageTitle>
@ -143,8 +143,6 @@ else
private ImportProfile? profile; private ImportProfile? profile;
private ImportProfileStep? step; private ImportProfileStep? step;
private DateTime nextExecution;
protected async override void OnInitialized() protected async override void OnInitialized()
{ {
profile = await Import.GetProfile(ProfileId); profile = await Import.GetProfile(ProfileId);

View File

@ -1,7 +1,7 @@
@using ECM.JobRunner.Common.JobRunnerReference; @using ECM.JobRunner.Common.JobRunnerReference;
@using ECM.JobRunner.Web.Data; @using ECM.JobRunner.Web.Data;
@inject ImportService Import; @inject ImportProfileService Import;
@inject JobService Jobs; @inject HelperService Jobs;
@if (step == null || profile == null) @if (step == null || profile == null)
{ {
@ -166,7 +166,12 @@ else
else else
{ {
step = profile.Steps.Where(s => s.Id == StepId).SingleOrDefault(); step = profile.Steps.Where(s => s.Id == StepId).SingleOrDefault();
if (step != null)
{
SetMethodArgs(step.Method); SetMethodArgs(step.Method);
}
} }
StateHasChanged(); StateHasChanged();
} }
@ -217,8 +222,8 @@ else
class StepArgument class StepArgument
{ {
public string name; public string name = "";
public string helpText; public string helpText = "";
} }
} }

View File

@ -4,7 +4,7 @@
@using ECM.JobRunner.Web.Data @using ECM.JobRunner.Web.Data
@using ECM.JobRunner.Web.Pages.ImportStep @using ECM.JobRunner.Web.Pages.ImportStep
@inject ImportService Import @inject ImportProfileService Import
<h3>Profilschritte</h3> <h3>Profilschritte</h3>

View File

@ -4,4 +4,3 @@
<h3>ECM Job Runner</h3> <h3>ECM Job Runner</h3>
<p>Welcome to your new app!</p>

View File

@ -6,7 +6,7 @@
<div class="list-group"> <div class="list-group">
<a href="profiles/import" class="list-group-item list-group-item-action d-flex justify-content-between align-items-start"> <a href="profiles/import" class="list-group-item list-group-item-action d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto"> <div class="me-auto">
<div class="fw-bold"> <div class="fw-bold">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-right" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-box-arrow-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M10 12.5a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v2a.5.5 0 0 0 1 0v-2A1.5 1.5 0 0 0 9.5 2h-8A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-2a.5.5 0 0 0-1 0v2z" /> <path fill-rule="evenodd" d="M10 12.5a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v2a.5.5 0 0 0 1 0v-2A1.5 1.5 0 0 0 9.5 2h-8A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-2a.5.5 0 0 0-1 0v2z" />
@ -16,7 +16,7 @@
</div> </div>
</a> </a>
<a href="profiles" class="list-group-item list-group-item-action d-flex justify-content-between align-items-start text-muted"> <a href="profiles" class="list-group-item list-group-item-action d-flex justify-content-between align-items-start text-muted">
<div class="ms-2 me-auto"> <div class="me-auto">
<div class="fw-bold"> <div class="fw-bold">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil-square" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil-square" viewBox="0 0 16 16">
<path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z" /> <path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z" />

View File

@ -6,6 +6,58 @@
<PageTitle>Status</PageTitle> <PageTitle>Status</PageTitle>
<section class="mb-5">
<div class="row row-cols-1 row-cols-md-3 g-4">
@if (last5MinutesItems != null)
{
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-hourglass-top" viewBox="0 0 16 16">
<path d="M2 14.5a.5.5 0 0 0 .5.5h11a.5.5 0 1 0 0-1h-1v-1a4.5 4.5 0 0 0-2.557-4.06c-.29-.139-.443-.377-.443-.59v-.7c0-.213.154-.451.443-.59A4.5 4.5 0 0 0 12.5 3V2h1a.5.5 0 0 0 0-1h-11a.5.5 0 0 0 0 1h1v1a4.5 4.5 0 0 0 2.557 4.06c.29.139.443.377.443.59v.7c0 .213-.154.451-.443.59A4.5 4.5 0 0 0 3.5 13v1h-1a.5.5 0 0 0-.5.5zm2.5-.5v-1a3.5 3.5 0 0 1 1.989-3.158c.533-.256 1.011-.79 1.011-1.491v-.702s.18.101.5.101.5-.1.5-.1v.7c0 .701.478 1.236 1.011 1.492A3.5 3.5 0 0 1 11.5 13v1h-7z" />
</svg> Last 5 Minutes
</h5>
<h6 class="card-subtitle mb-2 text-muted">@last5MinutesItems.Count jobs executed.</h6>
</div>
</div>
</div>
}
@if (lastHourItems != null)
{
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-hourglass-split" viewBox="0 0 16 16">
<path d="M2.5 15a.5.5 0 1 1 0-1h1v-1a4.5 4.5 0 0 1 2.557-4.06c.29-.139.443-.377.443-.59v-.7c0-.213-.154-.451-.443-.59A4.5 4.5 0 0 1 3.5 3V2h-1a.5.5 0 0 1 0-1h11a.5.5 0 0 1 0 1h-1v1a4.5 4.5 0 0 1-2.557 4.06c-.29.139-.443.377-.443.59v.7c0 .213.154.451.443.59A4.5 4.5 0 0 1 12.5 13v1h1a.5.5 0 0 1 0 1h-11zm2-13v1c0 .537.12 1.045.337 1.5h6.326c.216-.455.337-.963.337-1.5V2h-7zm3 6.35c0 .701-.478 1.236-1.011 1.492A3.5 3.5 0 0 0 4.5 13s.866-1.299 3-1.48V8.35zm1 0v3.17c2.134.181 3 1.48 3 1.48a3.5 3.5 0 0 0-1.989-3.158C8.978 9.586 8.5 9.052 8.5 8.351z" />
</svg> Last Hour
</h5>
<h6 class="card-subtitle mb-2 text-muted">@lastHourItems.Count jobs executed.</h6>
</div>
</div>
</div>
}
@if (last12HoursItems != null)
{
<div class="col">
<div class="card">
<div class="card-body">
<h5 class="card-title">
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-hourglass-bottom" viewBox="0 0 16 16">
<path d="M2 1.5a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-1v1a4.5 4.5 0 0 1-2.557 4.06c-.29.139-.443.377-.443.59v.7c0 .213.154.451.443.59A4.5 4.5 0 0 1 12.5 13v1h1a.5.5 0 0 1 0 1h-11a.5.5 0 1 1 0-1h1v-1a4.5 4.5 0 0 1 2.557-4.06c.29-.139.443-.377.443-.59v-.7c0-.213-.154-.451-.443-.59A4.5 4.5 0 0 1 3.5 3V2h-1a.5.5 0 0 1-.5-.5zm2.5.5v1a3.5 3.5 0 0 0 1.989 3.158c.533.256 1.011.791 1.011 1.491v.702s.18.149.5.149.5-.15.5-.15v-.7c0-.701.478-1.236 1.011-1.492A3.5 3.5 0 0 0 11.5 3V2h-7z" />
</svg> Last 12 Hours
</h5>
<h6 class="card-subtitle mb-2 text-muted">@last12HoursItems.Count jobs executed.</h6>
</div>
</div>
</div>
}
</div>
</section>
<h3 class="mb-3">Job Status</h3> <h3 class="mb-3">Job Status</h3>
<section class="mb-5"> <section class="mb-5">
@ -112,6 +164,10 @@ else
private List<StatusItem>? executingEntries; private List<StatusItem>? executingEntries;
private List<StatusItem>? completedEntries; private List<StatusItem>? completedEntries;
private List<HistoryItem>? last5MinutesItems;
private List<HistoryItem>? lastHourItems;
private List<HistoryItem>? last12HoursItems;
protected async override void OnInitialized() protected async override void OnInitialized()
{ {
DashboardResponse data = await Dashboard.GetData(); DashboardResponse data = await Dashboard.GetData();
@ -139,6 +195,10 @@ else
Where(s => s.StartTime.AddMinutes(10) > DateTime.Now). Where(s => s.StartTime.AddMinutes(10) > DateTime.Now).
ToList(); ToList();
last5MinutesItems = response.GetHistoryForLastMinutes(5);
lastHourItems = response.GetHistoryForLastMinutes(60);
last12HoursItems = response.GetHistoryForLastMinutes(60 * 12);
InvokeAsync(StateHasChanged); InvokeAsync(StateHasChanged);
} }
} }

View File

@ -28,5 +28,7 @@
</div> </div>
<script src="_framework/blazor.server.js"></script> <script src="_framework/blazor.server.js"></script>
<script src="~/js/echarts.min.js"></script>
<script src="~/js/bootstrap.min.js"></script>
</body> </body>
</html> </html>

View File

@ -12,8 +12,8 @@ builder.Services.AddTransient<LoggingService>();
builder.Services.AddTransient<DatabaseService>(); builder.Services.AddTransient<DatabaseService>();
builder.Services.AddSingleton<WcfService>(); builder.Services.AddSingleton<WcfService>();
builder.Services.AddTransient<DashboardService>(); builder.Services.AddTransient<DashboardService>();
builder.Services.AddTransient<JobService>(); builder.Services.AddTransient<HelperService>();
builder.Services.AddTransient<ImportService>(); builder.Services.AddTransient<ImportProfileService>();
var app = builder.Build(); var app = builder.Build();
@ -23,7 +23,6 @@ if (!app.Environment.IsDevelopment())
app.UseExceptionHandler("/Error"); app.UseExceptionHandler("/Error");
} }
app.UseStaticFiles(); app.UseStaticFiles();
app.UseRouting(); app.UseRouting();

View File

@ -1,10 +1,12 @@
@inherits LayoutComponentBase @using ECM.JobRunner.Web.Data;
@inherits LayoutComponentBase
@inject WcfService Wcf
<PageTitle>ECM.JobRunner.Web</PageTitle> <PageTitle>ECM.JobRunner.Web</PageTitle>
<div class="page"> <div class=@(connected ? "page connected" : "page disconnected")>
<div class="sidebar"> <div class="sidebar">
<NavMenu /> <NavMenu connected="connected" />
</div> </div>
<main> <main>
@ -17,3 +19,19 @@
</article> </article>
</main> </main>
</div> </div>
@code {
private bool connected = true;
protected override Task OnInitializedAsync()
{
Wcf.ConnectedChanged += Wcf_ConnectedChanged;
return Task.FromResult(true);
}
public void Wcf_ConnectedChanged(object? sender, bool status)
{
connected = status;
InvokeAsync(StateHasChanged);
}
}

View File

@ -1,6 +1,17 @@
<div class="top-row ps-3 navbar navbar-dark"> <div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid"> <div class="container-fluid">
<a class="navbar-brand" href="">ECM Job Runner</a> <a class="navbar-brand" href="">
ECM Job Runner
@if (!connected)
{
<span title="Offline!">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-emoji-dizzy text-danger" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path d="M9.146 5.146a.5.5 0 0 1 .708 0l.646.647.646-.647a.5.5 0 0 1 .708.708l-.647.646.647.646a.5.5 0 0 1-.708.708l-.646-.647-.646.647a.5.5 0 1 1-.708-.708l.647-.646-.647-.646a.5.5 0 0 1 0-.708zm-5 0a.5.5 0 0 1 .708 0l.646.647.646-.647a.5.5 0 1 1 .708.708l-.647.646.647.646a.5.5 0 1 1-.708.708L5.5 7.207l-.646.647a.5.5 0 1 1-.708-.708l.647-.646-.647-.646a.5.5 0 0 1 0-.708zM10 11a2 2 0 1 1-4 0 2 2 0 0 1 4 0z" />
</svg>
</span>
}
</a>
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu"> <button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
@ -46,6 +57,9 @@
</div> </div>
@code { @code {
[Parameter]
public bool connected { get; set; }
private bool collapseNavMenu = true; private bool collapseNavMenu = true;
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null; private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

View File

@ -9,6 +9,7 @@
"Config": { "Config": {
"ConnectionString": "", "ConnectionString": "",
"LogPath": "E:\\ECM\\JobRunner", "LogPath": "E:\\ECM\\JobRunner",
"LogDebug": true "LogDebug": true,
"LogJson": true
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -13,6 +13,7 @@ Namespace Scheduler.Jobs
Friend State As State Friend State As State
Friend Id As Integer Friend Id As Integer
Friend ExecutionId As String
Friend Name As String Friend Name As String
Friend ResultItems As New List(Of HistoryItem.HistoryStep) Friend ResultItems As New List(Of HistoryItem.HistoryStep)
@ -30,6 +31,7 @@ Namespace Scheduler.Jobs
Windream = oJobData.Item(Constants.Scheduler.JOB_CONFIG_WINDREAM) Windream = oJobData.Item(Constants.Scheduler.JOB_CONFIG_WINDREAM)
Logger = LogConfig.GetLogger() Logger = LogConfig.GetLogger()
ExecutionId = Guid.NewGuid.ToString()
Id = Integer.Parse(oArgs.Item("Id")) Id = Integer.Parse(oArgs.Item("Id"))
Name = oArgs.Item("Name") Name = oArgs.Item("Name")

View File

@ -39,15 +39,26 @@ Public Class State
LoadData() LoadData()
End Sub End Sub
Private Sub LoadData() Public Sub ReloadTypes()
_JobTypes = GetJobTypes() _JobTypes = GetJobTypes()
_ObjectTypes = GetObjectTypes() _ObjectTypes = GetObjectTypes()
End Sub
Public Sub ReloadJobs()
_JobDefinitions = GetJobDefinitions(_JobTypes) _JobDefinitions = GetJobDefinitions(_JobTypes)
End Sub
Public Sub ReloadProfiles()
_ProfileDefintions.ImportProfileSteps = GetImportProfileSteps() _ProfileDefintions.ImportProfileSteps = GetImportProfileSteps()
_ProfileDefintions.ImportProfiles = GetImportProfiles() _ProfileDefintions.ImportProfiles = GetImportProfiles()
End Sub End Sub
Private Sub LoadData()
ReloadTypes()
ReloadJobs()
ReloadProfiles()
End Sub
Private Function GetObjectTypes() As List(Of ObjectType) Private Function GetObjectTypes() As List(Of ObjectType)
Dim oObjectTypes As New List(Of ObjectType) Dim oObjectTypes As New List(Of ObjectType)
Try Try

View File

@ -16,6 +16,8 @@ Namespace WCF
Public Shared Database As MSSQLServer Public Shared Database As MSSQLServer
Public Shared Scheduler As JobScheduler Public Shared Scheduler As JobScheduler
Private ReadOnly Logger As Logger
''' <summary> ''' <summary>
''' See: https://stackoverflow.com/questions/42327988/addserviceendpoint-throws-key-is-null ''' See: https://stackoverflow.com/questions/42327988/addserviceendpoint-throws-key-is-null
''' </summary> ''' </summary>
@ -33,33 +35,41 @@ Namespace WCF
}) })
End Sub End Sub
Public Sub New()
Logger = LogConfig.GetLogger()
End Sub
Public Function GetHeartbeat() As Date Implements IJobRunner.GetHeartbeat Public Function GetHeartbeat() As Date Implements IJobRunner.GetHeartbeat
Return Now Return Now
End Function End Function
Public Function GetJobHistory() As GetJobStatus.GetJobStatusResponse Implements IJobRunner.GetJobStatus Public Function GetJobHistory() As GetJobStatus.GetJobStatusResponse Implements IJobRunner.GetJobStatus
Logger.Info("Calling Method [GetJobHistory]")
Dim oMethod As New GetJobStatus.GetJobStatusMethod(LogConfig, Database, State, Scheduler) Dim oMethod As New GetJobStatus.GetJobStatusMethod(LogConfig, Database, State, Scheduler)
Return oMethod.Run() Return oMethod.Run()
End Function End Function
Public Function GetJobConfig() As GetJobConfig.GetJobConfigResponse Implements IJobRunner.GetJobConfig Public Function GetJobConfig() As GetJobConfig.GetJobConfigResponse Implements IJobRunner.GetJobConfig
Logger.Info("Calling Method [GetJobConfig]")
Dim oMethod As New GetJobConfig.GetJobConfigMethod(LogConfig, Database, State) Dim oMethod As New GetJobConfig.GetJobConfigMethod(LogConfig, Database, State)
Return oMethod.Run() Return oMethod.Run()
End Function End Function
Public Function UpdateJob(pData As UpdateJob.UpdateJobRequest) As UpdateJob.UpdateJobResponse Implements IJobRunner.UpdateJob Public Function UpdateJob(pData As UpdateJob.UpdateJobRequest) As UpdateJob.UpdateJobResponse Implements IJobRunner.UpdateJob
Logger.Info("Calling Method [UpdateJob]")
Dim oMethod As New UpdateJob.UpdateJobMethod(LogConfig, Database, State, Scheduler) Dim oMethod As New UpdateJob.UpdateJobMethod(LogConfig, Database, State, Scheduler)
Return oMethod.Run(pData) Return oMethod.Run(pData)
End Function End Function
Public Function UpdateProfile(pData As UpdateProfile.UpdateProfileRequest) As UpdateProfile.UpdateProfileResponse Implements IJobRunner.UpdateProfile Public Function UpdateProfile(pData As UpdateProfile.UpdateProfileRequest) As UpdateProfile.UpdateProfileResponse Implements IJobRunner.UpdateProfile
Logger.Info("Calling Method [UpdateProfile]")
Dim oMethod As New UpdateProfile.UpdateProfileMethod(LogConfig, Database, State, Scheduler) Dim oMethod As New UpdateProfile.UpdateProfileMethod(LogConfig, Database, State, Scheduler)
Return oMethod.Run(pData) Return oMethod.Run(pData)
End Function End Function
Public Function RunJob(pData As RunJob.RunJobRequest) As RunJob.RunJobResponse Implements IJobRunner.RunJob Public Function RunJob(pData As RunJob.RunJobRequest) As RunJob.RunJobResponse Implements IJobRunner.RunJob
'Dim oMethod As New RunJob.RunJobMethod(LogConfig, Database, State, Scheduler) Dim oMethod As New RunJob.RunJobMethod(LogConfig, Database, State, Scheduler)
'Return oMethod.Run(pData) Return oMethod.Run(pData)
End Function End Function
End Class End Class

View File

@ -14,10 +14,10 @@ Public Class RunJob
Scheduler = pScheduler Scheduler = pScheduler
End Sub End Sub
Public Async Function Run(pData As RunJobRequest) As Task(Of RunJobResponse) Public Function Run(pData As RunJobRequest) As RunJobResponse
' This is calling the async function ScheduleJob synchronous, so that we can return a value to the caller ' This is calling the async function ScheduleJob synchronous, so that we can return a value to the caller
' This means that the job might or might not be scheduled when this method returns. ' This means that the job might or might not be scheduled when this method returns.
Task.Run(Function() Scheduler.ScheduleJob(pData.JobId)) Scheduler.ScheduleJob(pData.JobId)
Return New RunJobResponse() Return New RunJobResponse()
End Function End Function