public async Task NotifyFeaturePipeStatus(string userId, Guid organizationId, Guid projectId, Guid featureId, Guid projectServiceId, string activityName, string status, HttpClientWrapperAuthorizationModel internalAuthCredentials)
        {
            string notificationUrl = $"{_applicationOptions.Value.Url}/internalapi/realtime/organizations/{organizationId}/projects/{projectId}/features/{featureId}/services/{projectServiceId}/activities";

            var response = await _httpClientWrapperService.PostAsync(notificationUrl, new
            {
                userId       = userId,
                activityName = activityName,
                status       = status
            }, internalAuthCredentials);

            response.EnsureSuccessStatusCode();
        }
Пример #2
0
 public async Task Handle(ProjectFeatureServiceBuildQueuedEvent @event)
 {
     string eventUrl = $"{_applicationOptions.Value.Url}/publicapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}/features/{@event.FeatureId}/services/{@event.ServiceId}/events";
     await _httpClientWrapperService.PostAsync(eventUrl, new
     {
         SubscriptionId = Guid.NewGuid(),
         NotificationId = 1,
         Id             = string.Empty,
         EventType      = "git.push",
         PublisherId    = "ps",
         Message        = new
         {
             Text = "Build requested from PipelineSpace"
         },
         DetailedMessage = new { },
         Resource        = new { },
         Status          = "Queued",
         Date            = DateTime.UtcNow
     }, InternalAuthCredentials);
 }
Пример #3
0
        public async Task CompleteProjectFeature(ProjectFeatureCompletedEvent @event)
        {
            string accountUrl = $"https://{@event.CMSAccountName}.visualstudio.com";

            foreach (var item in @event.Services)
            {
                /*Delete Infrastructure*/
                if (@event.DeleteInfrastructure)
                {
                    CPSAuthModel authModel = new CPSAuthModel();
                    authModel.AccessId        = @event.CPSAccessId;
                    authModel.AccessName      = @event.CPSAccessName;
                    authModel.AccessSecret    = @event.CPSAccessSecret;
                    authModel.AccessRegion    = @event.CPSAccessRegion;
                    authModel.AccessAppId     = @event.CPSAccessAppId;
                    authModel.AccessAppSecret = @event.CPSAccessAppSecret;
                    authModel.AccessDirectory = @event.CPSAccessDirectory;

                    string cloudServiceName = $"{@event.OrganizationName}{@event.ProjectName}{item.ServiceName}development{@event.FeatureName}".ToLower();
                    await _cpsService(@event.CPSType).DeleteService(cloudServiceName, authModel);
                }

                HttpClientWrapperAuthorizationModel authCredentials = new HttpClientWrapperAuthorizationModel();
                authCredentials.Schema = "Basic";
                authCredentials.Value  = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", @event.CMSAccessSecret)));

                CMSVSTSPullRequestCreateModel pullRequestModel = new CMSVSTSPullRequestCreateModel();
                pullRequestModel.SourceRefName = $"refs/heads/{@event.FeatureName.ToLower()}";
                pullRequestModel.TargetRefName = "refs/heads/master";
                pullRequestModel.Title         = $"feature {@event.FeatureName}";
                pullRequestModel.Description   = $"The feature {@event.FeatureName} requests merge operation";

                string pullRequestUrl      = $"{accountUrl}/{@event.ProjectExternalId}/_apis/git/repositories/{item.ServiceExternalId}/pullrequests?api-version={_vstsOptions.Value.ApiVersion}";
                var    pullRequestResponse = await _httpClientWrapperService.PostAsync(pullRequestUrl, pullRequestModel, authCredentials);

                pullRequestResponse.EnsureSuccessStatusCode();
            }
        }
Пример #4
0
        public async Task CompleteProjectFeature(ProjectFeatureCompletedEvent @event)
        {
            foreach (var item in @event.Services)
            {
                /*Delete Infrastructure*/
                if (@event.DeleteInfrastructure)
                {
                    CPSAuthModel authModel = new CPSAuthModel();
                    authModel.AccessId        = @event.CPSAccessId;
                    authModel.AccessName      = @event.CPSAccessName;
                    authModel.AccessSecret    = @event.CPSAccessSecret;
                    authModel.AccessRegion    = @event.CPSAccessRegion;
                    authModel.AccessAppId     = @event.CPSAccessAppId;
                    authModel.AccessAppSecret = @event.CPSAccessAppSecret;
                    authModel.AccessDirectory = @event.CPSAccessDirectory;

                    string cloudServiceName = $"{@event.OrganizationName}{@event.ProjectName}{item.ServiceName}development{@event.FeatureName}".ToLower();
                    await _cpsService(@event.CPSType).DeleteService(cloudServiceName, authModel);
                }

                CMSGitHubPullRequestCreateModel pullRequestModel = new CMSGitHubPullRequestCreateModel();
                pullRequestModel.SourceRefName = $"{@event.FeatureName.ToLower()}";
                pullRequestModel.TargetRefName = "master";
                pullRequestModel.Title         = $"feature {@event.FeatureName}";
                pullRequestModel.Description   = $"The feature {@event.FeatureName} requests merge operation";

                HttpClientWrapperAuthorizationModel authCredentials = new HttpClientWrapperAuthorizationModel();
                authCredentials.Schema = "Bearer";
                authCredentials.Value  = @event.CMSAccessToken;

                string pullRequestUrl      = $"https://api.github.com/repos/{@event.CMSAccountName}/{item.ServiceName}/pulls";
                var    pullRequestResponse = await _httpClientWrapperService.PostAsync(pullRequestUrl, pullRequestModel, authCredentials, headers : Headers);

                pullRequestResponse.EnsureSuccessStatusCode();
            }
        }
