diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 0000000..62aef73 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,13 @@ +categories: + - title: '🚀 Features' + labels: + - 'feature' + - title: '🐛 Bug Fixes' + labels: + - 'bug' + - title: '🧰 Maintenance' + label: 'maintenance' +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +template: | + ## Changes + $CHANGES diff --git a/.github/workflows/createrelease.yml b/.github/workflows/createrelease.yml new file mode 100644 index 0000000..e5da2e3 --- /dev/null +++ b/.github/workflows/createrelease.yml @@ -0,0 +1,121 @@ +name: Release + +on: + release: + types: [published] + +jobs: + buildlinux: + name: "Release" + env: + ASPNETCORE_ENVIRONMENT: "Production" + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2.3.4 + + - name: Get the version + id: get_version + run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//} + + - name: Restore Nuget Packages + run: dotnet restore FileFormatConversion.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} + + - name: Build Code + run: dotnet build FileFormatConversion.sln --configuration Release + + #- name: Publish Images to Docker Hub - Pre Release + # if: ${{ github.event.release.prerelease == true }} + # run: | + # docker build . --file TransactionProcessor/Dockerfile --tag stuartferguson/transactionprocessor:dev + # docker login --username=${{ secrets.DOCKER_USERNAME }} --password=${{ secrets.DOCKER_PASSWORD }} + # docker push stuartferguson/transactionprocessor:dev + + #- name: Publish Images to Docker Hub - Formal Release + # if: ${{ github.event.release.prerelease == false }} + # run: | + # docker build . --file TransactionProcessor/Dockerfile --tag stuartferguson/transactionprocessor:latest + # docker login --username=${{ secrets.DOCKER_USERNAME }} --password=${{ secrets.DOCKER_PASSWORD }} + # docker push stuartferguson/transactionprocessor:latest + + - name: Publish API + if: ${{ github.event.release.prerelease == false }} + run: dotnet publish "FileFormatConversion\FileFormatConversion.csproj" --configuration Release --output publishOutput -r win-x64 --self-contained + + - name: Build Release Package + run: | + cd /home/runner/work/FileFormatConversion/FileFormatConversion/publishOutput + zip -r ../fileformatconversion.zip ./* + + - name: Upload the artifact + uses: actions/upload-artifact@v4.4.0 + with: + name: fileformatconversion + path: fileformatconversion.zip + + deploystaging: + runs-on: stagingserver + needs: buildlinux + environment: staging + name: "Deploy to Staging" + + steps: + - name: Download the artifact + uses: actions/download-artifact@v4.1.8 + with: + name: fileformatconversion + + - name: Remove existing Windows service + run: | + $serviceName = "Transaction Processing - File Format Conversion" + # Check if the service exists + if (Get-Service -Name $serviceName -ErrorAction SilentlyContinue) { + Stop-Service -Name $serviceName + sc.exe delete $serviceName + } + + - name: Unzip the files + run: | + Expand-Archive -Path fileformatconversion.zip -DestinationPath "C:\txnproc\transactionprocessing\fileformatconversion" -Force + + - name: Install as a Windows service + run: | + $serviceName = "Transaction Processing - File Format Conversion" + $servicePath = "C:\txnproc\transactionprocessing\fileformatconversion\FileFormatConversion.exe" + + New-Service -Name $serviceName -BinaryPathName $servicePath -Description "Transaction Processing - File Format Conversion" -DisplayName "Transaction Processing - File Format Conversion" -StartupType Automatic + Start-Service -Name $serviceName + + deployproduction: + runs-on: productionserver + needs: [buildlinux, deploystaging] + environment: production + name: "Deploy to Production" + + steps: + - name: Download the artifact + uses: actions/download-artifact@v4.1.8 + with: + name: fileformatconversion + + - name: Remove existing Windows service + run: | + $serviceName = "Transaction Processing - File Format Conversion" + # Check if the service exists + if (Get-Service -Name $serviceName -ErrorAction SilentlyContinue) { + Stop-Service -Name $serviceName + sc.exe delete $serviceName + } + + - name: Unzip the files + run: | + Expand-Archive -Path fileformatconversion.zip -DestinationPath "C:\txnproc\transactionprocessing\fileformatconversion" -Force + + - name: Install as a Windows service + run: | + $serviceName = "Transaction Processing - File Format Conversion" + $servicePath = "C:\txnproc\transactionprocessing\fileformatconversion\FileFormatConversion.exe" + + New-Service -Name $serviceName -BinaryPathName $servicePath -Description "Transaction Processing - File Format Conversion" -DisplayName "Transaction Processing - File Format Conversion" -StartupType Automatic + Start-Service -Name $serviceName diff --git a/.github/workflows/prlinked.yml b/.github/workflows/prlinked.yml new file mode 100644 index 0000000..84037c8 --- /dev/null +++ b/.github/workflows/prlinked.yml @@ -0,0 +1,47 @@ +name: Move Linked Issues + +on: + pull_request: + types: + - opened + - synchronize + - reopened + +jobs: + get-date: + runs-on: ubuntu-latest + outputs: + project_name_prefix: ${{ steps.format_date.outputs.formatted_date }} + steps: + - name: Get PR creation date + id: format_date + run: | + # Extract the month and year from the PR creation date + PR_DATE="${{ github.event.pull_request.created_at }}" + FORMATTED_DATE=$(date -d "$PR_DATE" "+%B %Y") # Format to Month Year + + # Debugging: print out the formatted date + echo "Formatted Date: ${FORMATTED_DATE} Sprint" + + # Set output using the Environment File method + echo "formatted_date=${FORMATTED_DATE} Sprint" >> $GITHUB_OUTPUT # Set the output for later jobs + + debug-date: + needs: get-date + runs-on: ubuntu-latest + steps: + - name: Debug the outputs + run: | + echo "PR Number: ${{ github.event.pull_request.number }}" + echo "Project Column Name: Review" + echo "Project Name Prefix (from get-date job output): ${{ needs.get-date.outputs.project_name_prefix }}" # Access the output correctly + + move-issues: + needs: get-date + uses: TransactionProcessing/org-ci-workflows/.github/workflows/move-linked-issue.yml@main + with: + pr_number: ${{ github.event.pull_request.number }} + project_column_name: "Review" + project_name_prefix: ${{ needs.get-date.outputs.project_name_prefix }} # Access the output from get-date job + secrets: + gh_token: ${{ secrets.GH_TOKEN }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml new file mode 100644 index 0000000..b5f1c63 --- /dev/null +++ b/.github/workflows/pullrequest.yml @@ -0,0 +1,35 @@ +name: Build and Test Pull Requests + +on: + pull_request: + branches: + - main + +jobs: + build: + name: "Build and Test Pull Requests" + env: + ASPNETCORE_ENVIRONMENT: "Production" + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2.3.4 + + - name: Restore Nuget Packages + run: dotnet restore FileFormatConversion.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} + + - name: Build Code + run: dotnet build FileFormatConversion.sln --configuration Release + + #- name: Build Docker Image + # run: docker build . --file TransactionProcessor/Dockerfile --tag transactionprocessor:latest + + #- name: Run Integration Tests + # run: dotnet test "TransactionProcessor.IntegrationTests\TransactionProcessor.IntegrationTests.csproj" --filter Category=PRTest --logger "trx;LogFileName=test-results.trx" + + - uses: actions/upload-artifact@v4.4.0 + if: ${{ failure() }} + with: + name: tracelogs + path: /home/txnproc/trace/ diff --git a/.github/workflows/release-management.yml b/.github/workflows/release-management.yml new file mode 100644 index 0000000..79b1204 --- /dev/null +++ b/.github/workflows/release-management.yml @@ -0,0 +1,16 @@ +name: Release Management + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - master + +jobs: + update_draft_release: + runs-on: ubuntu-latest + steps: + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: toolmantim/release-drafter@v5.12.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/repository_maintenance.yml b/.github/workflows/repository_maintenance.yml new file mode 100644 index 0000000..dda1d49 --- /dev/null +++ b/.github/workflows/repository_maintenance.yml @@ -0,0 +1,20 @@ +name: Maintenance Tasks + +on: + repository_dispatch: + workflow_dispatch: + schedule: + - cron: '0 0 * * *' # This schedule runs the workflow at midnight every day + +jobs: + cleanup-stale-branches: + runs-on: ubuntu-latest + steps: + - name: Cleanup Stale Branches + uses: cbrgm/cleanup-stale-branches-action@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + repository: ${{ github.repository }} + last-commit-age-days: 60 + dry-run: false + rate-limit: true diff --git a/.github/workflows/use_central_workflow.yml b/.github/workflows/use_central_workflow.yml new file mode 100644 index 0000000..fea6f93 --- /dev/null +++ b/.github/workflows/use_central_workflow.yml @@ -0,0 +1,9 @@ +name: Move Task on PR Assignment +on: + pull_request: + types: [assigned] + +jobs: + move_task: + uses: TransactionProcessing/org-ci-workflows/.github/workflows/move_task.yml@main + secrets: inherit diff --git a/FileFormatConversion.sln b/FileFormatConversion.sln new file mode 100644 index 0000000..1aa9e55 --- /dev/null +++ b/FileFormatConversion.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36109.1 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileFormatConversion", "FileFormatConversion\FileFormatConversion.csproj", "{A07E7D02-0D79-472D-A5CF-784251BED2CA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A07E7D02-0D79-472D-A5CF-784251BED2CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A07E7D02-0D79-472D-A5CF-784251BED2CA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A07E7D02-0D79-472D-A5CF-784251BED2CA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A07E7D02-0D79-472D-A5CF-784251BED2CA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9D7FCEE5-F6C9-4738-BBDF-3C2E470F80C2} + EndGlobalSection +EndGlobal diff --git a/FileFormatConversion/BusinessLogic/FileSystemWatcherManager.cs b/FileFormatConversion/BusinessLogic/FileSystemWatcherManager.cs new file mode 100644 index 0000000..f7209f5 --- /dev/null +++ b/FileFormatConversion/BusinessLogic/FileSystemWatcherManager.cs @@ -0,0 +1,178 @@ +using Azure.Core.Pipeline; +using Shared.Logger; +using Syncfusion.HtmlConverter; +using Syncfusion.Pdf; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using SimpleResults; + +namespace FileFormatConversion.BusinessLogic +{ + public interface IFileSystemWatcherManager{ + void InitialiseManger(); + void StartFileSystemWatchers(); + } + public class FileSystemWatcherManager : IFileSystemWatcherManager + { + private readonly IFileHandler FileHandler; + public FileSystemWatcherManager(IFileHandler fileHandler) { + this.FileHandler = fileHandler; + this.FileSystemWatchers = new List(); + } + + private readonly List FileSystemWatchers; + + public void InitialiseManger() { + // Load up the file configuration + IEnumerable fileProfiles = Startup.Configuration.GetSection("AppSettings:FileProfiles").GetChildren().ToList().Select(x => new + { + Name = x.GetValue("Name"), + ListeningDirectory = x.GetValue("ListeningDirectory"), + OutputDirectory = x.GetValue("OutputDirectory"), + Filter = x.GetValue("Filter"), + }).Select(f => new FileProfile(f.Name, f.ListeningDirectory, f.OutputDirectory, f.Filter)); + + foreach (FileProfile fileProfile in fileProfiles) { + this.SetupFileSystemWatcher(fileProfile); + } + } + + public void StartFileSystemWatchers() { + foreach (TaggedFileSystemWatcher fsw in this.FileSystemWatchers) { + Logger.LogInformation($"About to start File System Watcher {fsw.Tag}"); + fsw.Start(); + Logger.LogInformation($"Started File System Watcher {fsw.Tag}"); + } + } + + public void SetupFileSystemWatcher(FileProfile fileProfile) { + Logger.LogInformation($"About to Setup FileSystemWatcher for {fileProfile.Name}"); + + // make sure all the directories exist + CreateDirectoryWithLogging(fileProfile.ListeningDirectory); + CreateDirectoryWithLogging($"{fileProfile.ListeningDirectory}\\processed"); + CreateDirectoryWithLogging($"{fileProfile.ListeningDirectory}\\failed"); + CreateDirectoryWithLogging(fileProfile.OutputDirectory); + CreateDirectoryWithLogging($"{fileProfile.OutputDirectory}\\processed"); + CreateDirectoryWithLogging($"{fileProfile.OutputDirectory}\\failed"); + + // Create the file system watcher + FileSystemWatcher fsw = new(fileProfile.ListeningDirectory, fileProfile.Filter); + fsw.Created += (sender, + e) => this.FileHandler.FileCreated(sender, e, fileProfile); + fsw.Error += (sender, + e) => this.FileHandler.FileError(sender, e, fileProfile); + TaggedFileSystemWatcher taggedFileSystemWatcher = new TaggedFileSystemWatcher(fsw, fileProfile.Name); + this.FileSystemWatchers.Add(taggedFileSystemWatcher); + } + + static void CreateDirectoryWithLogging(String directory) { + // Check if the directory exists, if not create it + if (!Directory.Exists(directory)) { + Logger.LogInformation($"Directory {directory} does not exist, creating it now."); + // Create the directory + Directory.CreateDirectory(directory); + } + } + } + + public class TaggedFileSystemWatcher + { + public string Tag { get; } + public FileSystemWatcher Watcher { get; } + + public TaggedFileSystemWatcher(FileSystemWatcher watcher, string tag) + { + Tag = tag; + Watcher = watcher; + } + + public void Start() => Watcher.EnableRaisingEvents = true; + public void Stop() => Watcher.EnableRaisingEvents = false; + } + + public interface IFileHandler { + void FileCreated(object sender, + FileSystemEventArgs e, + FileProfile fileProfile); + + void FileError(object sender, + ErrorEventArgs e, + FileProfile fileProfile); + } + public class FileHandler : IFileHandler { + private readonly IPDFGenerator PdfGenerator; + + public FileHandler(IPDFGenerator pdfGenerator) { + this.PdfGenerator = pdfGenerator; + } + public void FileCreated(object sender, + FileSystemEventArgs e, + FileProfile fileProfile) { + String fileName = Path.GetFileNameWithoutExtension(e.FullPath); + Logger.LogWarning($"File detected {fileName} on file profile {fileProfile.Name}."); + String contents = File.ReadAllText(e.FullPath); + Logger.LogInformation("About to create PDF"); + Result createPdfResult = this.PdfGenerator.CreatePDF(contents); + if (createPdfResult.IsFailed) { + // Move the file to the failed directory + Logger.LogWarning($"Failed to create PDF: {createPdfResult.Message}"); + File.Move(e.FullPath, Path.Combine($"{fileProfile.ListeningDirectory}\\Failed", e.Name)); + Logger.LogInformation($"Moved file {e.FullPath} to {fileProfile.ListeningDirectory}\\Failed"); + return; + } + Logger.LogInformation("PDF Created as base64 string"); + File.WriteAllText($"{fileProfile.OutputDirectory}\\{fileName}", createPdfResult.Data); + Logger.LogInformation($"Output file written to {fileProfile.OutputDirectory}\\{fileName}"); + // Move the processed file + File.Move(e.FullPath, Path.Combine($"{fileProfile.ListeningDirectory}\\Processed", e.Name)); + Logger.LogInformation($"Moved file {e.FullPath} to {fileProfile.ListeningDirectory}\\Processed"); + } + + public void FileError(object sender, + ErrorEventArgs e, + FileProfile fileProfile) { + // TODO: Log the error + } + } + + public interface IPDFGenerator + { + #region Methods + + Result CreatePDF(String htmlString); + + #endregion + } + + [ExcludeFromCodeCoverage] + public class PDFGenerator : IPDFGenerator { + private readonly HtmlToPdfConverter Converter; + public PDFGenerator() { + BlinkConverterSettings settings = new BlinkConverterSettings + { + EnableJavaScript = false + }; + settings.CommandLineArguments.Add("--headless"); + this.Converter = new HtmlToPdfConverter(HtmlRenderingEngine.Blink) { ConverterSettings = settings }; + } + + #region Methods + public Result CreatePDF(String htmlString) + { + try { + PdfDocument? pdf = this.Converter.Convert(htmlString, ""); + MemoryStream stream = new(); + pdf.Save(stream); + pdf.Close(); + String base64 = Convert.ToBase64String(stream.ToArray()); + return Result.Success(base64); + } + catch (Exception ex) { + return Result.Failure(ex.Message); + } + } + + #endregion + } +} diff --git a/FileFormatConversion/FileFormatConversion.csproj b/FileFormatConversion/FileFormatConversion.csproj new file mode 100644 index 0000000..70dd7b9 --- /dev/null +++ b/FileFormatConversion/FileFormatConversion.csproj @@ -0,0 +1,34 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + + + + + + + Always + + + Always + + + diff --git a/FileFormatConversion/Program.cs b/FileFormatConversion/Program.cs new file mode 100644 index 0000000..d1019cd --- /dev/null +++ b/FileFormatConversion/Program.cs @@ -0,0 +1,220 @@ +using FileFormatConversion.BusinessLogic; +using Lamar; +using NLog; +using NLog.Extensions.Logging; +using Shared.Extensions; +using Shared.General; + +namespace FileFormatConversion +{ + using Lamar.Microsoft.DependencyInjection; + using Microsoft.AspNetCore.Diagnostics.HealthChecks; + using Microsoft.AspNetCore.Hosting; + using Microsoft.Extensions.Configuration; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Logging; + using System.Diagnostics.CodeAnalysis; + using System.IO; + using System.Reflection; + + [ExcludeFromCodeCoverage] + public class Program + { + public static void Main(string[] args) + { + Program.CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) + { + //At this stage, we only need our hosting file for ip and ports + FileInfo fi = new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location); + + IConfigurationRoot config = new ConfigurationBuilder().SetBasePath(fi.Directory.FullName) + .AddJsonFile("hosting.json", optional: true) + .AddJsonFile("hosting.development.json", optional: true) + .AddEnvironmentVariables().Build(); + + IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args); + hostBuilder.UseWindowsService(); + hostBuilder.UseLamar(); + hostBuilder.ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + webBuilder.UseConfiguration(config); + webBuilder.UseKestrel(); + }); + + return hostBuilder; + } + } + + [ExcludeFromCodeCoverage] + public class Startup + { + #region Fields + + public static Container Container; + + public static List AutoApiLogonOperators = new List(); + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The web host environment. + public Startup(IWebHostEnvironment webHostEnvironment) + { + 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; + } + + #endregion + + #region Properties + + /// + /// Gets or sets the configuration. + /// + /// + /// The configuration. + /// + public static IConfigurationRoot Configuration { get; set; } + + public static IServiceProvider ServiceProvider { get; set; } + + /// + /// Gets or sets the web host environment. + /// + /// + /// The web host environment. + /// + public static IWebHostEnvironment WebHostEnvironment { get; set; } + + #endregion + + #region Methods + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + /// + /// Configures the specified application. + /// + /// The application. + /// The env. + /// The logger factory. + /// The provider. + public void Configure(IApplicationBuilder app, + IWebHostEnvironment env, + ILoggerFactory loggerFactory) + { + ConfigurationReader.Initialise(Startup.Configuration); + + String nlogConfigFilename = "nlog.config"; + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + string directoryPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + LogManager.AddHiddenAssembly(Assembly.LoadFrom(Path.Combine(directoryPath, "Shared.dll"))); + + var developmentNlogConfigFilename = "nlog.development.config"; + if (File.Exists(Path.Combine(env.ContentRootPath, developmentNlogConfigFilename))) + { + nlogConfigFilename = developmentNlogConfigFilename; + } + } + else + { + LogManager.AddHiddenAssembly(Assembly.LoadFrom(Path.Combine(env.ContentRootPath, "Shared.dll"))); + } + + loggerFactory.ConfigureNLog(Path.Combine(env.ContentRootPath, nlogConfigFilename)); + loggerFactory.AddNLog(); + + ILogger logger = loggerFactory.CreateLogger("FileFormatConversion"); + + Shared.Logger.Logger.Initialise(logger); + + Startup.Configuration.LogConfiguration(Shared.Logger.Logger.LogWarning); + + //foreach (KeyValuePair type in TypeMap.Map) + //{ + // Shared.Logger.Logger.LogInformation($"Type name {type.Value} mapped to {type.Key.Name}"); + //} + + //app.AddRequestLogging(); + //app.AddResponseLogging(); + //app.AddExceptionHandler(); + + //app.UseRouting(); + + //app.UseAuthentication(); + //app.UseAuthorization(); + //app.UseMetricServer(s => { + //}); + //app.UseEndpoints(endpoints => { + // endpoints.MapControllers(); + // endpoints.MapHealthChecks("health", + // new HealthCheckOptions + // { + // Predicate = _ => true, + // ResponseWriter = Shared.HealthChecks.HealthCheckMiddleware.WriteResponse + // }); + // endpoints.MapHealthChecks("healthui", + // new HealthCheckOptions + // { + // Predicate = _ => true, + // ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse + // }); + //}); + + //app.UseSwagger(); + + //app.UseSwaggerUI(); + + app.PreWarm(); + + //Environment.SetEnvironmentVariable("SYNCFUSION_LICENSE_LOGGING", "1"); + //Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("Mgo+DSMBMAY9C3t2XFhhQlJHfV5AQmBIYVp/TGpJfl96cVxMZVVBJAtUQF1hTH5WdkxiWH9ec31QTmldWkZ/"); + + } + + public void ConfigureContainer(ServiceRegistry services) + { + ConfigurationReader.Initialise(Startup.Configuration); + + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + + Startup.Container = new Container(services); + + Startup.ServiceProvider = services.BuildServiceProvider(); + } + } + + public static class Extensions + { + public static void PreWarm(this IApplicationBuilder app) + { + IFileSystemWatcherManager fileSystemWatcherManager = Startup.Container.GetInstance(); + fileSystemWatcherManager.InitialiseManger(); + fileSystemWatcherManager.StartFileSystemWatchers(); + } + } + + public record FileProfile(String Name, String ListeningDirectory, String OutputDirectory, String Filter); + + #endregion +} diff --git a/FileFormatConversion/Properties/launchSettings.json b/FileFormatConversion/Properties/launchSettings.json new file mode 100644 index 0000000..cd46d69 --- /dev/null +++ b/FileFormatConversion/Properties/launchSettings.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:24954", + "sslPort": 0 + } + }, + "profiles": { + "FileFormatConversion": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/FileFormatConversion/appsettings.Development.json b/FileFormatConversion/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/FileFormatConversion/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/FileFormatConversion/appsettings.json b/FileFormatConversion/appsettings.json new file mode 100644 index 0000000..308573b --- /dev/null +++ b/FileFormatConversion/appsettings.json @@ -0,0 +1,21 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AppSettings": { + "FileProfiles": [ + { + "Name": "Merchant Statements", + "ListeningDirectory": "c:\\temp\\statements\\inbound", + "OutputDirectory": "c:\\temp\\statements\\outbound", + "Filter": "*.html" + + } + ] + } +} + + diff --git a/FileFormatConversion/hosting.json b/FileFormatConversion/hosting.json new file mode 100644 index 0000000..c839650 --- /dev/null +++ b/FileFormatConversion/hosting.json @@ -0,0 +1,3 @@ +{ + "urls": "http://*:5012" +} \ No newline at end of file diff --git a/FileFormatConversion/nlog.config b/FileFormatConversion/nlog.config new file mode 100644 index 0000000..6b6548d --- /dev/null +++ b/FileFormatConversion/nlog.config @@ -0,0 +1,47 @@ + + + + + + + + + + + +s + + + + + + + + + + + + + + \ No newline at end of file