diff --git a/src/AWS.Deploy.CLI/Commands/GenerateDeploymentProjectCommand.cs b/src/AWS.Deploy.CLI/Commands/GenerateDeploymentProjectCommand.cs index 5d39cdf9b..5200acb9e 100644 --- a/src/AWS.Deploy.CLI/Commands/GenerateDeploymentProjectCommand.cs +++ b/src/AWS.Deploy.CLI/Commands/GenerateDeploymentProjectCommand.cs @@ -101,7 +101,7 @@ public override async Task ExecuteAsync(CommandContext context, GenerateDep } } - cdkProjectHandler.CreateCdkProject(selectedRecommendation, session, saveDirectory); + await cdkProjectHandler.CreateCdkProject(selectedRecommendation, session, saveDirectory); await GenerateDeploymentRecipeSnapShot(selectedRecommendation, saveDirectory, projectDisplayName, targetApplicationFullPath); var saveCdkDirectoryFullPath = directoryManager.GetDirectoryInfo(saveDirectory).FullName; diff --git a/src/AWS.Deploy.Orchestration/AWS.Deploy.Orchestration.csproj b/src/AWS.Deploy.Orchestration/AWS.Deploy.Orchestration.csproj index 3ac9640ff..37c8f0055 100644 --- a/src/AWS.Deploy.Orchestration/AWS.Deploy.Orchestration.csproj +++ b/src/AWS.Deploy.Orchestration/AWS.Deploy.Orchestration.csproj @@ -26,9 +26,9 @@ - - - + + + diff --git a/src/AWS.Deploy.Orchestration/CdkProjectHandler.cs b/src/AWS.Deploy.Orchestration/CdkProjectHandler.cs index e60ff9963..8231f77a2 100644 --- a/src/AWS.Deploy.Orchestration/CdkProjectHandler.cs +++ b/src/AWS.Deploy.Orchestration/CdkProjectHandler.cs @@ -16,7 +16,7 @@ namespace AWS.Deploy.Orchestration public interface ICdkProjectHandler { Task ConfigureCdkProject(OrchestratorSession session, CloudApplication cloudApplication, Recommendation recommendation); - string CreateCdkProject(Recommendation recommendation, OrchestratorSession session, string? saveDirectoryPath = null); + Task CreateCdkProject(Recommendation recommendation, OrchestratorSession session, string? saveDirectoryPath = null); Task DeployCdkProject(OrchestratorSession session, CloudApplication cloudApplication, string cdkProjectPath, Recommendation recommendation); void DeleteTemporaryCdkProject(string cdkProjectPath); Task PerformCdkDiff(string cdkProjectPath, CloudApplication cloudApplication); @@ -71,7 +71,7 @@ public async Task ConfigureCdkProject(OrchestratorSession session, Cloud { // Create a new temporary CDK project for a new deployment _interactiveService.LogInfoMessage("Generating AWS Cloud Development Kit (AWS CDK) deployment project"); - cdkProjectPath = CreateCdkProject(recommendation, session); + cdkProjectPath = await CreateCdkProject(recommendation, session); } // Write required configuration in appsettings.json @@ -255,7 +255,7 @@ private async Task CheckCdkDeploymentFailure(string stackId, DateTime deployment } } - public string CreateCdkProject(Recommendation recommendation, OrchestratorSession session, string? saveCdkDirectoryPath = null) + public async Task CreateCdkProject(Recommendation recommendation, OrchestratorSession session, string? saveCdkDirectoryPath = null) { string? assemblyName; if (string.IsNullOrEmpty(saveCdkDirectoryPath)) @@ -278,7 +278,7 @@ public string CreateCdkProject(Recommendation recommendation, OrchestratorSessio _directoryManager.CreateDirectory(saveCdkDirectoryPath); var templateEngine = new TemplateEngine(); - templateEngine.GenerateCDKProjectFromTemplate(recommendation, session, saveCdkDirectoryPath, assemblyName); + await templateEngine.GenerateCdkProjectFromTemplateAsync(recommendation, session, saveCdkDirectoryPath, assemblyName); _interactiveService.LogDebugMessage($"Saving AWS CDK deployment project to: {saveCdkDirectoryPath}"); return saveCdkDirectoryPath; diff --git a/src/AWS.Deploy.Orchestration/TemplateEngine.cs b/src/AWS.Deploy.Orchestration/TemplateEngine.cs index 1b5da0975..c9c70390f 100644 --- a/src/AWS.Deploy.Orchestration/TemplateEngine.cs +++ b/src/AWS.Deploy.Orchestration/TemplateEngine.cs @@ -1,37 +1,30 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; using AWS.Deploy.Common; using Microsoft.TemplateEngine.Abstractions; -using Microsoft.TemplateEngine.Edge; -using Microsoft.TemplateEngine.Edge.Template; +using Microsoft.TemplateEngine.Abstractions.Installer; +using Microsoft.TemplateEngine.Edge.Installers.Folder; using Microsoft.TemplateEngine.IDE; using Microsoft.TemplateEngine.Orchestrator.RunnableProjects; -using Microsoft.TemplateEngine.Utils; +using DefaultTemplateEngineHost = Microsoft.TemplateEngine.Edge.DefaultTemplateEngineHost; +using WellKnownSearchFilters = Microsoft.TemplateEngine.Utils.WellKnownSearchFilters; namespace AWS.Deploy.Orchestration { public class TemplateEngine { - private const string HostIdentifier = "aws-net-deploy-template-generator"; - private const string HostVersion = "v1.0.0"; + private const string HOST_IDENTIFIER = "aws-net-deploy-template-generator"; + private const string HOST_VERSION = "v2.0.0"; private readonly Bootstrapper _bootstrapper; - private static readonly object s_locker = new(); public TemplateEngine() { - _bootstrapper = new Bootstrapper(CreateHost(), null, virtualizeConfiguration: true); + _bootstrapper = new Bootstrapper(CreateHost(), true); } - public void GenerateCDKProjectFromTemplate(Recommendation recommendation, OrchestratorSession session, string outputDirectory, string assemblyName) + public async Task GenerateCdkProjectFromTemplateAsync(Recommendation recommendation, OrchestratorSession session, string outputDirectory, string assemblyName) { if (string.IsNullOrEmpty(recommendation.Recipe.CdkProjectTemplate)) { @@ -49,23 +42,21 @@ public void GenerateCDKProjectFromTemplate(Recommendation recommendation, Orches recommendation.Recipe.CdkProjectTemplate); //Installing the base template into the templating engine to make it available for generation - InstallTemplates(cdkProjectTemplateDirectory); + await InstallTemplates(cdkProjectTemplateDirectory); //Looking up the installed template in the templating engine - var template = + var templates = await _bootstrapper - .ListTemplates( - true, - WellKnownSearchFilters.NameFilter(recommendation.Recipe.CdkProjectTemplateId)) - .FirstOrDefault() - ?.Info; + .GetTemplatesAsync( + new[] { WellKnownSearchFilters.NameFilter(recommendation.Recipe.CdkProjectTemplateId) }); + var template = templates.FirstOrDefault()?.Info; //If the template is not found, throw an exception if (template == null) throw new Exception($"Failed to find a Template for [{recommendation.Recipe.CdkProjectTemplateId}]"); - var templateParameters = new Dictionary { - // CDK Template projects can parameterize the version number of the AWS.Deploy.Recipes.CDK.Common package. This avoid + var templateParameters = new Dictionary { + // CDK Template projects can parameterize the version number of the AWS.Deploy.Recipes.CDK.Common package. This avoids // projects having to be modified every time the package version is bumped. { "AWSDeployRecipesCDKCommonVersion", FileVersionInfo.GetVersionInfo(typeof(AWS.Deploy.Recipes.CDK.Common.CDKRecipeSetup).Assembly.Location).ProductVersion ?? throw new InvalidAWSDeployRecipesCDKCommonVersionException(DeployToolErrorCode.InvalidAWSDeployRecipesCDKCommonVersion, "The version number of the AWS.Deploy.Recipes.CDK.Common package is invalid.") } @@ -73,11 +64,8 @@ public void GenerateCDKProjectFromTemplate(Recommendation recommendation, Orches try { - lock (s_locker) - { - //Generate the CDK project using the installed template into the output directory - _bootstrapper.CreateAsync(template, assemblyName, outputDirectory, templateParameters, false, "").GetAwaiter().GetResult(); - } + //Generate the CDK project using the installed template into the output directory + await _bootstrapper.CreateAsync(template, assemblyName, outputDirectory, templateParameters); } catch { @@ -85,14 +73,18 @@ public void GenerateCDKProjectFromTemplate(Recommendation recommendation, Orches } } - private void InstallTemplates(string folderLocation) + private async Task InstallTemplates(string folderLocation) { try { - lock (s_locker) + var installRequests = new[] { - _bootstrapper.Install(folderLocation); - } + new InstallRequest(folderLocation, folderLocation, force: true) + }; + + var result = await _bootstrapper.InstallTemplatePackagesAsync(installRequests); + if (result.Any(x => x.Success == false)) + throw new Exception("Failed to install the default template that is required to the generate the CDK project"); } catch(Exception e) { @@ -107,13 +99,13 @@ private ITemplateEngineHost CreateHost() { "prefs:language", "C#" } }; - var builtIns = new AssemblyComponentCatalog(new[] + var builtIns = new List<(Type, IIdentifiedComponent)> { - typeof(RunnableProjectGenerator).GetTypeInfo().Assembly, // for assembly: Microsoft.TemplateEngine.Orchestrator.RunnableProjects - typeof(AssemblyComponentCatalog).GetTypeInfo().Assembly, // for assembly: Microsoft.TemplateEngine.Edge - }); + (typeof(IGenerator), new RunnableProjectGenerator()), + (typeof(IInstallerFactory), new FolderInstallerFactory()) + }; - ITemplateEngineHost host = new DefaultTemplateEngineHost(HostIdentifier, HostVersion, CultureInfo.CurrentCulture.Name, preferences, builtIns, null); + ITemplateEngineHost host = new DefaultTemplateEngineHost(HOST_IDENTIFIER, HOST_VERSION, preferences, builtIns); return host; } diff --git a/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppAppRunner/.template.config/template.json b/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppAppRunner/.template.config/template.json index 4db1da255..280afaf47 100644 --- a/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppAppRunner/.template.config/template.json +++ b/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppAppRunner/.template.config/template.json @@ -1,4 +1,5 @@ { + "$schema": "http://json.schemastore.org/template", "author": "AWS", "classifications": [ "AWS", diff --git a/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppEcsFargate/.template.config/template.json b/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppEcsFargate/.template.config/template.json index 4fea35daf..4b458666c 100644 --- a/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppEcsFargate/.template.config/template.json +++ b/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppEcsFargate/.template.config/template.json @@ -1,4 +1,5 @@ { + "$schema": "http://json.schemastore.org/template", "author": "AWS", "classifications": [ "AWS", diff --git a/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppElasticBeanstalkLinux/.template.config/template.json b/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppElasticBeanstalkLinux/.template.config/template.json index 09788af30..a4599512b 100644 --- a/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppElasticBeanstalkLinux/.template.config/template.json +++ b/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppElasticBeanstalkLinux/.template.config/template.json @@ -1,4 +1,5 @@ { + "$schema": "http://json.schemastore.org/template", "author": "AWS", "classifications": [ "AWS", diff --git a/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppElasticBeanstalkWindows/.template.config/template.json b/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppElasticBeanstalkWindows/.template.config/template.json index 2c6f8696e..fc650470c 100644 --- a/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppElasticBeanstalkWindows/.template.config/template.json +++ b/src/AWS.Deploy.Recipes/CdkTemplates/AspNetAppElasticBeanstalkWindows/.template.config/template.json @@ -1,4 +1,5 @@ { + "$schema": "http://json.schemastore.org/template", "author": "AWS", "classifications": [ "AWS", diff --git a/src/AWS.Deploy.Recipes/CdkTemplates/BlazorWasm/.template.config/template.json b/src/AWS.Deploy.Recipes/CdkTemplates/BlazorWasm/.template.config/template.json index 834c9cadd..66fae21c7 100644 --- a/src/AWS.Deploy.Recipes/CdkTemplates/BlazorWasm/.template.config/template.json +++ b/src/AWS.Deploy.Recipes/CdkTemplates/BlazorWasm/.template.config/template.json @@ -1,4 +1,5 @@ { + "$schema": "http://json.schemastore.org/template", "author": "AWS", "classifications": [ "AWS", diff --git a/src/AWS.Deploy.Recipes/CdkTemplates/ConsoleAppECSFargateScheduleTask/.template.config/template.json b/src/AWS.Deploy.Recipes/CdkTemplates/ConsoleAppECSFargateScheduleTask/.template.config/template.json index f35d1550c..203975e3f 100644 --- a/src/AWS.Deploy.Recipes/CdkTemplates/ConsoleAppECSFargateScheduleTask/.template.config/template.json +++ b/src/AWS.Deploy.Recipes/CdkTemplates/ConsoleAppECSFargateScheduleTask/.template.config/template.json @@ -1,4 +1,5 @@ { + "$schema": "http://json.schemastore.org/template", "author": "AWS", "classifications": [ "AWS", diff --git a/src/AWS.Deploy.Recipes/CdkTemplates/ConsoleAppECSFargateService/.template.config/template.json b/src/AWS.Deploy.Recipes/CdkTemplates/ConsoleAppECSFargateService/.template.config/template.json index 1257747ff..c47cda9f1 100644 --- a/src/AWS.Deploy.Recipes/CdkTemplates/ConsoleAppECSFargateService/.template.config/template.json +++ b/src/AWS.Deploy.Recipes/CdkTemplates/ConsoleAppECSFargateService/.template.config/template.json @@ -1,4 +1,5 @@ { + "$schema": "http://json.schemastore.org/template", "author": "AWS", "classifications": [ "AWS",