This is an automated email from the ASF dual-hosted git repository. ofuks pushed a commit to branch multiple-cloud in repository https://gitbox.apache.org/repos/asf/incubator-dlab.git
The following commit(s) were added to refs/heads/multiple-cloud by this push: new 18bf3f5 Updated role functionality and some configs in selfservice 18bf3f5 is described below commit 18bf3f544a65829cd613909b3010d3f89b96b9b4 Author: Oleh Fuks <olegfuk...@gmail.com> AuthorDate: Fri Jan 17 16:53:10 2020 +0200 Updated role functionality and some configs in selfservice --- .../conf/SelfServiceApplicationConfiguration.java | 20 +++----- .../com/epam/dlab/backendapi/dao/UserRoleDao.java | 7 ++- .../epam/dlab/backendapi/dao/UserRoleDaoImpl.java | 59 +++++++++++++++++++--- .../dropwizard/listeners/MongoStartupListener.java | 21 +++++++- .../service/impl/EndpointServiceImpl.java | 24 +++++++-- ...fServiceCloudConfigurationSequenceProvider.java | 28 ---------- 6 files changed, 101 insertions(+), 58 deletions(-) diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/SelfServiceApplicationConfiguration.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/SelfServiceApplicationConfiguration.java index 4c2f7bf..aaface6 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/SelfServiceApplicationConfiguration.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/SelfServiceApplicationConfiguration.java @@ -21,17 +21,12 @@ package com.epam.dlab.backendapi.conf; import com.epam.dlab.ServiceConfiguration; import com.epam.dlab.backendapi.domain.SchedulerConfigurationData; -import com.epam.dlab.backendapi.validation.SelfServiceCloudConfigurationSequenceProvider; import com.epam.dlab.constants.ServiceConsts; import com.epam.dlab.rest.client.RESTServiceFactory; -import com.epam.dlab.validation.AwsValidation; -import com.epam.dlab.validation.AzureValidation; -import com.epam.dlab.validation.GcpValidation; import com.fasterxml.jackson.annotation.JsonProperty; import io.dropwizard.client.JerseyClientConfiguration; import io.dropwizard.util.Duration; import org.hibernate.validator.constraints.NotEmpty; -import org.hibernate.validator.group.GroupSequenceProvider; import javax.validation.Valid; import javax.validation.constraints.Max; @@ -42,30 +37,29 @@ import java.util.Map; /** * Configuration for Self Service. */ -@GroupSequenceProvider(SelfServiceCloudConfigurationSequenceProvider.class) public class SelfServiceApplicationConfiguration extends ServiceConfiguration { - @Min(value = 2, groups = AwsValidation.class) + @Min(value = 2) @JsonProperty private int minEmrInstanceCount; - @Max(value = 1000, groups = AwsValidation.class) + @Max(value = 1000) @JsonProperty private int maxEmrInstanceCount; - @Min(value = 10, groups = AwsValidation.class) + @Min(value = 10) @JsonProperty private int minEmrSpotInstanceBidPct; - @Max(value = 95, groups = AwsValidation.class) + @Max(value = 95) @JsonProperty private int maxEmrSpotInstanceBidPct; - @Min(value = 2, groups = {AzureValidation.class, AwsValidation.class, GcpValidation.class}) + @Min(value = 2) @JsonProperty private int minSparkInstanceCount; - @Max(value = 1000, groups = {AzureValidation.class, AwsValidation.class, GcpValidation.class}) + @Max(value = 1000) @JsonProperty private int maxSparkInstanceCount; @@ -84,7 +78,7 @@ public class SelfServiceApplicationConfiguration extends ServiceConfiguration { @JsonProperty private boolean billingSchedulerEnabled = false; - @NotEmpty(groups = AwsValidation.class) + @NotEmpty @JsonProperty private String billingConfFile; @JsonProperty diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDao.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDao.java index 33d00d9..c2a401b 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDao.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDao.java @@ -21,6 +21,7 @@ package com.epam.dlab.backendapi.dao; import com.epam.dlab.backendapi.resources.dto.UserGroupDto; import com.epam.dlab.backendapi.resources.dto.UserRoleDto; +import com.epam.dlab.cloud.CloudProvider; import java.util.List; import java.util.Set; @@ -28,20 +29,22 @@ import java.util.Set; public interface UserRoleDao { List<UserRoleDto> findAll(); - void removeAll(); - void insert(UserRoleDto dto); void insert(List<UserRoleDto> roles); boolean update(UserRoleDto dto); + void updateMissingRoles(CloudProvider cloudProvider); + boolean addGroupToRole(Set<String> groups, Set<String> roleIds); boolean removeGroupFromRole(Set<String> groups, Set<String> roleIds); void removeGroupWhenRoleNotIn(String group, Set<String> roleIds); + void removeUnnecessaryRoles(CloudProvider cloudProviderToBeRemoved, List<CloudProvider> remainingProviders); + void remove(String roleId); boolean removeGroup(String groupId); diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDaoImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDaoImpl.java index f271723..0767be4 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDaoImpl.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDaoImpl.java @@ -20,25 +20,38 @@ package com.epam.dlab.backendapi.dao; import com.epam.dlab.backendapi.resources.dto.UserGroupDto; import com.epam.dlab.backendapi.resources.dto.UserRoleDto; +import com.epam.dlab.cloud.CloudProvider; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.inject.Singleton; import com.mongodb.client.model.BsonField; import com.mongodb.client.result.UpdateResult; import org.bson.Document; import org.bson.conversions.Bson; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Set; import static com.epam.dlab.backendapi.dao.MongoCollections.USER_GROUPS; -import static com.mongodb.client.model.Aggregates.*; -import static com.mongodb.client.model.Filters.*; +import static com.mongodb.client.model.Aggregates.group; +import static com.mongodb.client.model.Aggregates.lookup; +import static com.mongodb.client.model.Aggregates.project; +import static com.mongodb.client.model.Aggregates.unwind; +import static com.mongodb.client.model.Filters.eq; +import static com.mongodb.client.model.Filters.in; +import static com.mongodb.client.model.Filters.not; +import static java.lang.String.format; import static java.util.stream.Collectors.toList; @Singleton public class UserRoleDaoImpl extends BaseDAO implements UserRoleDao { - + private static final ObjectMapper MAPPER = new ObjectMapper(); + private static final String ROLES_FILE_FORMAT = "/mongo/%s/mongo_roles.json"; private static final String USERS_FIELD = "users"; private static final String GROUPS_FIELD = "groups"; private static final String DESCRIPTION = "description"; @@ -58,11 +71,6 @@ public class UserRoleDaoImpl extends BaseDAO implements UserRoleDao { } @Override - public void removeAll() { - mongoService.getCollection(MongoCollections.ROLES).drop(); - } - - @Override public void insert(UserRoleDto dto) { insertOne(MongoCollections.ROLES, dto, dto.getId()); } @@ -81,6 +89,15 @@ public class UserRoleDaoImpl extends BaseDAO implements UserRoleDao { } @Override + public void updateMissingRoles(CloudProvider cloudProvider) { + getUserRoleFromFile(cloudProvider).stream() + .filter(u -> findAll().stream() + .map(UserRoleDto::getId) + .noneMatch(id -> id.equals(u.getId()))) + .forEach(this::insert); + } + + @Override public boolean addGroupToRole(Set<String> groups, Set<String> roleIds) { return conditionMatched(updateMany(MongoCollections.ROLES, in(ID, roleIds), addToSet(GROUPS_FIELD, groups))); @@ -97,6 +114,23 @@ public class UserRoleDaoImpl extends BaseDAO implements UserRoleDao { } @Override + public void removeUnnecessaryRoles(CloudProvider cloudProviderToBeRemoved, List<CloudProvider> remainingProviders) { + if (remainingProviders.contains(cloudProviderToBeRemoved)) { + return; + } + + List<UserRoleDto> remainingRoles = new ArrayList<>(); + remainingProviders.forEach(p -> remainingRoles.addAll(getUserRoleFromFile(p))); + + getUserRoleFromFile(cloudProviderToBeRemoved).stream() + .map(UserRoleDto::getId) + .filter(u -> remainingRoles.stream() + .map(UserRoleDto::getId) + .noneMatch(id -> id.equals(u))) + .forEach(this::remove); + } + + @Override public void remove(String roleId) { deleteOne(MongoCollections.ROLES, eq(ID, roleId)); } @@ -123,6 +157,15 @@ public class UserRoleDaoImpl extends BaseDAO implements UserRoleDao { .collect(toList()); } + private List<UserRoleDto> getUserRoleFromFile(CloudProvider cloudProvider) { + try (InputStream is = getClass().getResourceAsStream(format(ROLES_FILE_FORMAT, cloudProvider.getName()))) { + return MAPPER.readValue(is, new TypeReference<List<UserRoleDto>>() { + }); + } catch (IOException e) { + throw new IllegalStateException("Can not marshall dlab roles due to: " + e.getMessage()); + } + } + private Document roleDocument() { return new Document().append(ID, "$" + ID) .append(DESCRIPTION, "$" + DESCRIPTION) diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/MongoStartupListener.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/MongoStartupListener.java index eb9c553..d25e2dd 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/MongoStartupListener.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/MongoStartupListener.java @@ -1,6 +1,7 @@ package com.epam.dlab.backendapi.dropwizard.listeners; import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration; +import com.epam.dlab.backendapi.dao.EndpointDAO; import com.epam.dlab.backendapi.dao.SettingsDAO; import com.epam.dlab.backendapi.dao.UserRoleDao; import com.epam.dlab.backendapi.resources.dto.UserRoleDto; @@ -14,9 +15,16 @@ import org.eclipse.jetty.server.Server; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.TreeSet; import static java.lang.String.format; +import static java.util.Comparator.comparing; +import static java.util.stream.Collectors.collectingAndThen; +import static java.util.stream.Collectors.toCollection; @Slf4j @@ -27,13 +35,15 @@ public class MongoStartupListener implements ServerLifecycleListener { private final UserRoleDao userRoleDao; private final SelfServiceApplicationConfiguration configuration; private final SettingsDAO settingsDAO; + private final EndpointDAO endpointDAO; @Inject public MongoStartupListener(UserRoleDao userRoleDao, SelfServiceApplicationConfiguration configuration, - SettingsDAO settingsDAO) { + SettingsDAO settingsDAO, EndpointDAO endpointDAO) { this.userRoleDao = userRoleDao; this.configuration = configuration; this.settingsDAO = settingsDAO; + this.endpointDAO = endpointDAO; } @Override @@ -50,7 +60,14 @@ public class MongoStartupListener implements ServerLifecycleListener { } private List<UserRoleDto> getRoles() { - try (InputStream is = getClass().getResourceAsStream(format(ROLES_FILE_FORMAT, CloudProvider.AWS.getName()))) { + Set<UserRoleDto> userRoles = new HashSet<>(); + endpointDAO.getEndpoints().forEach(e -> userRoles.addAll(getUserRoleFromFile(e.getCloudProvider()))); + return userRoles.stream().collect(collectingAndThen(toCollection(() -> new TreeSet<>(comparing(UserRoleDto::getId))), + ArrayList::new)); + } + + private List<UserRoleDto> getUserRoleFromFile(CloudProvider cloudProvider) { + try (InputStream is = getClass().getResourceAsStream(format(ROLES_FILE_FORMAT, cloudProvider.getName()))) { return MAPPER.readValue(is, new TypeReference<List<UserRoleDto>>() { }); } catch (IOException e) { diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EndpointServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EndpointServiceImpl.java index 6c70927..247cbcb 100644 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EndpointServiceImpl.java +++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EndpointServiceImpl.java @@ -3,6 +3,7 @@ package com.epam.dlab.backendapi.service.impl; import com.epam.dlab.auth.UserInfo; import com.epam.dlab.backendapi.dao.EndpointDAO; import com.epam.dlab.backendapi.dao.ExploratoryDAO; +import com.epam.dlab.backendapi.dao.UserRoleDao; import com.epam.dlab.backendapi.domain.EndpointDTO; import com.epam.dlab.backendapi.domain.EndpointResourcesDTO; import com.epam.dlab.backendapi.domain.ProjectDTO; @@ -24,7 +25,8 @@ import javax.ws.rs.core.Response; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; @Slf4j public class EndpointServiceImpl implements EndpointService { @@ -34,15 +36,18 @@ public class EndpointServiceImpl implements EndpointService { private final ProjectService projectService; private final ExploratoryDAO exploratoryDAO; private final RESTService provisioningService; + private final UserRoleDao userRoleDao; @Inject public EndpointServiceImpl(EndpointDAO endpointDAO, ProjectService projectService, ExploratoryDAO exploratoryDAO, - @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService) { + @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService, + UserRoleDao userRoleDao) { this.endpointDAO = endpointDAO; this.projectService = projectService; this.exploratoryDAO = exploratoryDAO; this.provisioningService = provisioningService; + this.userRoleDao = userRoleDao; } @Override @@ -75,11 +80,13 @@ public class EndpointServiceImpl implements EndpointService { public void create(UserInfo userInfo, EndpointDTO endpointDTO) { if (!endpointDAO.get(endpointDTO.getName()).isPresent()) { CloudProvider cloudProvider = connectEndpoint(userInfo, endpointDTO.getUrl(), endpointDTO.getName()); - if (!Objects.nonNull(cloudProvider)) { - throw new DlabException("CloudProvider cannot be null"); - } + + Optional.ofNullable(cloudProvider) + .orElseThrow(() -> new DlabException("CloudProvider is not defined for endpoint")); + endpointDAO.create(new EndpointDTO(endpointDTO.getName(), endpointDTO.getUrl(), endpointDTO.getAccount(), endpointDTO.getTag(), EndpointDTO.EndpointStatus.ACTIVE, cloudProvider)); + userRoleDao.updateMissingRoles(cloudProvider); } else { throw new ResourceConflictException("Endpoint with passed name already exist in system"); } @@ -92,13 +99,20 @@ public class EndpointServiceImpl implements EndpointService { @Override public void remove(UserInfo userInfo, String name, boolean withResources) { + Optional<EndpointDTO> endpointDTO = endpointDAO.get(name); + endpointDTO.orElseThrow(() -> new ResourceNotFoundException(String.format("Endpoint %s does not exist", name))); List<ProjectDTO> projects = projectService.getProjectsByEndpoint(name); checkProjectEndpointResourcesStatuses(projects, name); if (withResources) { removeEndpointInAllProjects(userInfo, name, projects); } + CloudProvider cloudProvider = endpointDTO.get().getCloudProvider(); endpointDAO.remove(name); + List<CloudProvider> remainingProviders = endpointDAO.getEndpoints().stream() + .map(EndpointDTO::getCloudProvider) + .collect(Collectors.toList()); + userRoleDao.removeUnnecessaryRoles(cloudProvider, remainingProviders); } @Override diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/validation/SelfServiceCloudConfigurationSequenceProvider.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/validation/SelfServiceCloudConfigurationSequenceProvider.java deleted file mode 100644 index 1fd1748..0000000 --- a/services/self-service/src/main/java/com/epam/dlab/backendapi/validation/SelfServiceCloudConfigurationSequenceProvider.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package com.epam.dlab.backendapi.validation; - -import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration; -import com.epam.dlab.validation.CloudConfigurationSequenceProvider; - -public class SelfServiceCloudConfigurationSequenceProvider - extends CloudConfigurationSequenceProvider<SelfServiceApplicationConfiguration> { - -} --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@dlab.apache.org For additional commands, e-mail: commits-h...@dlab.apache.org