public async Task CreateProjectFeatureService(Guid organizationId, Guid projectId, Guid featureId, ProjectFeatureServicePostRp resource)
        {
            string loggedUserId = _identityService.GetUserId();

            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 != EntityStatus.Active)
            {
                await _domainManagerService.AddConflict($"The project with id {projectId} must be in status Active to add a new feature service.");

                return;
            }

            DomainModels.ProjectFeature feature = project.GetFeatureById(featureId);
            if (feature == null)
            {
                await _domainManagerService.AddNotFound($"The project feature with id {featureId} does not exists.");

                return;
            }

            if (feature.Status != EntityStatus.Active)
            {
                await _domainManagerService.AddConflict($"The project feature with id {featureId} must be in status Active to add a new feature service.");

                return;
            }

            if (resource.Services.Length == 0)
            {
                await _domainManagerService.AddConflict($"At least one pipe must be included.");

                return;
            }

            List <ProjectFeatureServiceCreatedEvent> projectFeatureServiceCreatedEventList = new List <ProjectFeatureServiceCreatedEvent>();

            foreach (var item in resource.Services)
            {
                DomainModels.ProjectService projectService = project.GetServiceById(item);
                if (projectService == null)
                {
                    await _domainManagerService.AddConflict($"The pipe with id {item} does not exists.");

                    return;
                }

                if (projectService.Status != EntityStatus.Active)
                {
                    await _domainManagerService.AddConflict($"The pipe with id {item} must be in status Active to be added as a feature service.");

                    return;
                }

                DomainModels.ProjectFeatureService projectFeatureService = feature.GetFeatureServiceById(item);
                if (projectFeatureService != null)
                {
                    await _domainManagerService.AddConflict($"The pipe with id {item} already exists in the feature.");

                    return;
                }

                var variables = projectService.Environments.First(x => x.ProjectEnvironment.Type == EnvironmentType.Root).Variables;

                feature.AddService(item, variables);

                projectFeatureServiceCreatedEventList.Add(new ProjectFeatureServiceCreatedEvent(_correlationId)
                {
                    OrganizationId             = organization.OrganizationId,
                    ProjectId                  = project.ProjectId,
                    FeatureId                  = feature.ProjectFeatureId,
                    ProjectExternalId          = project.ProjectExternalId,
                    ProjectExternalEndpointId  = project.ProjectExternalEndpointId,
                    ProjectExternalGitEndpoint = project.ProjectExternalGitEndpoint,
                    ProjectVSTSFakeName        = project.ProjectVSTSFakeName,
                    ProjectVSTSFakeId          = project.ProjectVSTSFakeId,
                    OrganizationName           = organization.Name,
                    ProjectName                = project.Name,
                    FeatureName                = feature.Name,
                    CMSType             = project.OrganizationCMS.Type,
                    CMSAccountId        = _dataProtectorService.Unprotect(project.OrganizationCMS.AccountId),
                    CMSAccountName      = _dataProtectorService.Unprotect(project.OrganizationCMS.AccountName),
                    CMSAccessId         = _dataProtectorService.Unprotect(project.OrganizationCMS.AccessId),
                    CMSAccessSecret     = _dataProtectorService.Unprotect(project.OrganizationCMS.AccessSecret),
                    CMSAccessToken      = _dataProtectorService.Unprotect(project.OrganizationCMS.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),
                    ServiceId           = item,
                    ServiceExternalId   = projectService.ProjectServiceExternalId,
                    ServiceExternalUrl  = projectService.ProjectServiceExternalUrl,
                    ServiceName         = projectService.Name,
                    InternalServiceName = projectService.InternalName,
                    ServiceTemplateUrl  = projectService.ProjectServiceTemplate.Url,
                    ReleaseStageId      = projectService.ReleaseStageId,
                    AgentPoolId         = project.AgentPoolId,
                    UserId = loggedUserId
                });
            }

            _userRepository.Update(user);

            await _userRepository.SaveChanges();

            //send events
            foreach (var @event in projectFeatureServiceCreatedEventList)
            {
                await _eventBusService.Publish(queueName : "ProjectFeatureServiceCreatedEvent", @event : @event);
            }
        }
        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);
            }
        }