| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 | 
							- using Microsoft.Azure.Batch;
 
- using Microsoft.Azure.Batch.Auth;
 
- using Microsoft.Azure.Batch.Common;
 
- using Microsoft.Azure.Services.AppAuthentication;
 
- using Microsoft.Azure.WebJobs;
 
- using Microsoft.Azure.WebJobs.Extensions.DurableTask;
 
- using Microsoft.Extensions.Logging;
 
- using System;
 
- using System.Collections.Generic;
 
- using System.Threading.Tasks;
 
- using static ADPControl.HttpSurface;
 
- namespace ADPControl
 
- {
 
-     public static class BatchActivity
 
-     {
 
-         // Batch resource settings
 
-         private const string PoolVMSize = "Standard_D8s_v3";
 
-         private const string PoolId = PoolVMSize;
 
-         private const int PoolNodeCount = 2;
 
-         private const string AppPackageName = "SqlPackageWrapper";
 
-         public const string AppPackageVersion = "1";
 
-         [FunctionName(nameof(CreateBatchPoolAndExportJob))]
 
-         public static async Task<string> CreateBatchPoolAndExportJob([ActivityTrigger] ExportRequest request, ILogger log)
 
-         {
 
-             var azureServiceTokenProvider = new AzureServiceTokenProvider();
 
-             // Get a Batch client using function identity
 
-             BatchTokenCredentials batchCred = new BatchTokenCredentials(request.BatchAccountUrl, await azureServiceTokenProvider.GetAccessTokenAsync("https://batch.core.windows.net/"));
 
-             string jobId = request.SourceSqlServerName + "-Export-" + DateTime.UtcNow.ToString("MMddHHmmss");
 
-             using (BatchClient batchClient = BatchClient.Open(batchCred))
 
-             {
 
-                 ImageReference imageReference = CreateImageReference();
 
-                 VirtualMachineConfiguration vmConfiguration = CreateVirtualMachineConfiguration(imageReference);
 
-                 await CreateBatchPoolIfNotExist(batchClient, vmConfiguration, request.VNetSubnetId);
 
-                 await CreateBatchJob(batchClient, jobId, log);
 
-             }
 
-             return jobId;
 
-         }
 
-         [FunctionName(nameof(CreateBatchPoolAndImportJob))]
 
-         public static async Task<string> CreateBatchPoolAndImportJob([ActivityTrigger] ImportRequest request, ILogger log)
 
-         {
 
-             var azureServiceTokenProvider = new AzureServiceTokenProvider();
 
-             // Get a Batch client using function identity
 
-             BatchTokenCredentials batchCred = new BatchTokenCredentials(request.BatchAccountUrl, await azureServiceTokenProvider.GetAccessTokenAsync("https://batch.core.windows.net/"));
 
-             string jobId = request.TargetSqlServerName + "-Import-" + DateTime.UtcNow.ToString("MMddHHmmss");
 
-             using (BatchClient batchClient = BatchClient.Open(batchCred))
 
-             {
 
-                 ImageReference imageReference = CreateImageReference();
 
-                 VirtualMachineConfiguration vmConfiguration = CreateVirtualMachineConfiguration(imageReference);
 
-                 await CreateBatchPoolIfNotExist(batchClient, vmConfiguration, request.VNetSubnetId);
 
-                 await CreateBatchJob(batchClient, jobId, log);
 
-             }
 
-             return jobId;
 
-         }
 
-         public static async Task<CloudJob> CreateBatchJob(BatchClient batchClient, string jobId, ILogger log)
 
-         {
 
-             // Create a Batch job
 
-             log.LogInformation("Creating job [{0}]...", jobId);
 
-             CloudJob job = null;
 
-             try
 
-             {
 
-                 job = batchClient.JobOperations.CreateJob(jobId, new PoolInformation { PoolId = PoolId });
 
-                 job.OnAllTasksComplete = OnAllTasksComplete.TerminateJob;
 
-                 // Commit the job to the Batch service
 
-                 await job.CommitAsync();
 
-                 log.LogInformation($"Created job {jobId}");
 
-                 // Obtain the bound job from the Batch service
 
-                 await job.RefreshAsync();
 
-             }
 
-             catch (BatchException be)
 
-             {
 
-                 // Accept the specific error code JobExists as that is expected if the job already exists
 
-                 if (be.RequestInformation?.BatchError?.Code == BatchErrorCodeStrings.JobExists)
 
-                 {
 
-                     log.LogWarning("The job {0} already existed when we tried to create it", jobId);
 
-                 }
 
-                 else
 
-                 {
 
-                     log.LogError("Exception creating job: {0}", be.Message);
 
-                     throw be; // Any other exception is unexpected
 
-                 }
 
-             }
 
-             return job;
 
-         }
 
-         // Create the Compute Pool of the Batch Account
 
-         public static async Task CreateBatchPoolIfNotExist(BatchClient batchClient, VirtualMachineConfiguration vmConfiguration, string vnetSubnetId)
 
-         {
 
-             Console.WriteLine("Creating pool [{0}]...", PoolId);
 
-             try
 
-             {
 
-                 CloudPool pool = batchClient.PoolOperations.CreatePool(
 
-                     poolId: PoolId,
 
-                     targetDedicatedComputeNodes: PoolNodeCount,
 
-                     virtualMachineSize: PoolVMSize,
 
-                     virtualMachineConfiguration: vmConfiguration);
 
-                 // Specify the application and version to install on the compute nodes
 
-                 pool.ApplicationPackageReferences = new List<ApplicationPackageReference>
 
-                 {
 
-                     new ApplicationPackageReference {
 
-                         ApplicationId = AppPackageName,
 
-                         Version = AppPackageVersion }
 
-                 };
 
-                 // Initial the first data disk for each VM in the pool
 
-                 StartTask startTask = new StartTask("cmd /c Powershell -command \"Get-Disk | Where partitionstyle -eq 'raw' | sort number | Select-Object -first 1 |" +
 
-                     " Initialize-Disk -PartitionStyle MBR -PassThru | New-Partition -UseMaximumSize -DriveLetter F |" +
 
-                     " Format-Volume -FileSystem NTFS -NewFileSystemLabel data1 -Confirm:$false -Force\"");
 
-                 startTask.MaxTaskRetryCount = 1;
 
-                 startTask.UserIdentity = new UserIdentity(new AutoUserSpecification(AutoUserScope.Pool, ElevationLevel.Admin));
 
-                 startTask.WaitForSuccess = true;
 
-                 pool.StartTask = startTask;
 
-                 // Create the Pool within the vnet subnet if it's specified.
 
-                 if (vnetSubnetId != null)
 
-                 {
 
-                     pool.NetworkConfiguration = new NetworkConfiguration();
 
-                     pool.NetworkConfiguration.SubnetId = vnetSubnetId;
 
-                 }
 
-                 await pool.CommitAsync();
 
-                 await pool.RefreshAsync();
 
-             }
 
-             catch (BatchException be)
 
-             {
 
-                 // Accept the specific error code PoolExists as that is expected if the pool already exists
 
-                 if (be.RequestInformation?.BatchError?.Code == BatchErrorCodeStrings.PoolExists)
 
-                 {
 
-                     Console.WriteLine("The pool {0} already existed when we tried to create it", PoolId);
 
-                 }
 
-                 else
 
-                 {
 
-                     throw; // Any other exception is unexpected
 
-                 }
 
-             }
 
-         }
 
-         public static VirtualMachineConfiguration CreateVirtualMachineConfiguration(ImageReference imageReference)
 
-         {
 
-             VirtualMachineConfiguration config = new VirtualMachineConfiguration(
 
-                 imageReference: imageReference,
 
-                 nodeAgentSkuId: "batch.node.windows amd64");
 
-             config.DataDisks = new List<DataDisk>();
 
-             config.DataDisks.Add(new DataDisk(0, 2048, CachingType.ReadOnly, StorageAccountType.PremiumLrs));
 
-             return config;
 
-         }
 
-         public static ImageReference CreateImageReference()
 
-         {
 
-             return new ImageReference(
 
-                 publisher: "MicrosoftWindowsServer",
 
-                 offer: "WindowsServer",
 
-                 sku: "2019-datacenter-smalldisk",
 
-                 version: "latest");
 
-         }
 
-         public static void CreateBatchTasks(string action, string jobId, string containerUrl, string batchAccountUrl, string sqlServerName, string accessToken, dynamic databases, ILogger log)
 
-         {
 
-             // Get a Batch client using function identity
 
-             log.LogInformation("CreateBatchTasks: entering");
 
-             var azureServiceTokenProvider = new AzureServiceTokenProvider();
 
-             BatchTokenCredentials batchCred = new BatchTokenCredentials(batchAccountUrl, azureServiceTokenProvider.GetAccessTokenAsync("https://batch.core.windows.net/").Result);
 
-             using (BatchClient batchClient = BatchClient.Open(batchCred))
 
-             {
 
-                 // For each database, submit the Exporting job to Azure Batch Compute Pool.
 
-                 log.LogInformation("CreateBatchTasks: enumerating databases");
 
-                 List<CloudTask> tasks = new List<CloudTask>();
 
-                 foreach (var db in databases)
 
-                 {
 
-                     string serverDatabaseName = db.name.ToString();
 
-                     string logicalDatabase = serverDatabaseName.Remove(0, sqlServerName.Length + 1);
 
-                     log.LogInformation("CreateBatchTasks: creating task for database {0}", logicalDatabase);
 
-                     string taskId = sqlServerName + "_" + logicalDatabase;
 
-                     string command = string.Format("cmd /c %AZ_BATCH_APP_PACKAGE_{0}#{1}%\\BatchWrapper {2}", AppPackageName.ToUpper(), AppPackageVersion, action);
 
-                     command += string.Format(" {0} {1} {2} {3} {4}", sqlServerName, logicalDatabase, accessToken, AppPackageName.ToUpper(), AppPackageVersion);
 
-                     string taskCommandLine = string.Format(command);
 
-                     CloudTask singleTask = new CloudTask(taskId, taskCommandLine);
 
-                     singleTask.EnvironmentSettings = new[] { new EnvironmentSetting("JOB_CONTAINER_URL", containerUrl) };
 
-                     Console.WriteLine(string.Format("Adding task {0} to job ...", taskId));
 
-                     tasks.Add(singleTask);
 
-                 }
 
-                 // Add all tasks to the job.
 
-                 batchClient.JobOperations.AddTask(jobId, tasks);
 
-             }
 
-             log.LogInformation("CreateBatchTasks: exiting");
 
-         }
 
-     }
 
- }
 
 
  |