You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dlab.apache.org by of...@apache.org on 2020/01/17 14:53:28 UTC

[incubator-dlab] branch multiple-cloud updated: Updated role functionality and some configs in selfservice

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 <ol...@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-unsubscribe@dlab.apache.org
For additional commands, e-mail: commits-help@dlab.apache.org