2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.model.operations.impl;
23 import org.janusgraph.core.JanusGraphVertex;
24 import fj.data.Either;
25 import org.apache.commons.lang3.BooleanUtils;
26 import org.apache.tinkerpop.gremlin.structure.Direction;
27 import org.apache.tinkerpop.gremlin.structure.Edge;
28 import org.apache.tinkerpop.gremlin.structure.Vertex;
29 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
30 import org.openecomp.sdc.be.dao.api.ActionStatus;
31 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
32 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
33 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
34 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao;
35 import org.openecomp.sdc.be.dao.utils.UserStatusEnum;
36 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
37 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
38 import org.openecomp.sdc.be.model.Component;
39 import org.openecomp.sdc.be.model.User;
40 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
41 import org.openecomp.sdc.be.model.operations.StorageException;
42 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
43 import org.openecomp.sdc.be.resources.data.UserData;
44 import org.openecomp.sdc.common.datastructure.Wrapper;
45 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
46 import org.openecomp.sdc.common.log.wrappers.Logger;
47 import org.openecomp.sdc.common.util.MethodActivationStatusEnum;
49 import javax.validation.constraints.NotNull;
50 import java.util.ArrayList;
51 import java.util.Collections;
52 import java.util.HashMap;
53 import java.util.List;
56 import static org.apache.commons.collections.CollectionUtils.isEmpty;
58 @org.springframework.stereotype.Component
59 public class UserAdminOperation {
61 private final JanusGraphGenericDao janusGraphGenericDao;
62 private final ToscaOperationFacade toscaOperationFacade;
64 public UserAdminOperation(JanusGraphGenericDao janusGraphGenericDao, ToscaOperationFacade toscaOperationFacade) {
65 this.janusGraphGenericDao = janusGraphGenericDao;
66 this.toscaOperationFacade = toscaOperationFacade;
69 private static final Logger log = Logger.getLogger(UserAdminOperation.class.getName());
71 public Either<User, ActionStatus> getUserData(String id, boolean inTransaction) {
72 return getUserData(id, true, inTransaction);
75 private Either<User, ActionStatus> getUserData(String id, boolean isActive, boolean inTransaction) {
76 log.debug("getUserData - start");
77 Wrapper<Either<User, ActionStatus>> resultWrapper = new Wrapper<>();
78 Wrapper<UserData> userWrapper = new Wrapper<>();
80 validateUserExists(resultWrapper, userWrapper, id);
82 if (resultWrapper.isEmpty()) {
83 validateUserData(resultWrapper, userWrapper.getInnerElement(), id);
86 if (resultWrapper.isEmpty()) {
88 validateActiveUser(resultWrapper, userWrapper.getInnerElement());
90 validateInActiveUser(resultWrapper, userWrapper.getInnerElement());
94 if (resultWrapper.isEmpty()) {
95 resultWrapper.setInnerElement(Either.left(convertToUser(userWrapper.getInnerElement())));
98 return resultWrapper.getInnerElement();
100 if (!inTransaction) {
101 janusGraphGenericDao.commit();
103 log.debug("getUserData - end");
107 private void validateInActiveUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
108 User user = convertToUser(userData);
109 if (user.getStatus() == UserStatusEnum.ACTIVE) {
110 resultWrapper.setInnerElement(Either.right(ActionStatus.USER_NOT_FOUND));
114 private void validateActiveUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
115 User user = convertToUser(userData);
116 if (user.getStatus() == UserStatusEnum.INACTIVE) {
117 resultWrapper.setInnerElement(Either.right(ActionStatus.USER_INACTIVE));
121 private void validateUserData(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData, String id) {
122 if (userData == null) {
123 log.debug("Problem get User with userId {}. Reason - either.left().value() = null", id);
124 resultWrapper.setInnerElement(Either.right(ActionStatus.GENERAL_ERROR));
128 private void validateUserExists(Wrapper<Either<User, ActionStatus>> resultWrapper, Wrapper<UserData> userWrapper, String id) {
130 log.info("User userId is empty");
131 resultWrapper.setInnerElement(Either.right(ActionStatus.MISSING_USER_ID));
134 id = id.toLowerCase();
135 Either<UserData, JanusGraphOperationStatus> either = janusGraphGenericDao
136 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), id, UserData.class);
138 if (either.isRight()) {
139 resultWrapper.setInnerElement(getUserNotFoundError(id, either.right().value()));
141 userWrapper.setInnerElement(either.left().value());
145 public User saveUserData(User user) {
146 Either<UserData, JanusGraphOperationStatus> result = null;
148 UserData userData = convertToUserData(user);
149 result = janusGraphGenericDao.createNode(userData, UserData.class);
150 if (result.isRight()) {
151 log.error("Problem while saving User {}. Reason - {}", userData.getUserId(), result.right().value());
152 throw new StorageException(StorageOperationStatus.GENERAL_ERROR);
154 log.debug("User {} saved successfully", userData.getUserId());
155 return convertToUser(result.left().value());
158 if (result == null || result.isRight()) {
159 log.error("saveUserData - Failed");
160 janusGraphGenericDao.rollback();
162 log.debug("saveUserData - end");
163 janusGraphGenericDao.commit();
168 public User updateUserData(User user) {
169 Either<UserData, JanusGraphOperationStatus> result = null;
171 log.debug("updateUserData - start");
172 UserData userData = convertToUserData(user);
173 result = janusGraphGenericDao.updateNode(userData, UserData.class);
174 if (result.isRight()) {
175 log.error("Problem while updating User {}. Reason - {}", userData.toString(), result.right().value());
176 throw new StorageException(StorageOperationStatus.GENERAL_ERROR);
178 log.debug("User {} updated successfully",userData.getUserId());
179 return convertToUser(result.left().value());
182 if (result == null || result.isRight()) {
183 log.error("updateUserData - Failed");
184 janusGraphGenericDao.rollback();
186 log.debug("updateUserData - end");
187 janusGraphGenericDao.commit();
193 public User deActivateUser(User user) {
194 user.setStatus(UserStatusEnum.INACTIVE);
195 return updateUserData(user);
198 public Either<User, ActionStatus> deleteUserData(String id) {
199 Either<User, ActionStatus> result;
200 Either<UserData, JanusGraphOperationStatus> eitherGet = janusGraphGenericDao
201 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), id, UserData.class);
202 if (eitherGet.isRight()) {
203 log.debug("Problem while retriving user with userId {}",id);
204 if (eitherGet.right().value() == JanusGraphOperationStatus.NOT_FOUND) {
205 result = Either.right(ActionStatus.USER_NOT_FOUND);
207 result = Either.right(ActionStatus.GENERAL_ERROR);
210 result = deleteUserLogic(eitherGet.left().value());
215 private Either<User, ActionStatus> deleteUserLogic(UserData userData) {
216 Wrapper<Either<User, ActionStatus>> resultWrapper = new Wrapper<>();
218 validateUserHasNoConnections(resultWrapper, userData);
219 if (resultWrapper.isEmpty()) {
220 deleteUser(resultWrapper, userData);
223 janusGraphGenericDao.commit();
225 return resultWrapper.getInnerElement();
228 private void deleteUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
229 Either<UserData, JanusGraphOperationStatus> eitherDelete = janusGraphGenericDao
230 .deleteNode(userData, UserData.class);
231 if (eitherDelete.isRight()) {
232 if (log.isDebugEnabled()) {
233 log.debug("Problem while deleting User {}. Reason - {}", userData.toString(), eitherDelete.right().value());
235 resultWrapper.setInnerElement(Either.right(ActionStatus.GENERAL_ERROR));
237 log.debug("User {} deleted successfully",userData.getUserId());
238 resultWrapper.setInnerElement(Either.left(convertToUser(eitherDelete.left().value())));
242 private void validateUserHasNoConnections(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
243 if (resultWrapper.isEmpty()) {
245 Either<List<Edge>, JanusGraphOperationStatus> edgesForNode = janusGraphGenericDao
246 .getEdgesForNode(userData, Direction.BOTH);
247 if (edgesForNode.isRight()) {
248 if (log.isDebugEnabled()) {
249 log.debug("Problem while deleting User {}. Reason - {}", userData.getUserId(), edgesForNode.right().value());
251 resultWrapper.setInnerElement(Either.right(ActionStatus.GENERAL_ERROR));
253 List<Edge> vertexEdges = edgesForNode.left().value();
254 if (!isEmpty(vertexEdges)) {
255 resultWrapper.setInnerElement(Either.right(ActionStatus.USER_HAS_ACTIVE_ELEMENTS));
261 public @NotNull List<Edge> getUserPendingTasksList(User user, List<Object> states) {
263 JanusGraphVertex userVertex = janusGraphGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), user.getUserId())
265 .on(this::handleJanusGraphError);
267 List<Edge> pendingTasks = new ArrayList<>();
268 for (Object state : states) {
269 Map<String, Object> property = new HashMap<>();
270 property.put(GraphPropertiesDictionary.STATE.getProperty(), state);
271 List<Edge> edges = janusGraphGenericDao.getOutgoingEdgesByCriteria(userVertex, GraphEdgeLabels.STATE, property)
273 .on(this::handleJanusGraphError);
274 for (Edge edge : edges) {
275 Vertex vertex = edge.inVertex();
276 if (!isComponentDeleted(vertex)) {
277 pendingTasks.add(edge);
281 logPendingTasks(user, pendingTasks);
285 public @NotNull List<Component> getUserActiveComponents(User user, List<Object> states) {
286 List<Component> components = new ArrayList<>();
287 List<Edge> edges = getUserPendingTasksList(user, states);
288 for (Edge edge : edges) {
289 JanusGraphVertex componentVertex = (JanusGraphVertex) edge.inVertex();
290 String componentId = (String) janusGraphGenericDao.getProperty(componentVertex, GraphPropertyEnum.UNIQUE_ID.getProperty());
291 Either<Component, StorageOperationStatus> toscaFullElement = toscaOperationFacade.getToscaFullElement(componentId);
292 if (toscaFullElement.isLeft()) {
293 components.add(toscaFullElement.left().value());
295 log.warn(EcompLoggerErrorCode.SCHEMA_ERROR, "", "", "Failed to retrieve component {} from graph db", componentId);
301 private <T> T handleJanusGraphError(JanusGraphOperationStatus janusGraphOperationStatus) {
302 throw new StorageException(janusGraphOperationStatus);
305 private boolean isComponentDeleted(Vertex componentVertex) {
306 VertexProperty<Object> property = componentVertex.property(GraphPropertiesDictionary.IS_DELETED.getProperty());
307 if (property.isPresent()) {
308 return BooleanUtils.isTrue((Boolean) property.value());
313 private void logPendingTasks(User user, List<Edge> pendingTasks) {
314 if (log.isDebugEnabled()) {
315 for (Edge edge : pendingTasks) {
316 Object resourceUuid = edge.inVertex().property(GraphPropertyEnum.UNIQUE_ID.getProperty()).value();
317 Object componentName = edge.inVertex().property(GraphPropertyEnum.NAME.getProperty()).value();
318 Object componentState = edge.inVertex().property(GraphPropertyEnum.STATE.getProperty()).value();
319 log.debug("The user userId = {} is working on the component name = {} uid = {} in state {}", user.getUserId(), componentName, resourceUuid, componentState);
324 public Either<List<User>, ActionStatus> getAllUsersWithRole(String role, String status) {
326 Map<String, Object> propertiesToMatch = new HashMap<>();
327 if (role != null && !role.trim().isEmpty()) {
328 propertiesToMatch.put(GraphPropertiesDictionary.ROLE.getProperty(), role);
330 if (status != null && !status.isEmpty()) {
331 propertiesToMatch.put(GraphPropertiesDictionary.USER_STATUS.getProperty(), status);
334 Either<List<UserData>, JanusGraphOperationStatus> userNodes = janusGraphGenericDao
335 .getByCriteria(NodeTypeEnum.User, propertiesToMatch, UserData.class);
337 janusGraphGenericDao.commit();
338 return convertToUsers(role, userNodes);
340 janusGraphGenericDao.commit();
344 private Either<List<User>, ActionStatus> convertToUsers(String role, Either<List<UserData>, JanusGraphOperationStatus> userNodes) {
346 if (userNodes.isRight()) {
347 // in case of NOT_FOUND from JanusGraph return empty list
348 JanusGraphOperationStatus tos = userNodes.right().value();
349 if (tos.equals(JanusGraphOperationStatus.NOT_FOUND)) {
350 return Either.left(Collections.emptyList());
352 log.error("Problem while getting all users with role {}. Reason - {}", role, tos);
353 return Either.right(ActionStatus.GENERAL_ERROR);
356 List<UserData> userDataList = userNodes.left().value();
357 if (userDataList != null) {
358 return Either.left(convertToUsers(userDataList));
360 log.debug("No users were found with role {}", role);
361 return Either.left(Collections.emptyList());
365 private List<User> convertToUsers(List<UserData> usersData) {
366 List<User> result = new ArrayList<>();
367 for (UserData userData : usersData) {
368 User user = convertToUser(userData);
374 private Either<User, ActionStatus> getUserNotFoundError(String uid, JanusGraphOperationStatus status) {
375 if (status == JanusGraphOperationStatus.NOT_FOUND) {
376 log.debug("User with userId {} not found", uid);
377 return Either.right(ActionStatus.USER_NOT_FOUND);
379 log.debug("Problem get User with userId {}. Reason - {}", uid, status);
380 return Either.right(ActionStatus.GENERAL_ERROR);
384 protected User convertToUser(UserData userData) {
385 User user = new User();
386 user.setUserId(userData.getUserId());
387 user.setEmail(userData.getEmail());
388 user.setFirstName(userData.getFirstName());
389 user.setLastName(userData.getLastName());
390 user.setRole(userData.getRole());
391 user.setLastLoginTime(userData.getLastLoginTime());
392 // Support backward compatibility - user status may not exist in old
394 Either<UserStatusEnum, MethodActivationStatusEnum> either = UserStatusEnum.findByName(userData.getStatus());
395 user.setStatus(either.isLeft() ? either.left().value() : UserStatusEnum.ACTIVE);
399 protected UserData convertToUserData(User user) {
400 UserData userData = new UserData();
401 userData.setUserId(user.getUserId().toLowerCase());
402 userData.setEmail(user.getEmail());
403 userData.setFirstName(user.getFirstName());
404 userData.setLastName(user.getLastName());
405 userData.setRole(user.getRole());
406 userData.setStatus(user.getStatus().name());
407 userData.setLastLoginTime(user.getLastLoginTime());