public async Task CreateProjectFeature(Guid organizationId, Guid projectId, ProjectFeaturePostRp resource) { string loggedUserId = _identityService.GetUserId(); DomainModels.User user = await _userRepository.GetUser(loggedUserId); DomainModels.Organization organization = user.FindOrganizationById(organizationId); if (organization == null) { await _domainManagerService.AddNotFound($"The organzation with id {organizationId} does not exists."); return; } DomainModels.Project project = user.FindProjectById(projectId); if (project == null) { await _domainManagerService.AddNotFound($"The project with id {projectId} does not exists."); return; } DomainModels.PipelineRole role = user.GetRoleInProject(projectId); if (role != DomainModels.PipelineRole.ProjectAdmin) { await _domainManagerService.AddForbidden($"You are not authorized to create features in this project."); return; } if (project.Status != DomainModels.EntityStatus.Active) { await _domainManagerService.AddConflict($"The project with id {projectId} must be in status Active to add a new feature."); return; } if (resource.Services.Length == 0) { await _domainManagerService.AddConflict($"At least one pipe must be included in the feature."); return; } var preparingServices = project.GetPreparingServices(); if (preparingServices.Any()) { await _domainManagerService.AddConflict($"The project with id {projectId} has pipes in status Preparing. All services must be in status Active to create a new feature"); return; } DomainModels.ProjectFeature existingFeature = project.GetFeatureByName(resource.Name); if (existingFeature != null) { await _domainManagerService.AddConflict($"The feature name {resource.Name} has already been taken."); return; } DomainModels.ProjectFeature newFeature = user.CreateProjectFeature(organizationId, projectId, resource.Name, resource.Description); //services asociated (TODO: services on demand) List <ProjectFeatureServiceCreatedEvent> @events = new List <ProjectFeatureServiceCreatedEvent>(); foreach (var item in resource.Services) { DomainModels.ProjectService projectService = project.GetServiceById(item); if (projectService == null) { await _domainManagerService.AddConflict($"The pipe id {item} does not exists."); return; } var variables = projectService.Environments.First(x => x.ProjectEnvironment.Type == EnvironmentType.Root).Variables; newFeature.AddService(item, variables); var serviceCredential = this._cloudCredentialService.ProjectServiceCredentialResolver(project, projectService); @events.Add(new ProjectFeatureServiceCreatedEvent(_correlationId) { ServiceId = item, ServiceExternalId = projectService.ProjectServiceExternalId, ServiceExternalUrl = projectService.ProjectServiceExternalUrl, ServiceName = projectService.Name, InternalServiceName = projectService.InternalName, ServiceTemplateUrl = serviceCredential.BranchUrl, ReleaseStageId = projectService.ReleaseStageId, AgentPoolId = project.AgentPoolId, OrganizationId = organization.OrganizationId, ProjectId = project.ProjectId, FeatureId = newFeature.ProjectFeatureId, ProjectExternalId = serviceCredential.ProjectExternalId, ProjectExternalEndpointId = project.ProjectExternalEndpointId, ProjectExternalGitEndpoint = project.ProjectExternalGitEndpoint, ProjectVSTSFakeName = project.ProjectVSTSFakeName, ProjectVSTSFakeId = project.ProjectVSTSFakeId, OrganizationName = organization.Name, ProjectName = serviceCredential.ProjectName, FeatureName = newFeature.Name, CMSType = serviceCredential.CMSType, CMSAccountId = serviceCredential.AccountId, CMSAccountName = serviceCredential.AccountName, CMSAccessId = serviceCredential.AccessId, CMSAccessSecret = serviceCredential.AccessSecret, CMSAccessToken = serviceCredential.AccessToken, CPSType = project.OrganizationCPS.Type, CPSAccessId = _dataProtectorService.Unprotect(project.OrganizationCPS.AccessId), CPSAccessName = _dataProtectorService.Unprotect(project.OrganizationCPS.AccessName), CPSAccessSecret = _dataProtectorService.Unprotect(project.OrganizationCPS.AccessSecret), CPSAccessRegion = _dataProtectorService.Unprotect(project.OrganizationCPS.AccessRegion), TemplateAccess = projectService.ProjectServiceTemplate.TemplateAccess, IsImported = projectService.IsImported, NeedCredentials = projectService.ProjectServiceTemplate.NeedCredentials, RepositoryCMSType = serviceCredential.CMSType, RepositoryAccessId = serviceCredential.AccessId, RepositoryAccessSecret = serviceCredential.AccessSecret, RepositoryAccessToken = serviceCredential.AccessToken, UserId = loggedUserId }); } _userRepository.Update(user); await _userRepository.SaveChanges(); await _domainManagerService.AddResult("FeatureId", newFeature.ProjectFeatureId); //send events foreach (var @event in @events) { await _eventBusService.Publish(queueName : "ProjectFeatureServiceCreatedEvent", @event : @event); } }