Пример #1
0
        private static async Task <OrchestratorProjectCreateCommandResult> ProvisionAsync(IDurableOrchestrationContext functionContext, OrchestratorProjectCreateCommand command, ILogger log)
        {
            var teamCloud = await functionContext
                            .GetTeamCloudAsync()
                            .ConfigureAwait(true);

            var commandResult = command.CreateResult();

            var project = commandResult.Result = command.Payload;

            project.Tags = teamCloud.Tags.Override(project.Tags);

            var projectUsers = project.Users.ToList();

            var providers = await functionContext
                            .ListProvidersAsync(project.Type.Providers.Select(p => p.Id).ToList())
                            .ConfigureAwait(true);

            var providerUserTasks = providers
                                    .Where(p => p.PrincipalId.HasValue)
                                    .Select(p => functionContext.GetUserAsync(p.PrincipalId.Value.ToString(), allowUnsafe: true));

            var providerUsers = await Task.WhenAll(providerUserTasks)
                                .ConfigureAwait(true);

            foreach (var u in providerUsers)
            {
                u.EnsureProjectMembership(project.Id, ProjectUserRole.Provider);
            }

            projectUsers.AddRange(providerUsers);

            using (await functionContext.LockContainerDocumentAsync(project).ConfigureAwait(true))
            {
                functionContext.SetCustomStatus($"Creating project", log);

                project = commandResult.Result = await functionContext
                                                 .CreateProjectAsync(project)
                                                 .ConfigureAwait(true);

                functionContext.SetCustomStatus($"Adding users", log);

                project.Users = await Task
                                .WhenAll(projectUsers.Select(user => functionContext.SetUserProjectMembershipAsync(user, project.Id, allowUnsafe: true)))
                                .ConfigureAwait(true);
            }

            functionContext.SetCustomStatus($"Allocating subscription", log);

            var subscriptionId = await functionContext
                                 .CallActivityWithRetryAsync <Guid>(nameof(ProjectSubscriptionSelectActivity), project)
                                 .ConfigureAwait(true);

            functionContext.SetCustomStatus($"Initializing subscription", log);

            await functionContext
            .InitializeSubscriptionAsync(subscriptionId, waitFor : false)
            .ConfigureAwait(true);

            functionContext.SetCustomStatus($"Provisioning resources", log);

            var deploymentOutput = await functionContext
                                   .CallDeploymentAsync(nameof(ProjectResourcesCreateActivity), (project, subscriptionId))
                                   .ConfigureAwait(true);

            using (await functionContext.LockContainerDocumentAsync(project).ConfigureAwait(true))
            {
                functionContext.SetCustomStatus($"Provisioning identity", log);

                project.Identity = await functionContext
                                   .CallActivityWithRetryAsync <ProjectIdentity>(nameof(ProjectIdentityCreateActivity), project)
                                   .ConfigureAwait(true);

                project.ResourceGroup = new AzureResourceGroup()
                {
                    SubscriptionId = subscriptionId,
                    Region         = project.Type.Region,
                    Id             = (string)deploymentOutput.GetValueOrDefault("resourceGroupId", default(string)),
                    Name           = (string)deploymentOutput.GetValueOrDefault("resourceGroupName", default(string))
                };

                project = commandResult.Result = await functionContext
                                                 .SetProjectAsync(project)
                                                 .ConfigureAwait(true);
            }

            functionContext.SetCustomStatus($"Tagging resources", log);

            await functionContext
            .CallActivityWithRetryAsync(nameof(ProjectResourcesTagActivity), project)
            .ConfigureAwait(true);

            functionContext.SetCustomStatus($"Registering required resource providers", log);

            await functionContext
            .RegisterResourceProvidersAsync(project)
            .ConfigureAwait(true);

            functionContext.SetCustomStatus($"Sending provider commands", log);

            var providerCommand = new ProviderProjectCreateCommand
                                  (
                command.User.PopulateExternalModel(),
                project.PopulateExternalModel(),
                command.CommandId
                                  );

            var providerResults = await functionContext
                                  .SendProviderCommandAsync <ProviderProjectCreateCommand, ProviderProjectCreateCommandResult>(providerCommand, project, failFast : true)
                                  .ConfigureAwait(true);

            var providerException = providerResults.Values?
                                    .SelectMany(result => result.Errors ?? new List <CommandError>())
                                    .ToException();

            if (providerException != null)
            {
                throw providerException;
            }

            return(commandResult);
        }