private static async Task CreateDbTargets(AzureSqlJobClient elasticJobs, CustomCollectionTargetInfo rootTarget, BackgroundTaskService.BackgroundTaskLog log , IList <DatabaseTarget> dbTargets, int pageSize, int delay) { for (int i = 0; i < dbTargets.Count; i += pageSize) { await Task.WhenAll(dbTargets.Skip(i).Take(pageSize).Select(x => CreateDbTarget(elasticJobs, rootTarget, log, x)).ToArray()); Thread.Sleep(delay); } }
private static async Task <int> FindLastUsedNumber(AzureSqlJobClient elasticJobs, string jobNamePrefix, BackgroundTaskService.BackgroundTaskLog log) { for (int i = 0; i < int.MaxValue; i++) { var jobName = BuildJobName(jobNamePrefix, i); log.LogInfo($"checking if {jobName} exists"); var job = await elasticJobs.Jobs.GetJobAsync(jobName); if (job == null) { return(i - 1); } } throw new Exception($"we used {int.MaxValue} numbers for jobs ????"); }
private static async Task <bool> IsJobInProgress(AzureSqlJobClient elasticJobs, string lastJobName) { var executions = await elasticJobs.JobExecutions.ListJobExecutionsAsync(new JobExecutionFilter() { JobName = lastJobName }); if (executions != null) { return(executions.Any(jobExecutionInfo => jobExecutionInfo.Lifecycle == JobExecutionLifecycle.Created || jobExecutionInfo.Lifecycle == JobExecutionLifecycle.InProgress || jobExecutionInfo.Lifecycle == JobExecutionLifecycle.WaitingForChildJobExecutions || jobExecutionInfo.Lifecycle == JobExecutionLifecycle.WaitingToRetry)); } return(false); }
private static async Task <JobExecutionInfo> StartJob(AzureSqlJobClient elasticJobs, IList <DatabaseTarget> targets , BackgroundTaskService.BackgroundTaskLog log, string dacPacName, string dacPacUri) { var dacPackDef = await elasticJobs.Content.GetContentAsync(dacPacName) ?? await elasticJobs.Content.CreateDacpacAsync(dacPacName, new Uri(dacPacUri)); var pwd = CreatePassword(Settings.ChalkableSchoolDbPassword); var credential = await elasticJobs.Credentials.CreateCredentialAsync(Guid.NewGuid().ToString(), Settings.ChalkableSchoolDbUser, pwd); string jobNamePrefix = "Apply DACPAC " + dacPacName + " "; int lastNumber = await FindLastUsedNumber(elasticJobs, jobNamePrefix, log); if (lastNumber >= 0) { bool inProgress = await IsJobInProgress(elasticJobs, BuildJobName(jobNamePrefix, lastNumber)); if (inProgress) { throw new Exception("Previous job on this version is not end yet"); } } var rooTarget = await elasticJobs.Targets.CreateCustomCollectionTargetAsync("Targets for DACPAC " + dacPacName + " " + Guid.NewGuid()); log.LogInfo("Job targets created as " + rooTarget.TargetId + " " + rooTarget.CustomCollectionName); await CreateDbTargets(elasticJobs, rooTarget, log, targets, 20, 2000); var jobName = BuildJobName(jobNamePrefix, lastNumber + 1); var job = await elasticJobs.Jobs.CreateJobAsync(jobName, new JobBuilder { ContentName = dacPackDef.ContentName, TargetId = rooTarget.TargetId, CredentialName = credential.CredentialName }); log.LogInfo("Job created as " + job.TargetId + " " + job.JobName); var jobExecution = await elasticJobs.JobExecutions.StartJobExecutionAsync(job.JobName); log.LogInfo($"{dacPacName} execution job as {jobExecution.JobExecutionId} with lifecycle {jobExecution.Lifecycle}"); return(jobExecution); }
private static async Task CreateDbTarget(AzureSqlJobClient elasticJobs, CustomCollectionTargetInfo rootTarget , BackgroundTaskService.BackgroundTaskLog log, DatabaseTarget dbTarget) { try { var dbTargetInfo = await elasticJobs.Targets.GetDatabaseTargetAsync(dbTarget.Server, dbTarget.Name) ?? await elasticJobs.Targets.CreateDatabaseTargetAsync(dbTarget.Server, dbTarget.Name); var result = await elasticJobs.Targets.AddChildTargetAsync(rootTarget.TargetId, dbTargetInfo.TargetId); if (!result) { throw new Exception("child target adding returns false"); } log.LogInfo("Targeting db " + dbTarget.Name + "@" + dbTarget.Server + " complete as " + dbTargetInfo.TargetId); } catch (Exception e) { log.LogException(e); throw new Exception("Targeting db " + dbTarget.Name + "@" + dbTarget.Server + " failed.", e); } }