diff --git a/Packages.props b/Packages.props
index b3acecce87..a69bc1bea7 100644
--- a/Packages.props
+++ b/Packages.props
@@ -26,12 +26,12 @@
-
+
-
+
diff --git a/bin/nuget/Microsoft.SqlServer.Migration.Assessment.1.0.20240321.1.nupkg b/bin/nuget/Microsoft.SqlServer.Migration.Assessment.1.0.20240410.1.nupkg
similarity index 78%
rename from bin/nuget/Microsoft.SqlServer.Migration.Assessment.1.0.20240321.1.nupkg
rename to bin/nuget/Microsoft.SqlServer.Migration.Assessment.1.0.20240410.1.nupkg
index eecc9c7917..b0a0d352c1 100644
Binary files a/bin/nuget/Microsoft.SqlServer.Migration.Assessment.1.0.20240321.1.nupkg and b/bin/nuget/Microsoft.SqlServer.Migration.Assessment.1.0.20240410.1.nupkg differ
diff --git a/bin/nuget/Microsoft.SqlServer.SqlTargetProvisioning.1.0.20240321.1.nupkg b/bin/nuget/Microsoft.SqlServer.SqlTargetProvisioning.1.0.20240410.1.nupkg
similarity index 80%
rename from bin/nuget/Microsoft.SqlServer.SqlTargetProvisioning.1.0.20240321.1.nupkg
rename to bin/nuget/Microsoft.SqlServer.SqlTargetProvisioning.1.0.20240410.1.nupkg
index b349a81c7f..25ed89a6fd 100644
Binary files a/bin/nuget/Microsoft.SqlServer.SqlTargetProvisioning.1.0.20240321.1.nupkg and b/bin/nuget/Microsoft.SqlServer.SqlTargetProvisioning.1.0.20240410.1.nupkg differ
diff --git a/src/Microsoft.SqlTools.Migration/Contracts/GetArmTemplateRequest.cs b/src/Microsoft.SqlTools.Migration/Contracts/GetArmTemplateRequest.cs
index 0077d29bc1..24816362a0 100644
--- a/src/Microsoft.SqlTools.Migration/Contracts/GetArmTemplateRequest.cs
+++ b/src/Microsoft.SqlTools.Migration/Contracts/GetArmTemplateRequest.cs
@@ -3,6 +3,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
+using System.Collections.Generic;
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
namespace Microsoft.SqlTools.Migration.Contracts
@@ -10,7 +11,7 @@ namespace Microsoft.SqlTools.Migration.Contracts
public class GetArmTemplateRequest
{
public static readonly
- RequestType Type =
- RequestType.Create("migration/getarmtemplate");
+ RequestType> Type =
+ RequestType>.Create("migration/getarmtemplate");
}
}
diff --git a/src/Microsoft.SqlTools.Migration/MigrationService.cs b/src/Microsoft.SqlTools.Migration/MigrationService.cs
index 1ac1d643dd..874329b8ae 100644
--- a/src/Microsoft.SqlTools.Migration/MigrationService.cs
+++ b/src/Microsoft.SqlTools.Migration/MigrationService.cs
@@ -607,21 +607,24 @@ internal async Task HandleEstablishUserMapping(
///
internal async Task HandleGetArmTemplateRequest(
string skuRecommendationReportFilePath,
- RequestContext requestContext)
+ RequestContext> requestContext)
{
try
{
ProvisioningScriptServiceProvider provider = new ProvisioningScriptServiceProvider();
List recommendations = ExtractSkuRecommendationReportAction.ExtractSkuRecommendationsFromReport(skuRecommendationReportFilePath);
- SqlArmTemplate template = provider.GenerateProvisioningScript(recommendations);
-
- string jsonOutput = JsonConvert.SerializeObject(
- template,
- Formatting.Indented,
- new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Culture = CultureInfo.InvariantCulture }
- );
-
- await requestContext.SendResult(jsonOutput);
+ List templateList = provider.GenerateProvisioningScript(recommendations);
+ List armTemplates = new List();
+ foreach (SqlArmTemplate template in templateList)
+ {
+ string jsonOutput = JsonConvert.SerializeObject(
+ template,
+ Formatting.Indented,
+ new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Culture = CultureInfo.InvariantCulture }
+ );
+ armTemplates.Add(jsonOutput);
+ }
+ await requestContext.SendResult(armTemplates);
}
catch (Exception e)
{
diff --git a/test/Microsoft.SqlTools.Migration.IntegrationTests/Migration/MigrationServiceTests.cs b/test/Microsoft.SqlTools.Migration.IntegrationTests/Migration/MigrationServiceTests.cs
index 149ad39906..b76f131319 100644
--- a/test/Microsoft.SqlTools.Migration.IntegrationTests/Migration/MigrationServiceTests.cs
+++ b/test/Microsoft.SqlTools.Migration.IntegrationTests/Migration/MigrationServiceTests.cs
@@ -22,6 +22,8 @@
using Assert_ = Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
using Microsoft.SqlServer.Migration.SkuRecommendation.TargetProvisioning.Contracts;
using Microsoft.SqlServer.Migration.TargetProvisioning;
+using Microsoft.SqlServer.Migration.SqlTargetProvisioning.Constants;
+
namespace Microsoft.SqlTools.Migration.IntegrationTests.Migration
{
@@ -163,13 +165,59 @@ public void GenerateProvisioningScript_DatabaseRecommendation_ReturnsDBArmTempla
var result = provisioningScriptserviceProvider.GenerateProvisioningScript(recs);
// Assert
- Assert_.IsInstanceOfType(result, typeof(SqlArmTemplate));
- Assert.AreEqual(result.resources.Count, 2);
- Assert.AreEqual(result.resources.Where(res => res.type == "Microsoft.Sql/servers").Count(), 1);
- Assert.AreEqual(result.resources.Where(res => res.type == "Microsoft.Sql/servers/databases").Count(), 1);
- Assert.AreEqual(result.parameters.Where(par => par.Key == "Server collation").FirstOrDefault().Value.defaultValue, "Latin1_General_CI_AI");
- Assert.AreEqual(result.parameters.Where(par => par.Key == "Collation for database testdb").FirstOrDefault().Value.defaultValue, "Latin1_General_CI_AI");
- Assert.AreEqual(result.parameters.Count, 9);
+ Assert_.IsInstanceOfType(result[0], typeof(SqlArmTemplate));
+ Assert.AreEqual(result[0].resources.Count, 2);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Sql/servers").Count(), 1);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Sql/servers/databases").Count(), 1);
+ Assert.AreEqual(result[0].parameters.Where(par => par.Key == "Server collation").FirstOrDefault().Value.defaultValue, "Latin1_General_CI_AI");
+ Assert.AreEqual(result[0].parameters.Where(par => par.Key == "Collation for database testdb").FirstOrDefault().Value.defaultValue, "Latin1_General_CI_AI");
+ Assert.AreEqual(result[0].parameters.Count, 9);
+ }
+
+ [Test]
+ public void GenerateProvisioningScript_DatabaseRecommendationLargeNumber_ReturnsDBArmTemplateList()
+ {
+ // Arrange
+ List recs = new List();
+ for (int i = 0; i < 125; i++)
+ {
+ var rec = new SkuRecommendationResult
+ {
+ SqlInstanceName = "TestServer",
+ DatabaseName = "TestDb" + i,
+ ServerCollation = serverLevelCollation,
+ DatabaseCollation = databaseLevelCollations["TestDb"],
+ TargetSku = new AzureSqlPaaSSku(
+ new AzureSqlSkuPaaSCategory(
+ AzureSqlTargetPlatform.AzureSqlDatabase,
+ AzureSqlPurchasingModel.vCore,
+ AzureSqlPaaSServiceTier.GeneralPurpose,
+ ComputeTier.Provisioned,
+ AzureSqlPaaSHardwareType.Gen5),
+ 2,
+ i)
+ {
+ }
+ };
+
+ recs.Add(rec);
+ }
+
+ // Act
+ var result = provisioningScriptserviceProvider.GenerateProvisioningScript(recs);
+
+ // Assert
+ Assert_.AreEqual(result.Count, 1 + recs.Count / ArmConstants.AzureSqlDbProvisioningBatchSize);
+ foreach (var res in result)
+ {
+ Assert_.IsInstanceOfType(res, typeof(SqlArmTemplate));
+ Assert.IsTrue(res.resources.Count <= 51);
+ Assert.AreEqual(res.resources.Where(res => res.type == "Microsoft.Sql/servers").Count(), 1);
+ Assert.IsTrue(res.resources.Where(res => res.type == "Microsoft.Sql/servers/databases").Count() <= 50);
+ Assert.AreEqual(res.parameters.Where(par => par.Key == "Server collation").FirstOrDefault().Value.defaultValue, "Latin1_General_CI_AI");
+ Assert.AreEqual(res.parameters.Where(par => par.Key.StartsWith("Collation for database testdb")).FirstOrDefault().Value.defaultValue, "Latin1_General_CI_AI");
+ Assert.IsTrue(res.parameters.Count <= 256);
+ }
}
[Test]
@@ -200,14 +248,14 @@ public void GenerateProvisioningScript_ManagedInstanceRecommendation_ReturnsMIAr
var result = provisioningScriptserviceProvider.GenerateProvisioningScript(recs);
// Assert
- Assert_.IsInstanceOfType(result, typeof(SqlArmTemplate));
- Assert.AreEqual(result.resources.Count, 4);
- Assert.AreEqual(result.resources.Where(res => res.type == "Microsoft.Network/networkSecurityGroups").Count(), 1);
- Assert.AreEqual(result.resources.Where(res => res.type == "Microsoft.Network/routeTables").Count(), 1);
- Assert.AreEqual(result.resources.Where(res => res.type == "Microsoft.Network/virtualNetworks").Count(), 1);
- Assert.AreEqual(result.resources.Where(res => res.type == "Microsoft.Sql/managedInstances").Count(), 1);
- Assert.AreEqual(result.parameters.Where(par => par.Key == "Server collation").FirstOrDefault().Value.defaultValue, "Latin1_General_CI_AI");
- Assert.AreEqual(result.parameters.Count, 11);
+ Assert_.IsInstanceOfType(result[0], typeof(SqlArmTemplate));
+ Assert.AreEqual(result[0].resources.Count, 4);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Network/networkSecurityGroups").Count(), 1);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Network/routeTables").Count(), 1);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Network/virtualNetworks").Count(), 1);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Sql/managedInstances").Count(), 1);
+ Assert.AreEqual(result[0].parameters.Where(par => par.Key == "Server collation").FirstOrDefault().Value.defaultValue, "Latin1_General_CI_AI");
+ Assert.AreEqual(result[0].parameters.Count, 11);
}
[Test]
@@ -268,16 +316,16 @@ public void GenerateProvisioningScript_VirtualMachineRecommendation_ReturnsVMArm
var result = provisioningScriptserviceProvider.GenerateProvisioningScript(recs);
// Assert
- Assert_.IsInstanceOfType(result, typeof(SqlArmTemplate));
- Assert.AreEqual(result.resources.Count, 6);
- Assert.AreEqual(result.resources.Where(res => res.type == "Microsoft.Network/networkSecurityGroups").Count(), 1);
- Assert.AreEqual(result.resources.Where(res => res.type == "Microsoft.SqlVirtualMachine/SqlVirtualMachines").Count(), 1);
- Assert.AreEqual(result.resources.Where(res => res.type == "Microsoft.Network/virtualNetworks").Count(), 1);
- Assert.AreEqual(result.resources.Where(res => res.type == "Microsoft.Compute/virtualMachines").Count(), 1);
- Assert.AreEqual(result.resources.Where(res => res.type == "Microsoft.Network/publicIpAddresses").Count(), 1);
- Assert.AreEqual(result.resources.Where(res => res.type == "Microsoft.Network/networkInterfaces").Count(), 1);
- Assert.AreEqual(result.parameters.Where(par => par.Key == "Server collation").FirstOrDefault().Value.defaultValue, "Latin1_General_CI_AI");
- Assert.AreEqual(result.parameters.Count, 14);
+ Assert_.IsInstanceOfType(result[0], typeof(SqlArmTemplate));
+ Assert.AreEqual(result[0].resources.Count, 7);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Network/networkSecurityGroups").Count(), 1);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.SqlVirtualMachine/SqlVirtualMachines").Count(), 1);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Network/virtualNetworks").Count(), 1);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Compute/virtualMachines").Count(), 1);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Network/publicIpAddresses").Count(), 1);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Network/networkInterfaces").Count(), 1);
+ Assert.AreEqual(result[0].parameters.Where(par => par.Key == "Server collation").FirstOrDefault().Value.defaultValue, "Latin1_General_CI_AI");
+ Assert.AreEqual(result[0].parameters.Count, 21);
// Add additional assertions based on the expected outcome for the virtual machine case
}
@@ -309,6 +357,48 @@ public void GenerateProvisioningScript_InvalidTargetPlatform_ThrowsArgumentExcep
Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException(() => provisioningScriptserviceProvider.GenerateProvisioningScript(recs));
}
+ [Test]
+ public void GenerateProvisioningScript_ManagedInstanceRecommendation_NextGenGP_ReturnsMIArmTemplate()
+ {
+ // Arrange
+ var recs = new List
+ {
+ new SkuRecommendationResult
+ {
+ SqlInstanceName = "TestServer",
+ ServerCollation = serverLevelCollation,
+ TargetSku = new AzureSqlPaaSSku(
+ new AzureSqlSkuPaaSCategory(
+ AzureSqlTargetPlatform.AzureSqlManagedInstance,
+ AzureSqlPurchasingModel.vCore,
+ AzureSqlPaaSServiceTier.NextGenGeneralPurpose,
+ ComputeTier.Provisioned,
+ AzureSqlPaaSHardwareType.Gen5),
+ 4,
+ 32,
+ maxStorageIops: 300)
+ {
+ }
+ }
+ };
+
+ // Act
+ var result = provisioningScriptserviceProvider.GenerateProvisioningScript(recs);
+
+ // Assert
+ Assert_.IsInstanceOfType(result[0], typeof(SqlArmTemplate));
+ Assert.AreEqual(result[0].resources.Count, 4);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Network/networkSecurityGroups").Count(), 1);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Network/routeTables").Count(), 1);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Network/virtualNetworks").Count(), 1);
+ Assert.AreEqual(result[0].resources.Where(res => res.type == "Microsoft.Sql/managedInstances").Count(), 1);
+ Assert.AreEqual(result[0].parameters.Where(par => par.Key == "Server collation").FirstOrDefault().Value.defaultValue, "Latin1_General_CI_AI");
+ Assert.AreEqual(result[0].parameters.Where(par => par.Key == "Server collation").FirstOrDefault().Value.defaultValue, "Latin1_General_CI_AI");
+ Assert.AreEqual(result[0].parameters.Count, 12);
+ int maxStorageIOPS = result[0].parameters.Where(par => par.Key == "Max storage IOPS").Select(par => Convert.ToInt32(par.Value.defaultValue)).FirstOrDefault();
+ Assert.AreEqual(maxStorageIOPS, 300);
+ }
+
}
}
\ No newline at end of file