diff --git a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/GenerateFileUploads/GenerateFileUploadsBootstrapper.cs b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/GenerateFileUploads/GenerateFileUploadsBootstrapper.cs index a05a57c..5eabbc8 100644 --- a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/GenerateFileUploads/GenerateFileUploadsBootstrapper.cs +++ b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/GenerateFileUploads/GenerateFileUploadsBootstrapper.cs @@ -10,7 +10,7 @@ /// /// /// - public class GenerateFileUploadsBootstrapper : BaseBoostrapper + public class GenerateFileUploadsJobBootstrapper : BaseBoostrapper { #region Methods diff --git a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/GenerateTransactions/GenerateTransactionsBootstrapper.cs b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/GenerateTransactions/GenerateTransactionsBootstrapper.cs index 50c3c8c..3a822f4 100644 --- a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/GenerateTransactions/GenerateTransactionsBootstrapper.cs +++ b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/GenerateTransactions/GenerateTransactionsBootstrapper.cs @@ -11,7 +11,7 @@ /// /// /// - public class GenerateTransactionsBootstrapper : BaseBoostrapper + public class GenerateTransactionsJobBootstrapper : BaseBoostrapper { #region Methods diff --git a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/ProcessSettlement/ProcessSettlementJob.cs b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/ProcessSettlement/ProcessSettlementJob.cs index 9161473..68e64c8 100644 --- a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/ProcessSettlement/ProcessSettlementJob.cs +++ b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/ProcessSettlement/ProcessSettlementJob.cs @@ -7,7 +7,6 @@ namespace TransactionProcessing.SchedulerService.Jobs { using System.Threading; - using Microsoft.Extensions.DependencyInjection; using Quartz; using SecurityService.Client; using SecurityService.DataTransferObjects.Responses; @@ -19,7 +18,7 @@ public class ProcessSettlementJob : IJob public ProcessSettlementJob(Func bootstrapperResolver) { - this.Bootstrapper = bootstrapperResolver(nameof(GenerateTransactionsJob)); + this.Bootstrapper = bootstrapperResolver(nameof(ProcessSettlementJob)); } /// @@ -67,23 +66,4 @@ public async Task Execute(IJobExecutionContext context) } } } - - public class ProcessSettlementBootstrapper : BaseBoostrapper - { - #region Methods - - /// - /// Configures the service additional. - /// - /// The job execution context. - public override void ConfigureServiceAdditional(IJobExecutionContext jobExecutionContext) - { - this.Services.AddSingleton(); - this.Services.AddSingleton(); - - this.Services.AddSingleton>(container => serviceName => { return jobExecutionContext.MergedJobDataMap.GetString(serviceName); }); - } - - #endregion - } } diff --git a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/ProcessSettlement/ProcessSettlementJobBootstrapper.cs b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/ProcessSettlement/ProcessSettlementJobBootstrapper.cs new file mode 100644 index 0000000..5e21547 --- /dev/null +++ b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService.Jobs/ProcessSettlement/ProcessSettlementJobBootstrapper.cs @@ -0,0 +1,27 @@ +namespace TransactionProcessing.SchedulerService.Jobs +{ + using System; + using Microsoft.Extensions.DependencyInjection; + using Quartz; + using SecurityService.Client; + using TransactionProcessor.Client; + + public class ProcessSettlementJobBootstrapper : BaseBoostrapper + { + #region Methods + + /// + /// Configures the service additional. + /// + /// The job execution context. + public override void ConfigureServiceAdditional(IJobExecutionContext jobExecutionContext) + { + this.Services.AddSingleton(); + this.Services.AddSingleton(); + + this.Services.AddSingleton>(container => serviceName => { return jobExecutionContext.MergedJobDataMap.GetString(serviceName); }); + } + + #endregion + } +} \ No newline at end of file diff --git a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService/Program.cs b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService/Program.cs index 6c95338..84c2884 100644 --- a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService/Program.cs +++ b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService/Program.cs @@ -48,6 +48,7 @@ public static IHostBuilder CreateHostBuilder(string[] args) webBuilder.UseConfiguration(config); webBuilder.UseKestrel(); }).ConfigureSilkierQuartzHost(); + return hostBuilder; } diff --git a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService/Properties/launchSettings.json b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService/Properties/launchSettings.json index c3c3f6b..e0fe19f 100644 --- a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService/Properties/launchSettings.json +++ b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService/Properties/launchSettings.json @@ -1,20 +1,12 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:64450", - "sslPort": 0 - } - }, "profiles": { - "SilkierQuartz.Example": { + "TransactionProcessing.SchedulerService": { "commandName": "Project", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "applicationUrl": "http://localhost:5000" + "applicationUrl": "http://localhost:9501/quartz" } } } \ No newline at end of file diff --git a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService/Startup.cs b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService/Startup.cs index 39a135e..917707f 100644 --- a/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService/Startup.cs +++ b/TransactionProcessing.SchedulerService/TransactionProcessing.SchedulerService/Startup.cs @@ -1,19 +1,64 @@ namespace TransactionProcessing.SchedulerService { using System; + using System.Collections.Generic; using System.Configuration; + using System.Linq; + using System.Reflection; + using System.Threading; + using System.Threading.Tasks; using Jobs; - using Jobs.GenerateTransactions; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; + using Quartz; using Quartz.Impl; using SilkierQuartz; + /// + /// + /// public class Startup { + #region Fields + + /// + /// The job bootstrappers + /// + private readonly List<(String name, IBootstrapper instance)> JobBootstrappers = new List<(String, IBootstrapper)>(); + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The web host environment. + public Startup(IWebHostEnvironment webHostEnvironment) + { + //this.Configuration = configuration; + IConfigurationBuilder builder = new ConfigurationBuilder().SetBasePath(webHostEnvironment.ContentRootPath) + .AddJsonFile("/home/txnproc/config/appsettings.json", true, true) + .AddJsonFile($"/home/txnproc/config/appsettings.{webHostEnvironment.EnvironmentName}.json", + optional:true).AddJsonFile("appsettings.json", optional:true, reloadOnChange:true) + .AddJsonFile($"appsettings.{webHostEnvironment.EnvironmentName}.json", + optional:true, + reloadOnChange:true).AddEnvironmentVariables(); + + Startup.Configuration = builder.Build(); + Startup.WebHostEnvironment = webHostEnvironment; + + var connectionString = Startup.Configuration.GetConnectionString("SchedulerReadModel"); + Startup.AddOrUpdateConnectionString("SchedulerReadModel", connectionString); + } + + #endregion + + #region Properties + /// /// Gets or sets the configuration. /// @@ -30,30 +75,23 @@ public class Startup /// public static IWebHostEnvironment WebHostEnvironment { get; set; } - public Startup(IWebHostEnvironment webHostEnvironment) - { - //this.Configuration = configuration; - IConfigurationBuilder builder = new ConfigurationBuilder().SetBasePath(webHostEnvironment.ContentRootPath) - .AddJsonFile("/home/txnproc/config/appsettings.json", true, true) - .AddJsonFile($"/home/txnproc/config/appsettings.{webHostEnvironment.EnvironmentName}.json", optional: true) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{webHostEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true) - .AddEnvironmentVariables(); + #endregion - Startup.Configuration = builder.Build(); - Startup.WebHostEnvironment = webHostEnvironment; - - var connectionString = Configuration.GetConnectionString("SchedulerReadModel"); - AddOrUpdateConnectionString("SchedulerReadModel", connectionString); - } + #region Methods - public static void AddOrUpdateConnectionString(string name, string connectionString) + /// + /// Adds the or update connection string. + /// + /// The name. + /// The connection string. + public static void AddOrUpdateConnectionString(String name, + String connectionString) { try { - var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); - var settings = configFile.ConnectionStrings.ConnectionStrings; - + Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); + ConnectionStringSettingsCollection settings = configFile.ConnectionStrings.ConnectionStrings; + if (settings[name] == null) { settings.Add(new ConnectionStringSettings(name, connectionString)); @@ -62,16 +100,23 @@ public static void AddOrUpdateConnectionString(string name, string connectionStr { settings[name].ConnectionString = connectionString; } + configFile.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection(configFile.AppSettings.SectionInformation.Name); } - catch (ConfigurationErrorsException) + catch(ConfigurationErrorsException) { Console.WriteLine("Error writing connection string"); } } - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + /// + /// Configures the specified application. + /// + /// The application. + /// The env. + public void Configure(IApplicationBuilder app, + IWebHostEnvironment env) { if (env.IsDevelopment()) { @@ -88,52 +133,71 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseAuthorization(); app.UseSilkierQuartz(); - app.UseEndpoints(endpoints => - { - endpoints.MapRazorPages(); - }); + app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); } - - + /// + /// Configures the services. + /// + /// The services. public void ConfigureServices(IServiceCollection services) { - services.AddSingleton>(container => (type) => + services.AddSingleton>(container => type => { - switch (type) - { - case "GenerateTransactionsJob": - return new GenerateTransactionsBootstrapper(); - case "GenerateFileUploadsJob": - return new GenerateFileUploadsBootstrapper(); - case "ProcessSettlementJob": - return new ProcessSettlementBootstrapper(); - } - - return null; + (String name, IBootstrapper instance) bootstrapper = + this.JobBootstrappers.SingleOrDefault(b => b.name == $"{type}Bootstrapper"); + return bootstrapper.instance; }); services.AddRazorPages(); - - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSilkierQuartz(s => - { - s.VirtualPathRoot = "/quartz"; - s.UseLocalTime = true; - s.DefaultDateFormat = "yyyy-MM-dd"; - s.DefaultTimeFormat = "HH:mm:ss"; - s.Scheduler = StdSchedulerFactory.GetDefaultScheduler().Result; - - }, - a => - { - a.AccessRequirement = SilkierQuartzAuthenticationOptions.SimpleAccessRequirement.AllowAnonymous; - }); + this.RegisterJobBootstrappers(); + this.RegisterJobs(services); + IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler().Result; + services.AddSilkierQuartz(s => + { + s.VirtualPathRoot = "/quartz"; + s.UseLocalTime = true; + s.DefaultDateFormat = "yyyy-MM-dd"; + s.DefaultTimeFormat = "HH:mm:ss"; + s.Scheduler = scheduler; + }, + a => { a.AccessRequirement = SilkierQuartzAuthenticationOptions.SimpleAccessRequirement.AllowAnonymous; }); + } + + /// + /// Registers the job bootstrappers. + /// + private void RegisterJobBootstrappers() + { + IEnumerable jobs = typeof(IBootstrapper).GetTypeInfo().Assembly.DefinedTypes + .Where(t => typeof(IBootstrapper).GetTypeInfo().IsAssignableFrom(t.AsType()) && t.IsClass && + t.IsAbstract == false).Select(p => p.AsType()); + + foreach (Type job in jobs) + { + Object instance = Activator.CreateInstance(job); + this.JobBootstrappers.Add((job.Name, (IBootstrapper)instance)); + } } + + /// + /// Registers the jobs. + /// + /// The services. + private void RegisterJobs(IServiceCollection services) + { + Type type = typeof(IJob); + IEnumerable jobs = AppDomain.CurrentDomain.GetAssemblies().SelectMany(s => s.GetTypes()).Where(p => type.IsAssignableFrom(p) && p.IsInterface == false); + + foreach (Type job in jobs) + { + services.AddSingleton(job); + } + } + + #endregion } } \ No newline at end of file