Пример #5
0
        public async Task CreateProject(ProjectCreatedEvent @event, ApplicationOptions applicationOptions)
        {
            /*Create project*/
            var oAuthToken = await _httpClientWrapperService.GetTokenFromClientCredentials($"{applicationOptions.Url}/connect/token", applicationOptions.ClientId, applicationOptions.ClientSecret, applicationOptions.Scope);

            HttpClientWrapperAuthorizationModel internalAuthCredentials = new HttpClientWrapperAuthorizationModel();

            internalAuthCredentials.Schema = "Bearer";
            internalAuthCredentials.Value  = oAuthToken.access_token;

            //Post Fake Project
            string projectPostUrl = $"{applicationOptions.Url}/internalapi/organizations/{@event.OrganizationId}/fake/vsts/projects/{@event.ProjectId}";
            var    response       = await _httpClientWrapperService.PostAsync(projectPostUrl, new { }, internalAuthCredentials);

            response.EnsureSuccessStatusCode();

            /*Wait for project to activate*/
            string accountUrl = $"https://{_fakeAccountOptions.Value.AccountId}.visualstudio.com";
            int    index      = 0;

            while (true)
            {
                HttpClientWrapperAuthorizationModel authCredentials = new HttpClientWrapperAuthorizationModel();
                authCredentials.Schema = "Basic";
                authCredentials.Value  = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", _fakeAccountOptions.Value.AccessSecret)));

                string projectUrl      = $"{accountUrl}/_apis/projects?api-version={_fakeAccountOptions.Value.ApiVersion}";
                var    projectResponse = await _httpClientWrapperService.GetAsync(projectUrl, authCredentials);

                projectResponse.EnsureSuccessStatusCode();

                var projects = await projectResponse.MapTo <CMSVSTSProjectListModel>();

                var project = projects.Items.FirstOrDefault(x => x.Name.Equals(@event.ProjectVSTSFake, StringComparison.InvariantCultureIgnoreCase));
                if (project != null)
                {
                    oAuthToken = await _httpClientWrapperService.GetTokenFromClientCredentials($"{applicationOptions.Url}/connect/token", applicationOptions.ClientId, applicationOptions.ClientSecret, applicationOptions.Scope);

                    internalAuthCredentials        = new HttpClientWrapperAuthorizationModel();
                    internalAuthCredentials.Schema = "Bearer";
                    internalAuthCredentials.Value  = oAuthToken.access_token;

                    //Patch Project External Id
                    string projectPatchUrl      = $"{applicationOptions.Url}/internalapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}";
                    var    projectPatchResponse = await _httpClientWrapperService.PatchAsync(projectPatchUrl, new { ProjectVSTSFakeId = project.Id }, internalAuthCredentials);

                    projectPatchResponse.EnsureSuccessStatusCode();

                    break;
                }
                else
                {
                    index++;
                    //this means after 20 seconds it didn't create the project
                    if (index == 6)
                    {
                        throw new Exception($"After 20 seconds it could be possible to retreive the external project id: Ref: {@event.ProjectId} - {@event.ProjectName}");
                    }

                    Thread.Sleep(TimeSpan.FromSeconds(5));
                }
            }
        }
        public async Task Handle(ProjectFeatureServiceCreatedEvent @event)
        {
            this.userId = @event.UserId;

            GetQueueResult queue = null;

            await ExecuteProjectFeatureServiceActivity(@event.OrganizationId, @event.ProjectId, @event.FeatureId, @event.ServiceId, nameof(DomainConstants.Activities.PSPRRQ), async() => {
                /* QUEUE - POOL ####################################################################################################################################################*/
                GetQueueOptions getQueueOptions      = new GetQueueOptions();
                getQueueOptions.CMSType              = @event.CMSType;
                getQueueOptions.VSTSAPIVersion       = _vstsOptions.Value.ApiVersion;
                getQueueOptions.VSTSAccountName      = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccountName : _fakeAccountOptions.Value.AccountId;
                getQueueOptions.VSTSAccessSecret     = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccessSecret : _fakeAccountOptions.Value.AccessSecret;
                getQueueOptions.VSTSAccountProjectId = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectName : @event.ProjectVSTSFakeName;
                getQueueOptions.ProjectName          = @event.ProjectName;
                getQueueOptions.AgentPoolId          = @event.AgentPoolId;

                queue = await _pipelineSpaceManagerService.GetQueue(getQueueOptions);
            });

            string releaseDefinition = string.Empty;

            await ExecuteProjectFeatureServiceActivity(@event.OrganizationId, @event.ProjectId, @event.FeatureId, @event.ServiceId, nameof(DomainConstants.Activities.PSCRBR), async() => {
                CreateBranchOptions createBranchOptions       = new CreateBranchOptions();
                createBranchOptions.ProjectName               = @event.ProjectName;
                createBranchOptions.FeatureName               = @event.FeatureName;
                createBranchOptions.ServiceName               = @event.ServiceName;
                createBranchOptions.VSTSAccessId              = _vstsOptions.Value.AccessId;
                createBranchOptions.VSTSAccessSecret          = _vstsOptions.Value.AccessSecret;
                createBranchOptions.VSTSRepositoryTemplateUrl = @event.ServiceTemplateUrl;
                createBranchOptions.GitProviderType           = @event.CMSType;
                createBranchOptions.GitProviderAccessId       = @event.CMSAccessId;
                createBranchOptions.GitProviderAccessSecret   = @event.CMSAccessSecret;
                createBranchOptions.GitProviderAccessToken    = @event.CMSAccessToken;
                createBranchOptions.GitProviderRepositoryUrl  = @event.ServiceExternalUrl;
                createBranchOptions.TemplateAccess            = @event.TemplateAccess;
                createBranchOptions.NeedCredentials           = @event.NeedCredentials;
                createBranchOptions.RepositoryCMSType         = @event.RepositoryCMSType;
                createBranchOptions.RepositoryAccessId        = @event.RepositoryAccessId;
                createBranchOptions.RepositoryAccessSecret    = @event.RepositoryAccessSecret;
                createBranchOptions.RepositoryAccessToken     = @event.RepositoryAccessToken;
                createBranchOptions.IsImported = @event.IsImported;

                releaseDefinition = await _pipelineSpaceManagerService.CreateBranch(createBranchOptions);
            });

            /* COMMIT-STAGE ##############################################################################################################################################*/
            CreateBuildDefinitionOptions createBuildDefinitionOptions = null;
            int  commitStageId       = 0;
            Guid?commitServiceHookId = null;
            Guid?codeServiceHookId   = null;

            await ExecuteProjectFeatureServiceActivity(@event.OrganizationId, @event.ProjectId, @event.FeatureId, @event.ServiceId, nameof(DomainConstants.Activities.PSCRBD), async() => {
                createBuildDefinitionOptions = new CreateBuildDefinitionOptions();
                createBuildDefinitionOptions.VSTSAPIVersion       = _vstsOptions.Value.ApiVersion;
                createBuildDefinitionOptions.VSTSAccountName      = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccountName : _fakeAccountOptions.Value.AccountId;
                createBuildDefinitionOptions.VSTSAccessSecret     = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccessSecret : _fakeAccountOptions.Value.AccessSecret;
                createBuildDefinitionOptions.VSTSAccountProjectId = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectName : @event.ProjectVSTSFakeName;

                createBuildDefinitionOptions.ProjectName                 = @event.ProjectName;
                createBuildDefinitionOptions.ServiceName                 = @event.ServiceName;
                createBuildDefinitionOptions.CommitStageName             = $"{@event.InternalServiceName}-ft-{@event.FeatureName}";
                createBuildDefinitionOptions.GitProviderType             = @event.CMSType;
                createBuildDefinitionOptions.GitProviderAccountId        = @event.CMSAccountId;
                createBuildDefinitionOptions.GitProviderAccountName      = @event.CMSAccountName;
                createBuildDefinitionOptions.GitProviderAccessId         = @event.CMSAccessId;
                createBuildDefinitionOptions.GitProviderAccessSecret     = @event.CMSAccessSecret;
                createBuildDefinitionOptions.GitProviderAccessToken      = @event.CMSAccessToken;
                createBuildDefinitionOptions.GitProviderRepositoryId     = @event.ServiceExternalId;
                createBuildDefinitionOptions.GitProviderRepositoryUrl    = @event.ServiceExternalUrl;
                createBuildDefinitionOptions.GitProviderRepositoryBranch = @event.CMSType == ConfigurationManagementService.VSTS ? $"refs/heads/{@event.FeatureName.ToLower()}" : @event.FeatureName.ToLower();
                createBuildDefinitionOptions.ProjectExternalGitEndpoint  = @event.ProjectExternalGitEndpoint;
                createBuildDefinitionOptions.QueueId   = queue.QueueId;
                createBuildDefinitionOptions.QueueName = queue.QueueName;
                createBuildDefinitionOptions.PoolId    = queue.PoolId;
                createBuildDefinitionOptions.PoolName  = queue.PoolName;
                if (@event.IsImported)
                {
                    createBuildDefinitionOptions.YamlFilename = ".pipelinespace/build.definition.yml";
                }

                commitStageId = await _pipelineSpaceManagerService.CreateBuildDefinition(createBuildDefinitionOptions);

                /* SERVICE-HOOK BUILD ##############################################################################################################################################*/
                if (@event.CMSType == ConfigurationManagementService.VSTS)
                {
                    CreateServiceHookOptions createServiceHookCodeOptions = new CreateServiceHookOptions();
                    createServiceHookCodeOptions.VSTSAPIVersion           = _vstsOptions.Value.ApiVersion;
                    createServiceHookCodeOptions.VSTSAccountName          = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccountName : _fakeAccountOptions.Value.AccountId;
                    createServiceHookCodeOptions.VSTSAccessSecret         = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccessSecret : _fakeAccountOptions.Value.AccessSecret;
                    createServiceHookCodeOptions.VSTSAccountProjectId     = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectName : @event.ProjectVSTSFakeName;

                    createServiceHookCodeOptions.OrganizationId    = @event.OrganizationId;
                    createServiceHookCodeOptions.ProjectId         = @event.ProjectId;
                    createServiceHookCodeOptions.ServiceId         = @event.ServiceId;
                    createServiceHookCodeOptions.ProjectExternalId = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectExternalId : @event.ProjectVSTSFakeId;
                    createServiceHookCodeOptions.EventType         = "code";
                    createServiceHookCodeOptions.Definition        = createBuildDefinitionOptions.CommitStageName;
                    createServiceHookCodeOptions.Url = $"{_applicationOptions.Value.Url}/publicapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}/features/{@event.FeatureId}/services/{@event.ServiceId}/events";

                    createServiceHookCodeOptions.Repository = @event.ServiceExternalId;
                    createServiceHookCodeOptions.Branch     = @event.FeatureName.ToLower();

                    codeServiceHookId = await _pipelineSpaceManagerService.CreateServiceHook(createServiceHookCodeOptions);
                }

                CreateServiceHookOptions createServiceHookBuildOptions = new CreateServiceHookOptions();
                createServiceHookBuildOptions.VSTSAPIVersion           = _vstsOptions.Value.ApiVersion;
                createServiceHookBuildOptions.VSTSAccountName          = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccountName : _fakeAccountOptions.Value.AccountId;
                createServiceHookBuildOptions.VSTSAccessSecret         = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccessSecret : _fakeAccountOptions.Value.AccessSecret;
                createServiceHookBuildOptions.VSTSAccountProjectId     = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectName : @event.ProjectVSTSFakeName;

                createServiceHookBuildOptions.OrganizationId    = @event.OrganizationId;
                createServiceHookBuildOptions.ProjectId         = @event.ProjectId;
                createServiceHookBuildOptions.ServiceId         = @event.ServiceId;
                createServiceHookBuildOptions.ProjectExternalId = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectExternalId : @event.ProjectVSTSFakeId;
                createServiceHookBuildOptions.EventType         = "build";
                createServiceHookBuildOptions.Definition        = createBuildDefinitionOptions.CommitStageName;
                createServiceHookBuildOptions.Url = $"{_applicationOptions.Value.Url}/publicapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}/features/{@event.FeatureId}/services/{@event.ServiceId}/events";

                commitServiceHookId = await _pipelineSpaceManagerService.CreateServiceHook(createServiceHookBuildOptions);
            });

            /* RELEASE-STAGE ##############################################################################################################################################*/
            int? releaseStageId                        = null;
            Guid?releaseServiceHookId                  = null;
            Guid?releaseStartedServiceHookId           = null;
            Guid?releasePendingApprovalServiceHookId   = null;
            Guid?releaseCompletedApprovalServiceHookId = null;

            if ([email protected])
            {
                await ExecuteProjectFeatureServiceActivity(@event.OrganizationId, @event.ProjectId, @event.FeatureId, @event.ServiceId, nameof(DomainConstants.Activities.PSCRRD), async() => {
                    CreateReleaseDefinitionOptions createReleaseDefinitionOptions = new CreateReleaseDefinitionOptions();
                    createReleaseDefinitionOptions.VSTSAPIVersion       = _vstsOptions.Value.ApiVersion;
                    createReleaseDefinitionOptions.VSTSAccountName      = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccountName : _fakeAccountOptions.Value.AccountId;
                    createReleaseDefinitionOptions.VSTSAccessSecret     = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccessSecret : _fakeAccountOptions.Value.AccessSecret;
                    createReleaseDefinitionOptions.VSTSAccountProjectId = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectName : @event.ProjectVSTSFakeName;

                    createReleaseDefinitionOptions.OrganizationName        = @event.OrganizationName;
                    createReleaseDefinitionOptions.ProjectName             = @event.ProjectName;
                    createReleaseDefinitionOptions.ServiceName             = @event.ServiceName;
                    createReleaseDefinitionOptions.CommitStageName         = createBuildDefinitionOptions.CommitStageName;
                    createReleaseDefinitionOptions.ReleaseStageName        = createBuildDefinitionOptions.CommitStageName;
                    createReleaseDefinitionOptions.BuildDefinitionName     = createBuildDefinitionOptions.CommitStageName;
                    createReleaseDefinitionOptions.ReleaseDefinition       = releaseDefinition;
                    createReleaseDefinitionOptions.CloudProviderEndpointId = @event.ProjectExternalEndpointId;
                    createReleaseDefinitionOptions.ProjectExternalId       = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectExternalId : @event.ProjectVSTSFakeId;
                    createReleaseDefinitionOptions.CommitStageId           = commitStageId;
                    createReleaseDefinitionOptions.QueueId = queue.QueueId;
                    createReleaseDefinitionOptions.CloudProviderAccessId     = @event.CPSAccessId;
                    createReleaseDefinitionOptions.CloudProviderAccessSecret = @event.CPSAccessSecret;
                    createReleaseDefinitionOptions.CloudProviderAccessRegion = @event.CPSAccessRegion;
                    createReleaseDefinitionOptions.WorkFeature        = @event.FeatureName;
                    createReleaseDefinitionOptions.BaseReleaseStageId = @event.ReleaseStageId;

                    releaseStageId = await _pipelineSpaceManagerService.CreateReleaseDefinitionFromBaseDefinition(createReleaseDefinitionOptions);

                    if (releaseStageId.HasValue)
                    {
                        /* SERVICE-HOOK RELEASe ##############################################################################################################################################*/
                        CreateServiceHookOptions createServiceHookReleaseStartedOptions = new CreateServiceHookOptions();
                        createServiceHookReleaseStartedOptions.VSTSAPIVersion           = _vstsOptions.Value.ApiVersion;
                        createServiceHookReleaseStartedOptions.VSTSAccountName          = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccountName : _fakeAccountOptions.Value.AccountId;
                        createServiceHookReleaseStartedOptions.VSTSAccessSecret         = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccessSecret : _fakeAccountOptions.Value.AccessSecret;
                        createServiceHookReleaseStartedOptions.VSTSAccountProjectId     = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectName : @event.ProjectVSTSFakeName;

                        createServiceHookReleaseStartedOptions.OrganizationId    = @event.OrganizationId;
                        createServiceHookReleaseStartedOptions.ProjectId         = @event.ProjectId;
                        createServiceHookReleaseStartedOptions.ServiceId         = @event.ServiceId;
                        createServiceHookReleaseStartedOptions.ProjectExternalId = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectExternalId : @event.ProjectVSTSFakeId;
                        createServiceHookReleaseStartedOptions.EventType         = "releaseStarted";
                        createServiceHookReleaseStartedOptions.Definition        = releaseStageId.Value.ToString();
                        createServiceHookReleaseStartedOptions.Url = $"{_applicationOptions.Value.Url}/publicapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}/features/{@event.FeatureId}/services/{@event.ServiceId}/events";

                        releaseStartedServiceHookId = await _pipelineSpaceManagerService.CreateServiceHook(createServiceHookReleaseStartedOptions);

                        CreateServiceHookOptions createServiceHookReleasePendingApprovalOptions = new CreateServiceHookOptions();
                        createServiceHookReleasePendingApprovalOptions.VSTSAPIVersion           = _vstsOptions.Value.ApiVersion;
                        createServiceHookReleasePendingApprovalOptions.VSTSAccountName          = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccountName : _fakeAccountOptions.Value.AccountId;
                        createServiceHookReleasePendingApprovalOptions.VSTSAccessSecret         = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccessSecret : _fakeAccountOptions.Value.AccessSecret;
                        createServiceHookReleasePendingApprovalOptions.VSTSAccountProjectId     = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectName : @event.ProjectVSTSFakeName;

                        createServiceHookReleasePendingApprovalOptions.OrganizationId    = @event.OrganizationId;
                        createServiceHookReleasePendingApprovalOptions.ProjectId         = @event.ProjectId;
                        createServiceHookReleasePendingApprovalOptions.ServiceId         = @event.ServiceId;
                        createServiceHookReleasePendingApprovalOptions.ProjectExternalId = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectExternalId : @event.ProjectVSTSFakeId;
                        createServiceHookReleasePendingApprovalOptions.EventType         = "releasePendingApproval";
                        createServiceHookReleasePendingApprovalOptions.Definition        = releaseStageId.Value.ToString();
                        createServiceHookReleasePendingApprovalOptions.Url = $"{_applicationOptions.Value.Url}/publicapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}/features/{@event.FeatureId}/services/{@event.ServiceId}/events";

                        releasePendingApprovalServiceHookId = await _pipelineSpaceManagerService.CreateServiceHook(createServiceHookReleasePendingApprovalOptions);

                        CreateServiceHookOptions createServiceHookReleaseCompletedApprovalOptions = new CreateServiceHookOptions();
                        createServiceHookReleaseCompletedApprovalOptions.VSTSAPIVersion           = _vstsOptions.Value.ApiVersion;
                        createServiceHookReleaseCompletedApprovalOptions.VSTSAccountName          = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccountName : _fakeAccountOptions.Value.AccountId;
                        createServiceHookReleaseCompletedApprovalOptions.VSTSAccessSecret         = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccessSecret : _fakeAccountOptions.Value.AccessSecret;
                        createServiceHookReleaseCompletedApprovalOptions.VSTSAccountProjectId     = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectName : @event.ProjectVSTSFakeName;

                        createServiceHookReleaseCompletedApprovalOptions.OrganizationId    = @event.OrganizationId;
                        createServiceHookReleaseCompletedApprovalOptions.ProjectId         = @event.ProjectId;
                        createServiceHookReleaseCompletedApprovalOptions.ServiceId         = @event.ServiceId;
                        createServiceHookReleaseCompletedApprovalOptions.ProjectExternalId = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectExternalId : @event.ProjectVSTSFakeId;
                        createServiceHookReleaseCompletedApprovalOptions.EventType         = "releaseCompletedApproval";
                        createServiceHookReleaseCompletedApprovalOptions.Definition        = releaseStageId.Value.ToString();
                        createServiceHookReleaseCompletedApprovalOptions.Url = $"{_applicationOptions.Value.Url}/publicapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}/features/{@event.FeatureId}/services/{@event.ServiceId}/events";

                        releaseCompletedApprovalServiceHookId = await _pipelineSpaceManagerService.CreateServiceHook(createServiceHookReleaseCompletedApprovalOptions);

                        CreateServiceHookOptions createServiceHookReleaseOptions = new CreateServiceHookOptions();
                        createServiceHookReleaseOptions.VSTSAPIVersion           = _vstsOptions.Value.ApiVersion;
                        createServiceHookReleaseOptions.VSTSAccountName          = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccountName : _fakeAccountOptions.Value.AccountId;
                        createServiceHookReleaseOptions.VSTSAccessSecret         = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccessSecret : _fakeAccountOptions.Value.AccessSecret;
                        createServiceHookReleaseOptions.VSTSAccountProjectId     = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectName : @event.ProjectVSTSFakeName;

                        createServiceHookReleaseOptions.OrganizationId    = @event.OrganizationId;
                        createServiceHookReleaseOptions.ProjectId         = @event.ProjectId;
                        createServiceHookReleaseOptions.ServiceId         = @event.ServiceId;
                        createServiceHookReleaseOptions.ProjectExternalId = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectExternalId : @event.ProjectVSTSFakeId;
                        createServiceHookReleaseOptions.EventType         = "release";
                        createServiceHookReleaseOptions.Definition        = releaseStageId.Value.ToString();
                        createServiceHookReleaseOptions.Url = $"{_applicationOptions.Value.Url}/publicapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}/features/{@event.FeatureId}/services/{@event.ServiceId}/events";

                        releaseServiceHookId = await _pipelineSpaceManagerService.CreateServiceHook(createServiceHookReleaseOptions);
                    }
                });
            }


            /* QUEUE - BUILD ##############################################################################################################################################*/

            await ExecuteProjectFeatureServiceActivity(@event.OrganizationId, @event.ProjectId, @event.FeatureId, @event.ServiceId, nameof(DomainConstants.Activities.PSQUDB), async() => {
                QueueBuildOptions queueBuildOptions    = new QueueBuildOptions();
                queueBuildOptions.VSTSAPIVersion       = _vstsOptions.Value.ApiVersion;
                queueBuildOptions.VSTSAccountName      = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccountName : _fakeAccountOptions.Value.AccountId;
                queueBuildOptions.VSTSAccessSecret     = @event.CMSType == ConfigurationManagementService.VSTS ? @event.CMSAccessSecret : _fakeAccountOptions.Value.AccessSecret;
                queueBuildOptions.VSTSAccountProjectId = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectName : @event.ProjectVSTSFakeName;

                queueBuildOptions.ProjectName       = @event.ProjectName;
                queueBuildOptions.ProjectExternalId = @event.CMSType == ConfigurationManagementService.VSTS ? @event.ProjectExternalId : @event.ProjectVSTSFakeId;
                queueBuildOptions.QueueId           = queue.QueueId;
                queueBuildOptions.BuildDefinitionId = commitStageId;
                queueBuildOptions.SourceBranch      = @event.CMSType == ConfigurationManagementService.VSTS ? $"refs/heads/{@event.FeatureName.ToLower()}" : @event.FeatureName.ToLower();

                await _pipelineSpaceManagerService.QueueBuild(queueBuildOptions);

                string eventUrl = $"{_applicationOptions.Value.Url}/publicapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}/features/{@event.FeatureId}/services/{@event.ServiceId}/events";
                await _httpClientWrapperService.PostAsync(eventUrl, new
                {
                    SubscriptionId = Guid.NewGuid(),
                    NotificationId = 1,
                    Id             = string.Empty,
                    EventType      = "git.push",
                    PublisherId    = "ps",
                    Message        = new
                    {
                        Text = "PipelineSpace initial build"
                    },
                    DetailedMessage = new { },
                    Resource        = new { },
                    Status          = "Queued",
                    Date            = DateTime.UtcNow
                }, InternalAuthCredentials);
            });

            //Patch Feature Service
            await ExecuteProjectFeatureServiceActivity(@event.OrganizationId, @event.ProjectId, @event.FeatureId, @event.ServiceId, nameof(DomainConstants.Activities.PSACBA), async() => {
                string projectFeatureServicePatchUrl   = $"{_applicationOptions.Value.Url}/internalapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}/features/{@event.FeatureId}/services/{@event.ServiceId}";
                var projectFeatureServicePatchResponse = await _httpClientWrapperService.PatchAsync(projectFeatureServicePatchUrl,
                                                                                                    new
                {
                    CommitStageId                         = commitStageId,
                    ReleaseStageId                        = releaseStageId,
                    CommitServiceHookId                   = commitServiceHookId,
                    ReleaseServiceHookId                  = releaseServiceHookId,
                    CodeServiceHookId                     = codeServiceHookId,
                    ReleaseStartedServiceHookId           = releaseStartedServiceHookId,
                    ReleasePendingApprovalServiceHookId   = releasePendingApprovalServiceHookId,
                    ReleaseCompletedApprovalServiceHookId = releaseCompletedApprovalServiceHookId,
                    PipelineStatus                        = PipelineStatus.Building
                }, InternalAuthCredentials);
                projectFeatureServicePatchResponse.EnsureSuccessStatusCode();
            });
        }
        public async Task Handle(ProjectImportedEvent @event)
        {
            this.userId = @event.UserId;
            string accountUrl     = string.Empty;
            string accountSecret  = string.Empty;
            string accountProject = string.Empty;

            if (@event.CMSType == ConfigurationManagementService.VSTS)
            {
                accountUrl     = $"https://{@event.CMSAccountName}.visualstudio.com";
                accountSecret  = @event.CMSAccessSecret;
                accountProject = @event.ProjectExternalName;
            }
            else
            {
                accountUrl     = $"https://{_vstsFakeOptions.Value.AccountId}.visualstudio.com";
                accountSecret  = _vstsFakeOptions.Value.AccessSecret;
                accountProject = @event.ProjectVSTSFake;
            }

            await ExecuteProjectActivity(@event.OrganizationId, @event.ProjectId, nameof(DomainConstants.Activities.PRCRBA), async() =>
            {
                await _projectHandlerService(@event.CMSType).ImportProject(@event, _applicationOptions.Value);
            });

            HttpClientWrapperAuthorizationModel authCredentials = new HttpClientWrapperAuthorizationModel();

            authCredentials.Schema = "Basic";
            authCredentials.Value  = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", accountSecret)));

            //Extesions
            if (@event.CPSType == CloudProviderService.AWS)
            {
                if (@event.CMSType == ConfigurationManagementService.VSTS)
                {
                    await ExecuteProjectActivity(@event.OrganizationId, @event.ProjectId, nameof(DomainConstants.Activities.PREXBA), async() =>
                    {
                        string extensionUrl   = $"https://extmgmt.dev.azure.com/{@event.CMSAccountName}/_apis/extensionmanagement/installedextensionsbyname/AmazonWebServices/aws-vsts-tools?api-version=4.1-preview.1";
                        var extensionResponse = await _httpClientWrapperService.GetAsync(extensionUrl, authCredentials);
                        if (extensionResponse.StatusCode == System.Net.HttpStatusCode.NotFound)
                        {
                            extensionResponse = await _httpClientWrapperService.PostAsync(extensionUrl, new { }, authCredentials);
                            extensionResponse.EnsureSuccessStatusCode();
                        }
                    });
                }

                if (@event.CMSType == ConfigurationManagementService.GitHub)
                {
                    await ExecuteProjectActivity(@event.OrganizationId, @event.ProjectId, nameof(DomainConstants.Activities.PREXBA), async() =>
                    {
                        await Task.CompletedTask;
                    });
                }
            }

            if (@event.CPSType == CloudProviderService.Azure)
            {
                await ExecuteProjectActivity(@event.OrganizationId, @event.ProjectId, nameof(DomainConstants.Activities.PREXBO), async() =>
                {
                    string extensionUrl   = $"https://extmgmt.dev.azure.com/{@event.CMSAccountName}/_apis/extensionmanagement/installedextensionsbyname/keesschollaart/arm-outputs?api-version=4.1-preview.1";
                    var extensionResponse = await _httpClientWrapperService.GetAsync(extensionUrl, authCredentials);
                    if (extensionResponse.StatusCode == System.Net.HttpStatusCode.NotFound)
                    {
                        extensionResponse = await _httpClientWrapperService.PostAsync(extensionUrl, new { }, authCredentials);
                        extensionResponse.EnsureSuccessStatusCode();
                    }
                });
            }


            //Create Service Endpoint - Cloud
            //######################################################################################################################################################
            Guid serviceEndpointId = Guid.NewGuid();
            CMSVSTSServiceEndpointModel service = null;

            if (@event.CPSType == CloudProviderService.AWS)
            {
                service = CMSVSTSServiceEndpointModel.Factory.CreateAWSService(serviceEndpointId, $"{@event.ProjectName}AWS", @event.CPSAccessId, @event.CPSAccessSecret);
            }

            if (@event.CPSType == CloudProviderService.Azure)
            {
                service = CMSVSTSServiceEndpointModel.Factory.CreateAzureService(serviceEndpointId, $"{@event.ProjectName}Az", @event.CPSAccessId, @event.CPSAccessName, @event.CPSAccessAppId, @event.CPSAccessAppSecret, @event.CPSAccessDirectory);
            }

            string serviceEndpointUrl = string.Empty;
            HttpResponseMessage serviceEndpointResponse = null;
            string projectPatchUrl = string.Empty;
            HttpResponseMessage         projectPatchResponse = null;
            CMSVSTSServiceEndpointModel serviceEndpoint      = null;

            await ExecuteProjectActivity(@event.OrganizationId, @event.ProjectId, nameof(DomainConstants.Activities.PRCLEP), async() =>
            {
                serviceEndpointUrl      = $"{accountUrl}/{accountProject}/_apis/serviceendpoint/endpoints?api-version={_vstsOptions.Value.ApiVersion}-preview";
                serviceEndpointResponse = await _httpClientWrapperService.PostAsync(serviceEndpointUrl, service, authCredentials);
                serviceEndpointResponse.EnsureSuccessStatusCode();

                serviceEndpoint = await serviceEndpointResponse.MapTo <CMSVSTSServiceEndpointModel>();

                //Patch External Endpoint Id
                projectPatchUrl      = $"{_applicationOptions.Value.Url}/internalapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}";
                projectPatchResponse = await _httpClientWrapperService.PatchAsync(projectPatchUrl, new { ProjectExternalEndpointId = serviceEndpoint.Id.ToString() }, InternalAuthCredentials);
                projectPatchResponse.EnsureSuccessStatusCode();
            });

            //Create Service Endpoint - Git
            //######################################################################################################################################################

            await ExecuteProjectActivity(@event.OrganizationId, @event.ProjectId, nameof(DomainConstants.Activities.PRGTEP), async() =>
            {
                if (@event.CMSType == ConfigurationManagementService.GitHub)
                {
                    var serviceConnectionModel = new
                    {
                        id            = Guid.NewGuid(),
                        name          = $"{@event.ProjectName}GitHub",
                        description   = "PipelineSpaceGitHub",
                        authorization = new
                        {
                            parameters = new
                            {
                                accessToken = @event.CMSAccessToken
                            },
                            scheme = "PersonalAccessToken",
                        },
                        type = "github",
                        url  = "https://api.github.com"
                    };

                    serviceEndpointUrl      = $"{accountUrl}/{accountProject}/_apis/serviceendpoint/endpoints?api-version={_vstsOptions.Value.ApiVersion}-preview";
                    serviceEndpointResponse = await _httpClientWrapperService.PostAsync(serviceEndpointUrl, serviceConnectionModel, authCredentials);
                    serviceEndpointResponse.EnsureSuccessStatusCode();

                    serviceEndpoint = await serviceEndpointResponse.MapTo <CMSVSTSServiceEndpointModel>();

                    //Patch External Git Endpoint Id
                    projectPatchUrl      = $"{_applicationOptions.Value.Url}/internalapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}";
                    projectPatchResponse = await _httpClientWrapperService.PatchAsync(projectPatchUrl, new { ProjectExternalGitEndpoint = serviceEndpoint.Id.ToString() }, InternalAuthCredentials);
                    projectPatchResponse.EnsureSuccessStatusCode();
                }

                if (@event.CMSType == ConfigurationManagementService.Bitbucket)
                {
                    // Create External Connection.
                    var serviceConnectionModel = new
                    {
                        id            = Guid.NewGuid(),
                        name          = $"{@event.ProjectName}BitBucket",
                        description   = "PipelineSpaceBitBucket",
                        authorization = new
                        {
                            parameters = new
                            {
                                username = @event.CMSAccessId,
                                password = @event.CMSAccessSecret
                            },
                            scheme = "UsernamePassword",
                        },
                        type = "bitbucket",
                        url  = "https://api.bitbucket.org"
                    };

                    serviceEndpointUrl      = $"{accountUrl}/{accountProject}/_apis/serviceendpoint/endpoints?api-version={_vstsOptions.Value.ApiVersion}-preview";
                    serviceEndpointResponse = await _httpClientWrapperService.PostAsync(serviceEndpointUrl, serviceConnectionModel, authCredentials);
                    serviceEndpointResponse.EnsureSuccessStatusCode();

                    serviceEndpoint = await serviceEndpointResponse.MapTo <CMSVSTSServiceEndpointModel>();

                    //Patch External Git Endpoint Id
                    projectPatchUrl      = $"{_applicationOptions.Value.Url}/internalapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}";
                    projectPatchResponse = await _httpClientWrapperService.PatchAsync(projectPatchUrl, new { ProjectExternalGitEndpoint = serviceEndpoint.Id.ToString() }, InternalAuthCredentials);
                    projectPatchResponse.EnsureSuccessStatusCode();
                }
            });

            //Activate Project External Id
            await ExecuteProjectActivity(@event.OrganizationId, @event.ProjectId, nameof(DomainConstants.Activities.PRACBA), async() =>
            {
                string projectActivateUrl   = $"{_applicationOptions.Value.Url}/internalapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}/activate";
                var projectActivateResponse = await _httpClientWrapperService.PatchAsync(projectActivateUrl, new { }, InternalAuthCredentials);
                projectActivateResponse.EnsureSuccessStatusCode();
            });

            //Import Services From Git
            if (@event.ProjectRepository != null && @event.ProjectRepository.Repositories != null && @event.ProjectRepository.Repositories.Count > 0)
            {
                await ExecuteProjectActivity(@event.OrganizationId, @event.ProjectId, nameof(DomainConstants.Activities.PRSTIR), async() =>
                {
                    foreach (var item in @event.ProjectRepository.Repositories)
                    {
                        string projecServicePostUrl   = $"{_applicationOptions.Value.Url}/internalapi/organizations/{@event.OrganizationId}/projects/{@event.ProjectId}/services/imports";
                        var projecServicePostResponse = await _httpClientWrapperService.PostAsync(projecServicePostUrl,
                                                                                                  new
                        {
                            ServiceExternalId   = item.Id,
                            ServiceExternalUrl  = item.Link,
                            ServiceExternalName = item.ExternalName,
                            Name                     = item.Name,
                            Description              = item.Name,
                            BranchName               = item.BranchName,
                            UserId                   = @event.UserId,
                            OrganizationCMSId        = @event.OrganizationCMSId,
                            BuildDefinitionYML       = @event.BuildDefinitionYML,
                            ProjectServiceTemplateId = @event.ProjectServiceTemplateId,
                            ProjectExternalId        = @event.ProjectExternalId,
                            ProjectExternalName      = @event.ProjectExternalName
                        }, InternalAuthCredentials);
                        projecServicePostResponse.EnsureSuccessStatusCode();
                    }
                });
            }
        }