diff --git a/Global.asax.cs b/Global.asax.cs index 9169c81f..44cd6886 100644 --- a/Global.asax.cs +++ b/Global.asax.cs @@ -1,4 +1,5 @@ -using System; +using ReportBuilder.Web.Jobs; +using System; using System.Collections.Generic; using System.Linq; using System.Web; @@ -12,6 +13,7 @@ public class MvcApplication : System.Web.HttpApplication protected void Application_Start() { RouteConfig.RegisterRoutes(RouteTable.Routes); + JobScheduler.Start(); } } } diff --git a/Jobs/DotNetReportJob.cs b/Jobs/DotNetReportJob.cs new file mode 100644 index 00000000..21234593 --- /dev/null +++ b/Jobs/DotNetReportJob.cs @@ -0,0 +1,94 @@ +using Newtonsoft.Json; +using Quartz; +using Quartz.Impl; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using System.Web; + +namespace ReportBuilder.Web.Jobs +{ + public class ReportSchedule + { + public string Schedule { get; set; } + public string EmailTo { get; set; } + public DateTime? LastRun { get; set; } + public DateTime? NextRun { get; set; } + public string UserId { get; set; } + } + public class ReportWithSchedule + { + public int Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public string DataConnectName { get; set; } + public List Schedules { get; set; } + + } + public class JobScheduler + { + public static async void Start() + { + var schedulerFactory = new StdSchedulerFactory(); + var scheduler = await schedulerFactory.GetScheduler(); + await scheduler.Start(); + + IJobDetail job = JobBuilder.Create() + .WithIdentity("DotNetReportJob") + .StoreDurably() + .Build(); + + ITrigger trigger = TriggerBuilder.Create() + .WithIdentity("DotNetReportJobTrigger") + .StartNow() + .WithSimpleSchedule(s => s.WithIntervalInSeconds(60).RepeatForever()) + .Build(); + + await scheduler.ScheduleJob(job, trigger); + + } + } + + public class DotNetReportJob : IJob + { + async Task IJob.Execute(IJobExecutionContext context) + { + var apiUrl = ConfigurationManager.AppSettings["dotNetReport.apiUrl"]; + var accountApiKey = ConfigurationManager.AppSettings["dotNetReport.accountApiToken"]; + var databaseApiKey = ConfigurationManager.AppSettings["dotNetReport.dataconnectApiToken"]; + var clientId = ""; // you can specify client id here if needed + + // Get all reports with schedule and run the ones that are due + using (var client = new HttpClient()) + { + var response = await client.GetAsync($"{apiUrl}/ReportApi/GetScheduledReports?account={accountApiKey}&dataConnect={databaseApiKey}&clientId={clientId}"); + + response.EnsureSuccessStatusCode(); + + var content = await response.Content.ReadAsStringAsync(); + var reports = JsonConvert.DeserializeObject>(content); + + foreach(var report in reports) + { + foreach(var schedule in report.Schedules) + { + try + { + var chron = new CronExpression(schedule.Schedule); + var nextRun = chron.GetTimeAfter(DateTimeOffset.UtcNow); + + schedule.NextRun = null; + } + catch(Exception ex) + { + schedule.NextRun = null; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/ReportBuilder.Web.csproj b/ReportBuilder.Web.csproj index 4143b3e2..3b412b03 100644 --- a/ReportBuilder.Web.csproj +++ b/ReportBuilder.Web.csproj @@ -13,7 +13,7 @@ Properties ReportBuilder.Web ReportBuilder.Web - v4.5 + v4.6.1 true @@ -60,8 +60,12 @@ packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + + packages\Quartz.3.0.7\lib\net452\Quartz.dll + + @@ -276,6 +280,7 @@ Global.asax + diff --git a/ReportBuilder.Web.sln b/ReportBuilder.Web.sln index f5734e9f..759ffb8f 100644 --- a/ReportBuilder.Web.sln +++ b/ReportBuilder.Web.sln @@ -12,8 +12,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{7ECE70 .nuget\NuGet.targets = .nuget\NuGet.targets EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReportBuilder.ScheduleJob", "..\ReportBuilder.ScheduleJob\ReportBuilder.ScheduleJob.csproj", "{10A52487-7E03-4A11-9D44-8DF7FF1AABE5}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -24,10 +22,6 @@ Global {AFDCDA4C-8F56-46E1-8E07-ABFC39537EDE}.Debug|Any CPU.Build.0 = Debug|Any CPU {AFDCDA4C-8F56-46E1-8E07-ABFC39537EDE}.Release|Any CPU.ActiveCfg = Release|Any CPU {AFDCDA4C-8F56-46E1-8E07-ABFC39537EDE}.Release|Any CPU.Build.0 = Release|Any CPU - {10A52487-7E03-4A11-9D44-8DF7FF1AABE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {10A52487-7E03-4A11-9D44-8DF7FF1AABE5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {10A52487-7E03-4A11-9D44-8DF7FF1AABE5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {10A52487-7E03-4A11-9D44-8DF7FF1AABE5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/packages.config b/packages.config index 07fe238b..14e4487c 100644 --- a/packages.config +++ b/packages.config @@ -17,6 +17,7 @@ + \ No newline at end of file