public async Task <bool> IsExecutionPermitted(string circuitBreakerId, ILogger log, IDurableOrchestrationContext orchestrationContext) { if (string.IsNullOrEmpty(circuitBreakerId)) { throw new ArgumentNullException($"{nameof(circuitBreakerId)}"); } log?.LogCircuitBreakerMessage(circuitBreakerId, $"Asking IsExecutionPermitted (consistency priority) for circuit-breaker = '{circuitBreakerId}'."); return(await orchestrationContext.CreateEntityProxy <IDurableCircuitBreaker>(circuitBreakerId).IsExecutionPermitted()); }
public static async Task RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext orchestrationContext, ILogger log) { if (orchestrationContext is null) { throw new ArgumentNullException(nameof(orchestrationContext)); } var command = orchestrationContext.GetInput <ICommand>(); var commandResult = command.CreateResult(); var commandLog = orchestrationContext.CreateReplaySafeLogger(log ?? NullLogger.Instance); try { orchestrationContext.SetCustomStatus("Auditing command", log); await orchestrationContext .AuditAsync(command, commandResult) .ConfigureAwait(true); orchestrationContext.SetCustomStatus("Processing command", log); commandResult = await orchestrationContext .CallSubOrchestratorWithRetryAsync <ICommandResult>(OrchestratorCommandOrchestrationHandler.GetCommandOrchestrationName(command), command.CommandId.ToString(), command) .ConfigureAwait(true); } catch (Exception exc) { commandResult ??= command.CreateResult(); commandResult.Errors.Add(exc); } finally { try { orchestrationContext.SetCustomStatus("Augmenting command result", log); commandResult = await orchestrationContext .CallActivityWithRetryAsync <ICommandResult>(nameof(CommandResultAugmentActivity), commandResult) .ConfigureAwait(true); } catch (Exception exc) { commandResult ??= command.CreateResult(); commandResult.Errors.Add(exc); } orchestrationContext.SetCustomStatus("Auditing command result", log); await orchestrationContext .AuditAsync(command, commandResult) .ConfigureAwait(true); var commandException = commandResult.Errors?.ToException(); if (commandException is null) { orchestrationContext.SetCustomStatus($"Command succeeded", log); } else { orchestrationContext.SetCustomStatus($"Command failed: {commandException.Message}", log, commandException); } orchestrationContext.SetOutput(commandResult); } }
public static async Task RunImportOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { log.LogInformation("RunImportOrchestrator: entering"); try { ImportRequest importRequest = context.GetInput <ImportRequest>(); // Deploy the ARM template to Create empty SQL resource string deploymentName = await context.CallActivityAsync <string>(nameof(AzureResourceManagerActivity.BeginDeployArmTemplateForImport), importRequest); while (true) { log.LogInformation("RunImportOrchestrator: starting ARM deployment"); string status = await context.CallActivityAsync <string>(nameof(AzureResourceManagerActivity.GetArmDeploymentForImport), (importRequest.SubscriptionId, importRequest.TargetSqlServerResourceGroupName, deploymentName)); if (status == "Succeeded") { log.LogInformation("RunImportOrchestrator: ARM deployment succeeded"); break; } else if (status == "Failed") { log.LogInformation("RunImportOrchestrator: ARM deployment failed"); throw new Exception("Failed ARM Deployment"); } // Orchestration sleeps until this time. var nextCheck = context.CurrentUtcDateTime.AddSeconds(10); if (!context.IsReplaying) { log.LogInformation($"RunImportOrchestrator: Replaying ARM deployment, next check at {nextCheck}."); } await context.CreateTimer(nextCheck, CancellationToken.None); } log.LogInformation("RunImportOrchestrator: Enumerating databases"); var databases = await context.CallActivityAsync <dynamic>(nameof(AzureResourceManagerActivity.GetArmTemplateForImportSkipParameterization), importRequest); // Create BatchPool And Job log.LogInformation("RunImportOrchestrator: Creating batch pool and import job"); string jobId = await context.CallActivityAsync <string>(nameof(BatchActivity.CreateBatchPoolAndImportJob), importRequest); string containerUrl = await context.CallActivityAsync <string>(nameof(StorageActivity.GettingJobContainerUrl), (importRequest.SubscriptionId, importRequest.ResourceGroupName, importRequest.StorageAccountName, importRequest.ContainerName)); log.LogInformation("RunImportOrchestrator: Creating import database tasks"); BatchActivity.CreateBatchTasks("Import", jobId, containerUrl, importRequest.BatchAccountUrl, importRequest.TargetSqlServerName, importRequest.TargetAccessToken, databases, log); // create output values Tuple <string, string>[] outputValues = { Tuple.Create("Orchestration progress:", "Complete"), Tuple.Create("deploymentName", deploymentName), Tuple.Create("jobId", jobId), Tuple.Create("containerUrl", containerUrl) }; context.SetOutput(outputValues); } finally { log.LogInformation("RunImportOrchestrator: exiting"); } }
public static async Task <IActionResult> DonateLocation( [OrchestrationTrigger] IDurableOrchestrationContext context, [SignalR(HubName = "center")] IAsyncCollector <SignalRMessage> signalRMessages, [Table(nameof(Center))] CloudTable centerTable, ILogger log) { var twilioResponse = context.GetInput <TwilioResponse>(); var centerClient = new DataAccess <Center>(centerTable); var msgProcessed = true; var responseMessage = ""; try { var centerFilter = new TableQuery <Center>() .Where(TableQuery.GenerateFilterCondition("HostPhoneNumber", QueryComparisons.Equal, twilioResponse.From)); var centers = await centerClient.GetAllAsync(centerFilter); var center = centers.FirstOrDefault(); var donatedItem = ConfigUtil.GetEnvironmentVariable("donatedItem"); if (center != null) { var geoAddress = await GetLocationAsync(twilioResponse.Body); if (geoAddress.results.Length > 0) { var address = geoAddress.results.FirstOrDefault(); if (string.IsNullOrEmpty(center.DonationPhoneNumber)) { var areaCode = int.Parse(twilioResponse.From.Substring(1, 3)); var newTwilioNumber = TwilioUtil.GetTwilioNumber(areaCode)?.PhoneNumber?.ToString(); var simulated = bool.Parse(ConfigUtil.GetEnvironmentVariable("Simulated")); if (!simulated) { var phoneSID = TwilioUtil.ProvisionNumber(newTwilioNumber); center.DonationPhoneNumberSID = phoneSID; } center.DonationPhoneNumber = newTwilioNumber; } center.Address = address.formatted_address; center.Active = true; center.Lat = address.geometry.location.lat.ToString(); center.Lng = address.geometry.location.lng.ToString(); await centerClient.ReplaceAsync(center); TwilioUtil.Notify(twilioResponse.From, string.Format(Messages.DonationAddress, center.Address, donatedItem, center.DonationPhoneNumber), log); var broadcastStat = new { Lat = center.Lat, Lng = center.Lng, PhoneNumber = center.DonationPhoneNumber }; await signalRMessages.AddAsync( new SignalRMessage { Target = "BroadcastMessage", Arguments = new[] { broadcastStat } }); } else { TwilioUtil.Notify(twilioResponse.From, string.Format(Messages.DonationAddressNotFound, center.Address), log); } } } catch (Exception ex) { msgProcessed = false; responseMessage = $"{ex.Message} {ex.StackTrace} {ex?.InnerException?.StackTrace ?? ""}"; } return(msgProcessed ? new OkObjectResult(msgProcessed) : (IActionResult) new BadRequestObjectResult(responseMessage)); }
private RecompensateApplicationProcessCommand BuildRecompensationCommand( IDurableOrchestrationContext context, RegisterApplicationCommand command) { return(new RecompensateApplicationProcessCommand(context.InstanceId, command.Photo, command.Cv)); }
public static Task <Project> GetProjectAsync(this IDurableOrchestrationContext durableOrchestrationContext, Guid projectId) => durableOrchestrationContext.CallActivityWithRetryAsync <Project>(nameof(ProjectGetActivity), projectId);
public static async Task <ICommandResult> RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext functionContext, ILogger log) { if (functionContext is null) { throw new ArgumentNullException(nameof(functionContext)); } var(command, provider) = functionContext.GetInput <(IProviderCommand, Provider)>(); var commandResult = command.CreateResult(); var commandMessage = default(ICommandMessage); var commandCallback = default(string); try { functionContext.SetCustomStatus($"Acquire callback url for command '{command.CommandId}'", log); commandCallback = await functionContext .CallActivityWithRetryAsync <string>(nameof(CallbackAcquireActivity), (functionContext.InstanceId, command)) .ConfigureAwait(true); commandMessage = new ProviderCommandMessage(command, commandCallback); functionContext.SetCustomStatus($"Prepare sending command '{command.CommandId}'", log); await RegisterProviderAsync(functionContext, command, provider) .ConfigureAwait(true); await EnableProviderAsync(functionContext, command, provider) .ConfigureAwait(true); command = await AugmentCommandAsync(functionContext, provider, command) .ConfigureAwait(true); await functionContext .AuditAsync(provider, command, commandResult) .ConfigureAwait(true); try { functionContext.SetCustomStatus($"Sending command '{command.CommandId}'", log); commandResult = await functionContext .CallActivityWithRetryAsync <ICommandResult>(nameof(CommandSendActivity), (provider, commandMessage)) .ConfigureAwait(true); } catch (RetryCanceledException) { commandResult = await functionContext .CallActivityWithRetryAsync <ICommandResult>(nameof(CommandResultActivity), (provider, commandMessage)) .ConfigureAwait(true); } finally { await functionContext .AuditAsync(provider, command, commandResult) .ConfigureAwait(true); } if (commandResult.RuntimeStatus.IsActive()) { var commandTimeout = (commandResult.Timeout > TimeSpan.Zero && commandResult.Timeout < CommandResult.MaximumTimeout) ? commandResult.Timeout // use the timeout reported back by the provider : CommandResult.MaximumTimeout; // use the defined maximum timeout functionContext.SetCustomStatus($"Waiting for command ({command.CommandId}) result on {commandCallback} for {commandTimeout}", log); commandResult = await functionContext .WaitForExternalEvent <ICommandResult>(command.CommandId.ToString(), commandTimeout, null) .ConfigureAwait(true); if (commandResult is null) { commandResult = await functionContext .CallActivityWithRetryAsync <ICommandResult>(nameof(CommandResultActivity), (provider, commandMessage)) .ConfigureAwait(true); throw new TimeoutException($"Provider '{provider.Id}' ran into timeout ({commandTimeout})"); } } } catch (Exception exc) { functionContext.SetCustomStatus($"Sending command '{command.CommandId}' failed: {exc.Message}", log, exc); // ensure we always have a command result // to add our exception so we won't break // our command auditing in the finally block commandResult ??= command.CreateResult(); commandResult.Errors.Add(exc); // re-throw the exception to inform the // outer orchestration that some bad happened throw; } finally { if (!string.IsNullOrEmpty(commandCallback)) { functionContext.SetCustomStatus($"Invalidating callback url for command '{command.CommandId}'", log); await functionContext .CallActivityWithRetryAsync(nameof(CallbackInvalidateActivity), functionContext.InstanceId) .ConfigureAwait(true); } await functionContext .AuditAsync(provider, command, commandResult) .ConfigureAwait(true); await ProcessOutputAsync(functionContext, provider, command, commandResult) .ConfigureAwait(true); } return(commandResult); }
public static int NoOpOrchestration([OrchestrationTrigger] IDurableOrchestrationContext ctx) { return(ctx.GetInput <int>()); }
public static async Task RunOrchestration( [OrchestrationTrigger] IDurableOrchestrationContext functionContext, ILogger log) { if (functionContext is null) { throw new ArgumentNullException(nameof(functionContext)); } if (log is null) { throw new ArgumentNullException(nameof(log)); } var command = functionContext.GetInput <OrchestratorTeamCloudUserUpdateCommand>(); var commandResult = command.CreateResult(); var user = command.Payload; using (log.BeginCommandScope(command)) { try { functionContext.SetCustomStatus($"Updating user.", log); var existingUser = default(UserDocument); using (await functionContext.LockAsync <UserDocument>(user.Id.ToString()).ConfigureAwait(true)) { existingUser = await functionContext .GetUserAsync(user.Id) .ConfigureAwait(true); if (existingUser is null) { throw new OrchestratorCommandException($"User '{user.Id}' does not exist.", command); } if (user.HasEqualTeamCloudInfo(existingUser)) { throw new OrchestratorCommandException($"User '{user.Id}' TeamCloud details have not changed.", command); } if (!user.HasEqualMemberships(existingUser)) { throw new OrchestratorCommandException($"User '{user.Id}' Project Memberships cannot be changed using the TeamCloudUserUpdateCommand. Project Memebership details must be changed using the ProjectUserUpdateCommand.", command); } user = await functionContext .SetUserTeamCloudInfoAsync(user) .ConfigureAwait(true); } var projects = default(IEnumerable <ProjectDocument>); // only update all projects if the updated user is an admin // or the user was an admin before the update, otherwise // only update member projects if user's teamcloud level properties changed if (user.IsAdmin() || existingUser.IsAdmin()) { projects = await functionContext .ListProjectsAsync() .ConfigureAwait(true); } else if (user.ProjectMemberships.Any() && !user.Properties.SequenceEqual(existingUser.Properties)) { projects = await functionContext .ListProjectsAsync(user.ProjectMemberships.Select(m => m.ProjectId).ToList()) .ConfigureAwait(true); } if (projects?.Any() ?? false) { foreach (var project in projects) { var projectUpdateCommand = new OrchestratorProjectUpdateCommand(command.BaseApi, command.User, project); functionContext.StartNewOrchestration(nameof(OrchestratorProjectUpdateCommandOrchestration), projectUpdateCommand); } } commandResult.Result = user; functionContext.SetCustomStatus($"User updated.", log); } catch (Exception ex) { functionContext.SetCustomStatus("Failed to update user.", log, ex); commandResult ??= command.CreateResult(); commandResult.Errors.Add(ex); throw; } finally { functionContext.SetOutput(commandResult); } } }
public async Task RenewSiteCertificates([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { var(site, certificates) = context.GetInput <(Site, Certificate[])>();
public static Task <UserDocument> GetUserAsync(this IDurableOrchestrationContext functionContext, string userId, bool allowUnsafe = false) => functionContext.IsLockedBy <UserDocument>(userId) || allowUnsafe ? functionContext.CallActivityWithRetryAsync <UserDocument>(nameof(UserGetActivity), userId) : throw new NotSupportedException($"Unable to get user '{userId}' without acquired lock");
public static async Task <string> RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { string response = "OK"; List <DataOpParameters> pipelines = context.GetInput <List <DataOpParameters> >(); log.LogInformation($"RunOrchestrator: Number of pipelines: {pipelines.Count}."); foreach (var pipe in pipelines) { context.SetCustomStatus($"Starting pipe number {pipe.Id} with name {pipe.Name}"); if (pipe.Name == "CreateIndex") { response = await context.CallActivityAsync <string>("ManageDataOps_CreateIndex", pipe); } else if (pipe.Name == "DataQC") { List <QcResult> qcList = await context.CallActivityAsync <List <QcResult> >("ManageDataOps_InitDataQC", pipe); var tasks = new Task <List <int> > [qcList.Count]; for (int i = 0; i < qcList.Count; i++) { int qcId = qcList[i].Id; JObject pipeParm = JObject.Parse(pipe.JsonParameters); pipeParm["RuleId"] = qcId; pipe.JsonParameters = pipeParm.ToString(); tasks[i] = context.CallActivityAsync <List <int> >("ManageDataOps_DataQC", pipe); } await Task.WhenAll(tasks); List <RuleFailures> failures = new List <RuleFailures>(); for (int i = 0; i < qcList.Count; i++) { failures.Add(new RuleFailures { RuleId = qcList[i].Id, Failures = tasks[i].Result }); } DataQCDataOpsCloseParameters parms = new DataQCDataOpsCloseParameters() { Parameters = pipe, Failures = failures }; log.LogInformation($"RunOrchestrator: Ready to close data QC"); string stat = await context.CallActivityAsync <string>("ManageDataOps_CloseDataQC", parms); } else if (pipe.Name == "DataTransfer") { log.LogInformation($"Starting data transfer"); List <string> files = await context.CallActivityAsync <List <string> >("ManageDataOps_InitDataTransfer", pipe); TransferParameters parms = JObject.Parse(pipe.JsonParameters).ToObject <TransferParameters>(); if (parms.SourceType == "DataBase") { foreach (string file in files) { JObject pipeParm = JObject.Parse(pipe.JsonParameters); pipeParm["Table"] = file; pipe.JsonParameters = pipeParm.ToString(); string stat = await context.CallActivityAsync <string>("ManageDataOps_DeleteDataTransfer", pipe); } } foreach (string file in files) { JObject pipeParm = JObject.Parse(pipe.JsonParameters); pipeParm["Table"] = file; pipe.JsonParameters = pipeParm.ToString(); string stat = await context.CallActivityAsync <string>("ManageDataOps_DataTransfer", pipe); } } else if (pipe.Name == "Predictions") { log.LogInformation($"Starting Predictions"); List <PredictionCorrection> predictionList = await context.CallActivityAsync <List <PredictionCorrection> >("ManageDataOps_InitPredictions", pipe); var tasks = new Task <string> [predictionList.Count]; JObject pipeParm = JObject.Parse(pipe.JsonParameters); for (int i = 0; i < predictionList.Count; i++) { int id = predictionList[i].Id; pipeParm["PredictionId"] = id; pipe.JsonParameters = pipeParm.ToString(); string stat = await context.CallActivityAsync <string>("ManageDataOps_Prediction", pipe); } } else { log.LogInformation($"Artifact {pipe.Name} does not exist"); } context.SetCustomStatus($"Completed pipe number {pipe.Id} with name {pipe.Name}"); } log.LogInformation($"RunOrchestrator: All pipelines processed"); return(response); }
public async Task <DurableCircuitBreaker> GetBreakerState(string circuitBreakerId, ILogger log, IDurableOrchestrationContext orchestrationContext) { log?.LogCircuitBreakerMessage(circuitBreakerId, $"Getting breaker state for circuit-breaker = '{circuitBreakerId}'."); return(await orchestrationContext.CreateEntityProxy <IDurableCircuitBreaker>(circuitBreakerId).GetBreakerState()); }
public async Task RecordFailure(string circuitBreakerId, ILogger log, IDurableOrchestrationContext orchestrationContext) { log?.LogCircuitBreakerMessage(circuitBreakerId, $"Recording failure for circuit-breaker = '{circuitBreakerId}'."); await orchestrationContext.CreateEntityProxy <IDurableCircuitBreaker>(circuitBreakerId).RecordFailure(); }
public static Task SetAppSettingAsync(this IDurableOrchestrationContext functionContext, string key, string value = default) => functionContext.CallActivityWithRetryAsync(nameof(ProviderCommandAppSettingActivity), (key, value));
public static Task <UserDocument> SetUserProjectMembershipAsync(this IDurableOrchestrationContext functionContext, UserDocument user, string projectId, bool allowUnsafe = false) => functionContext.IsLockedBy <UserDocument>(user.Id) || allowUnsafe ? functionContext.CallActivityWithRetryAsync <UserDocument>(nameof(UserProjectMembershipSetActivity), (user, projectId)) : throw new NotSupportedException($"Unable to create or update project membership without acquired lock for user {user.Id}");
public OrchestrationContextProxy(IDurableOrchestrationContext context) { _context = context; }
public static async Task RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { var notification = context.GetInput <NotificationDataEntity>(); // Update notification status. await context.CallActivityWithRetryAsync( FunctionNames.UpdateNotificationStatusActivity, FunctionSettings.DefaultRetryOptions, (notification.Id, NotificationStatus.SyncingRecipients)); // All users. if (notification.AllUsers) { await context.CallActivityWithRetryAsync( FunctionNames.SyncAllUsersActivity, FunctionSettings.DefaultRetryOptions, notification); return; } // Members of specific teams. if (notification.Rosters.Any()) { var tasks = new List <Task>(); foreach (var teamId in notification.Rosters) { var task = context.CallActivityWithRetryAsync( FunctionNames.SyncTeamMembersActivity, FunctionSettings.DefaultRetryOptions, (notification.Id, teamId)); tasks.Add(task); } // Fan-Out Fan-In. await Task.WhenAll(tasks); return; } // Members of M365 groups, DG or SG. if (notification.Groups.Any()) { var tasks = new List <Task>(); foreach (var groupId in notification.Groups) { var task = context.CallActivityWithRetryAsync( FunctionNames.SyncGroupMembersActivity, FunctionSettings.DefaultRetryOptions, (notification.Id, groupId)); tasks.Add(task); } // Fan-Out Fan-In await Task.WhenAll(tasks); return; } // General channel of teams. if (notification.Teams.Any()) { await context.CallActivityWithRetryAsync( FunctionNames.SyncTeamsActivity, FunctionSettings.DefaultRetryOptions, notification); return; } // Invalid audience. var errorMessage = $"Invalid audience select for notification id: {notification.Id}"; log.LogError(errorMessage); throw new ArgumentException(errorMessage); }
private static void AddUploadTask(List <Task> tasks, IDurableOrchestrationContext context, BlobModel blob) { tasks.Add(context.CallActivityAsync <AnalysisResult>("UploadFunction", blob)); }
public async Task AddCertificate([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log) { var request = context.GetInput <AddCertificateRequest>(); var activity = context.CreateActivityProxy <ISharedFunctions>(); var site = await activity.GetSite((request.ResourceGroupName, request.AppName, request.SlotName)); if (site == null) { log.LogError($"{request.AppName} is not found"); return; } var hostNameSslStates = site.HostNameSslStates .Where(x => request.Domains.Contains(x.Name)) .ToArray(); if (hostNameSslStates.Length != request.Domains.Length) { foreach (var hostName in request.Domains.Except(hostNameSslStates.Select(x => x.Name))) { log.LogError($"{hostName} is not found"); } return; } // ワイルドカード、コンテナ、Linux の場合は DNS-01 を利用する var useDns01Auth = request.Domains.Any(x => x.StartsWith("*")) || site.Kind.Contains("container") || site.Kind.Contains("linux"); // 前提条件をチェック if (useDns01Auth) { await activity.Dns01Precondition(request.Domains); } else { await activity.Http01Precondition(site); } // 新しく ACME Order を作成する var orderDetails = await activity.Order(request.Domains); IList <AcmeChallengeResult> challengeResults; // ACME Challenge を実行 if (useDns01Auth) { // DNS-01 を使う challengeResults = await activity.Dns01Authorization(orderDetails.Payload.Authorizations); // Azure DNS で正しくレコードが引けるか確認 await activity.CheckDnsChallenge(challengeResults); } else { // HTTP-01 を使う challengeResults = await activity.Http01Authorization((site, orderDetails.Payload.Authorizations)); // HTTP で正しくアクセスできるか確認 await activity.CheckHttpChallenge(challengeResults); } // ACME Answer を実行 await activity.AnswerChallenges(challengeResults); // Order のステータスが ready になるまで 60 秒待機 await activity.CheckIsReady(orderDetails); // Order の最終処理を実行し PFX を作成 var(thumbprint, pfxBlob) = await activity.FinalizeOrder((request.Domains, orderDetails)); await activity.UpdateCertificate((site, $"{request.Domains[0]}-{thumbprint}", pfxBlob)); foreach (var hostNameSslState in hostNameSslStates) { hostNameSslState.Thumbprint = thumbprint; hostNameSslState.SslState = request.UseIpBasedSsl ?? false ? SslState.IpBasedEnabled : SslState.SniEnabled; hostNameSslState.ToUpdate = true; } await activity.UpdateSiteBinding(site); // クリーンアップ処理を実行 await activity.CleanupVirtualApplication(site); }
public async Task <Certificate> IssueCertificate([OrchestrationTrigger] IDurableOrchestrationContext context) { var(site, dnsNames, forceDns01Challenge) = context.GetInput <(Site, string[], bool)>(); var activity = context.CreateActivityProxy <ISharedActivity>(); // ワイルドカード、コンテナ、Linux の場合は DNS-01 を利用する var useDns01Auth = forceDns01Challenge || dnsNames.Any(x => x.StartsWith("*")) || site.Kind.Contains("container") || site.Kind.Contains("linux"); // 前提条件をチェック if (useDns01Auth) { await activity.Dns01Precondition(dnsNames); } else { await activity.Http01Precondition(site); } // 新しく ACME Order を作成する var orderDetails = await activity.Order(dnsNames); // 既に確認済みの場合は Challenge をスキップする if (orderDetails.Payload.Status != "ready") { // 複数の Authorizations を処理する IReadOnlyList <AcmeChallengeResult> challengeResults; // ACME Challenge を実行 if (useDns01Auth) { challengeResults = await activity.Dns01Authorization(orderDetails.Payload.Authorizations); // DNS レコードの変更が伝搬するまで 10 秒遅延させる await context.CreateTimer(context.CurrentUtcDateTime.AddSeconds(10), CancellationToken.None); // Azure DNS で正しくレコードが引けるか確認 await activity.CheckDnsChallenge(challengeResults); } else { challengeResults = await activity.Http01Authorization((site, orderDetails.Payload.Authorizations)); // HTTP で正しくアクセスできるか確認 await activity.CheckHttpChallenge(challengeResults); } // ACME Answer を実行 await activity.AnswerChallenges(challengeResults); // Order のステータスが ready になるまで 60 秒待機 await activity.CheckIsReady((orderDetails, challengeResults)); if (useDns01Auth) { // 作成した DNS レコードを削除 await activity.CleanupDnsChallenge(challengeResults); } } // CSR を作成し Finalize を実行 var(finalize, rsaParameters) = await activity.FinalizeOrder((dnsNames, orderDetails)); // Finalize の時点でステータスが valid の時点はスキップ if (finalize.Payload.Status != "valid") { // Finalize 後のステータスが valid になるまで 60 秒待機 finalize = await activity.CheckIsValid(finalize); } // 証明書をダウンロードし App Service へアップロード var certificate = await activity.UploadCertificate((site, dnsNames[0], forceDns01Challenge, finalize, rsaParameters));
public static async Task RunOrchestration( [OrchestrationTrigger] IDurableOrchestrationContext orchestrationContext, ILogger log) { if (orchestrationContext is null) { throw new ArgumentNullException(nameof(orchestrationContext)); } if (log is null) { throw new ArgumentNullException(nameof(log)); } var command = orchestrationContext.GetInput <OrchestratorProjectComponentCreateCommand>(); var commandResult = command.CreateResult(); var component = command.Payload; using (log.BeginCommandScope(command)) { try { orchestrationContext.SetCustomStatus("Getting provider", log); var provider = await orchestrationContext .GetProviderAsync(component.ProviderId, allowUnsafe : true) .ConfigureAwait(true); orchestrationContext.SetCustomStatus("Sending commands", log); var providerCommand = new ProviderComponentCreateCommand ( command.User.PopulateExternalModel(), component.PopulateExternalModel(), command.ProjectId, command.CommandId ); var providerResult = await orchestrationContext .SendProviderCommandAsync <ProviderComponentCreateCommand, ProviderComponentCreateCommandResult>(providerCommand, provider) .ConfigureAwait(true); providerResult.Errors.ToList().ForEach(e => commandResult.Errors.Add(e)); commandResult.Result = component.PopulateFromExternalModel(providerResult.Result); orchestrationContext.SetCustomStatus($"Component created.", log); } catch (Exception exc) { commandResult ??= command.CreateResult(); commandResult.Errors.Add(exc); } finally { var commandException = commandResult.Errors?.ToException(); if (commandException is null) { orchestrationContext.SetCustomStatus($"Command succeeded", log); } else { orchestrationContext.SetCustomStatus($"Command failed", log, commandException); } orchestrationContext.SetOutput(commandResult); } } }
public static async Task <object> ProcessNumbers([OrchestrationTrigger] IDurableOrchestrationContext ctx, ILogger log) { string[] numbers = null; string callinfoAfterCall = null; string answeredCallTaskResult = null; bool callAnswered = false; try { // ***************************** STEP 1 - get the phone numbers from storage* ***************************************** if (!ctx.IsReplaying) { log.LogWarning("About to call A_GetNumbersFromStorage activity"); } // Get the number from storage numbers = await ctx.CallActivityAsync <string[]>("A_GetNumbersFromStorage", null); CallInfo callinfo = new CallInfo { InstanceId = ctx.InstanceId, Numbers = numbers }; // ***************************** STEP 2 - Attempt to make a call ****************************************** if (!ctx.IsReplaying) { log.LogWarning("About to call A_MakeCall activity"); } // Attempt to call the numbers retrieved from storage ////foreach (var number in numbers) ////{ //// var done = false; //// done = await ctx.CallNumberAsync(number, log); //// if (done) //// { //// break; //// } ////} callinfoAfterCall = await ctx.CallActivityAsync <string>("A_MakeCall", callinfo); using (var cts = new CancellationTokenSource()) { var timeout = ctx.CurrentUtcDateTime.AddSeconds(60); var timeoutTask = ctx.CreateTimer(timeout, cts.Token); var answeredCallTask = ctx.WaitForExternalEvent <string>("AnsweredCallResult", TimeSpan.FromSeconds(60), cts.Token); var winner = await Task.WhenAny(answeredCallTask, timeoutTask); if (winner == answeredCallTask) { log.LogWarning($"Call answered at {ctx.CurrentUtcDateTime}"); callAnswered = true; answeredCallTaskResult = answeredCallTask.Result; cts.Cancel(); } else { callAnswered = false; answeredCallTaskResult = "Timed Out"; } } return(new { CallAnswered = callAnswered, Success = true, OrchestrationId = ctx.InstanceId }); } catch (Exception e) { // Log Exception, pefrom any cleanup return(new { Success = false, Error = e.Message }); } }
public static async Task ShareAllTickets([OrchestrationTrigger] IDurableOrchestrationContext context) { var tickets = await context.CallActivityAsync <long[]>(nameof(DurableWatcher.SearchTickets), null); await ShareTickets(context, tickets); }
public async Task RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context, [DurableClient] IDurableOrchestrationClient processStarter, ILogger log) { _correlationInitializer.Initialize(context.InstanceId); var beginProcessCommand = this.BuildBeginProcessCommand(context); await context.CallActivityAsync <Task>(nameof(StatusTracker), beginProcessCommand); var command = context.GetInput <RegisterApplicationCommand>(); var uploadCvCommand = new UploadCvCommand( command.Cv.File, command.Cv.ContentType, command.Cv.Extension); var uploadPhotoCommand = new UploadPhotoCommand( command.Photo.File, command.Photo.ContentType, command.Photo.Extension); await Task.WhenAll( context.CallActivityAsync <Task>(nameof(CvUploader), uploadCvCommand), context.CallActivityAsync <Task>(nameof(PhotoUploader), uploadPhotoCommand)); var cvUploadedEventTask = context.WaitForExternalEvent <CvUploadedInternalFunctionEvent>(nameof(CvUploadedInternalFunctionEvent)); var cvUploadFailedEventTask = context.WaitForExternalEvent <CvUploadFailedInternalFunctionEvent>(nameof(CvUploadFailedInternalFunctionEvent)); var photoUploadedEventTask = context.WaitForExternalEvent <PhotoUploadedInternalFunctionEvent>(nameof(PhotoUploadedInternalFunctionEvent)); var photoUploadFailedEventTask = context.WaitForExternalEvent <PhotoUploadFailedInternalFunctionEvent>(nameof(PhotoUploadFailedInternalFunctionEvent)); var cvUploadEventTask = await Task.WhenAny(cvUploadedEventTask, cvUploadFailedEventTask); var photoUploadEventTask = await Task.WhenAny(photoUploadedEventTask, photoUploadFailedEventTask); var cvUploadedSuccessfully = cvUploadEventTask == cvUploadedEventTask; var photoUploadedSuccessfully = photoUploadEventTask == photoUploadedEventTask; if (!cvUploadedSuccessfully || !photoUploadedSuccessfully) { await this.HandleUploadFilesFailure( context, processStarter, log, photoUploadFailedEventTask, cvUploadFailedEventTask, command); return; } log.LogProgress(OperationStatus.InProgress, "Finished the files uploading", context.InstanceId); var cvUri = cvUploadedEventTask.Result.CvUri; var photoUri = photoUploadedEventTask.Result.PhotoUri; var saveApplicationCommand = new CreateApplicationCommand( context.InstanceId, command.Candidate.FirstName, command.Candidate.LastName, photoUri, cvUri, command.Candidate.Category, command.CreationTime, command.Candidate.EducationLevel, command.Candidate.Address, command.Candidate.FinishedSchools, command.Candidate.ConfirmedSkills, command.Candidate.WorkExperiences, context.InstanceId); await context.CallActivityAsync <Task>(nameof(ApplicationSaver), saveApplicationCommand); var applicationSavedEvent = context.WaitForExternalEvent <ApplicationSavedInternalFunctionEvent>(nameof(ApplicationSavedInternalFunctionEvent)); var applicationSaveFailed = context.WaitForExternalEvent <ApplicationSaveFailedInternalFunctionEvent>(nameof(ApplicationSaveFailedInternalFunctionEvent)); var applicationSaveEvent = await Task.WhenAny(applicationSavedEvent, applicationSaveFailed); var applicationSavedSuccessfully = applicationSaveEvent == applicationSavedEvent; if (!applicationSavedSuccessfully) { log.LogFailedOperation(OperationStatus.Failed, "Storing application failed", applicationSaveFailed.Result.Errors, context.InstanceId); var failedProcessCommand = this.BuildFailedProcessCommand(context, applicationSaveFailed.Result.Errors); await context.CallActivityAsync <Task>(nameof(StatusTracker), failedProcessCommand); await this.StartRecompensateProcess(processStarter, context, command, log); return; } var finishProcessCommand = this.BuildFinishedProcessCommand(context); await context.CallActivityAsync <Task>(nameof(StatusTracker), finishProcessCommand); }
public static async Task ShareListedTickets([OrchestrationTrigger] IDurableOrchestrationContext context) { var tickets = context.GetInput <long[]>(); await ShareTickets(context, tickets); }
public static async Task RunOrchestration( [OrchestrationTrigger] IDurableOrchestrationContext functionContext, ILogger log) { if (functionContext is null) { throw new ArgumentNullException(nameof(functionContext)); } if (log is null) { throw new ArgumentNullException(nameof(log)); } var command = functionContext.GetInput <OrchestratorTeamCloudUserDeleteCommand>(); var commandResult = command.CreateResult(); var user = command.Payload; using (log.BeginCommandScope(command)) { try { functionContext.SetCustomStatus($"Deleting user.", log); using (await functionContext.LockAsync <UserDocument>(user.Id.ToString()).ConfigureAwait(true)) { await functionContext .DeleteUserAsync(user.Id) .ConfigureAwait(true); } var projects = default(IEnumerable <ProjectDocument>); // TODO: this is totally wrong // only update all projects if user was an admin if (user.IsAdmin()) { projects = await functionContext .ListProjectsAsync() .ConfigureAwait(true); } else if (user.ProjectMemberships.Any()) { projects = await functionContext .ListProjectsAsync(user.ProjectMemberships.Select(m => m.ProjectId).ToList()) .ConfigureAwait(true); } if (projects?.Any() ?? false) { foreach (var project in projects) { var projectUpdateCommand = new OrchestratorProjectUpdateCommand(command.BaseApi, command.User, project); functionContext.StartNewOrchestration(nameof(OrchestratorProjectUpdateCommandOrchestration), projectUpdateCommand); } } commandResult.Result = user; functionContext.SetCustomStatus($"User deleted.", log); } catch (Exception ex) { functionContext.SetCustomStatus("Failed to delete user.", log, ex); commandResult ??= command.CreateResult(); commandResult.Errors.Add(ex); throw; } finally { functionContext.SetOutput(commandResult); } } }
public static Task SetInstrumentationKeyAsync(this IDurableOrchestrationContext functionContext, Guid instrumentationKey) => instrumentationKey.ToString().Equals(Environment.GetEnvironmentVariable("APPINSIGHTS_INSTRUMENTATIONKEY"), StringComparison.OrdinalIgnoreCase) ? Task.CompletedTask : functionContext.SetAppSettingAsync("APPINSIGHTS_INSTRUMENTATIONKEY", instrumentationKey.ToString());
public AzureGenerator(FractalOptions options, IDurableOrchestrationContext context, int chunks = 8) : base(options) { _context = context; _chunks = chunks; }
public static async Task <object> ProcessVideo( [OrchestrationTrigger] IDurableOrchestrationContext ctx, ILogger log) { var cart = ctx.GetInput <CartDto>(); string paid = null; string shipped = null; string inventoryDone = null; string approvalResult = "Unknown"; string token = null; try { /* * if (!ctx.IsReplaying) * log.LogInformation("About to call an purchased activity"); * * paid = await ctx.CallActivityAsync<string>("A_Payment", cart); * * if (!ctx.IsReplaying) * log.LogInformation("About to call shipping"); * * shipped = await ctx.CallActivityAsync<string>("A_Shipping", cart); * * if (!ctx.IsReplaying) * log.LogInformation("About to call inventory"); * * inventoryDone = await ctx.CallActivityAsync<string>("A_Inventory", cart); */ await ctx.CallActivityAsync("A_SendApprovalRequestEmail", new ApprovalInfo() { OrchestrationId = ctx.InstanceId, Message = "activate your account." }); using (var cts = new CancellationTokenSource()) { var timeoutAt = ctx.CurrentUtcDateTime.AddMinutes(5); var timeoutTask = ctx.CreateTimer(timeoutAt, cts.Token); var approvalTask = ctx.WaitForExternalEvent <string>("ApprovalResult"); var winner = await Task.WhenAny(approvalTask, timeoutTask); if (winner == approvalTask) { approvalResult = approvalTask.Result; cts.Cancel(); // we should cancel the timeout task } else { approvalResult = "Timed Out"; } } if (approvalResult == "Approved") { token = await ctx.CallActivityAsync <string>("A_GetGigyaToken", cart.Name);//Name is the email. } else { await ctx.CallActivityAsync("A_Reject", "rejected"); } } catch (Exception e) { if (!ctx.IsReplaying) { log.LogError($"Caught an error from an activity: {e.Message}"); } await ctx.CallActivityAsync <string>("A_Cleanup", new[] { paid ?? "", shipped ?? "", inventoryDone ?? "" }); return(new { Error = "Failed to process the purchase", Message = e.Message, Paid = paid ?? "", Shipped = shipped ?? "", InventoryDone = inventoryDone ?? "" }); } return(new CheckoutReturnDto { Paid = paid, Shipped = shipped, InventoryDone = inventoryDone, Token = token }); }