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.User;
39 import org.openecomp.sdc.be.model.operations.api.IUserAdminOperation;
40 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
41 import org.openecomp.sdc.be.resources.data.UserData;
42 import org.openecomp.sdc.common.datastructure.Wrapper;
43 import org.openecomp.sdc.common.log.wrappers.Logger;
44 import org.openecomp.sdc.common.util.MethodActivationStatusEnum;
45 import org.springframework.beans.factory.annotation.Qualifier;
46 import org.springframework.stereotype.Component;
50 import static org.apache.commons.collections.CollectionUtils.isEmpty;
52 @Component("user-operation")
53 public class UserAdminOperation implements IUserAdminOperation {
55 private JanusGraphGenericDao janusGraphGenericDao;
57 public UserAdminOperation(@Qualifier("janusgraph-generic-dao")
58 JanusGraphGenericDao janusGraphGenericDao) {
60 this.janusGraphGenericDao = janusGraphGenericDao;
64 private static final Logger log = Logger.getLogger(UserAdminOperation.class.getName());
67 public Either<User, ActionStatus> getUserData(String id, boolean inTransaction) {
68 return getUserData(id, true, inTransaction);
71 private Either<User, ActionStatus> getUserData(String id, boolean isActive, boolean inTransaction) {
72 log.debug("getUserData - start");
73 Wrapper<Either<User, ActionStatus>> resultWrapper = new Wrapper<>();
74 Wrapper<UserData> userWrapper = new Wrapper<>();
76 validateUserExists(resultWrapper, userWrapper, id);
78 if (resultWrapper.isEmpty()) {
79 validateUserData(resultWrapper, userWrapper.getInnerElement(), id);
82 if (resultWrapper.isEmpty()) {
84 validateActiveUser(resultWrapper, userWrapper.getInnerElement());
86 validateInActiveUser(resultWrapper, userWrapper.getInnerElement());
90 if (resultWrapper.isEmpty()) {
91 resultWrapper.setInnerElement(Either.left(convertToUser(userWrapper.getInnerElement())));
94 return resultWrapper.getInnerElement();
97 janusGraphGenericDao.commit();
99 log.debug("getUserData - end");
103 private void validateInActiveUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
104 User user = convertToUser(userData);
105 if (user.getStatus() == UserStatusEnum.ACTIVE) {
106 resultWrapper.setInnerElement(Either.right(ActionStatus.USER_NOT_FOUND));
110 private void validateActiveUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
111 User user = convertToUser(userData);
112 if (user.getStatus() == UserStatusEnum.INACTIVE) {
113 resultWrapper.setInnerElement(Either.right(ActionStatus.USER_INACTIVE));
117 private void validateUserData(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData, String id) {
118 if (userData == null) {
119 log.debug("Problem get User with userId {}. Reason - either.left().value() = null", id);
120 resultWrapper.setInnerElement(Either.right(ActionStatus.GENERAL_ERROR));
124 private void validateUserExists(Wrapper<Either<User, ActionStatus>> resultWrapper, Wrapper<UserData> userWrapper, String id) {
126 log.info("User userId is empty");
127 resultWrapper.setInnerElement(Either.right(ActionStatus.MISSING_INFORMATION));
130 id = id.toLowerCase();
131 Either<UserData, JanusGraphOperationStatus> either = janusGraphGenericDao
132 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), id, UserData.class);
134 if (either.isRight()) {
135 resultWrapper.setInnerElement(getUserNotFoundError(id, either.right().value()));
137 userWrapper.setInnerElement(either.left().value());
142 public Either<User, StorageOperationStatus> saveUserData(User user) {
143 Either<UserData, JanusGraphOperationStatus> result = null;
145 UserData userData = convertToUserData(user);
146 result = janusGraphGenericDao.createNode(userData, UserData.class);
147 if (result.isRight()) {
148 log.debug("Problem while saving User {}. Reason - {}", userData.getUserId(), result.right().value());
149 return Either.right(StorageOperationStatus.GENERAL_ERROR);
151 log.debug("User {} saved successfully", userData.getUserId());
152 return Either.left(convertToUser(result.left().value()));
156 if (result == null || result.isRight()) {
157 log.error("saveUserData - Failed");
158 janusGraphGenericDao.rollback();
160 log.debug("saveUserData - end");
161 janusGraphGenericDao.commit();
167 public Either<User, StorageOperationStatus> updateUserData(User user) {
168 Either<UserData, JanusGraphOperationStatus> result = null;
170 log.debug("updateUserData - start");
171 UserData userData = convertToUserData(user);
172 result = janusGraphGenericDao.updateNode(userData, UserData.class);
173 if (result.isRight()) {
174 if (log.isDebugEnabled()) {
175 log.debug("Problem while updating User {}. Reason - {}", userData.toString(), result.right().value());
177 return Either.right(StorageOperationStatus.GENERAL_ERROR);
179 log.debug("User {} updated successfully",userData.getUserId());
180 return Either.left(convertToUser(result.left().value()));
184 if (result == null || result.isRight()) {
185 log.error("updateUserData - Failed");
186 janusGraphGenericDao.rollback();
188 log.debug("updateUserData - end");
189 janusGraphGenericDao.commit();
196 public Either<User, StorageOperationStatus> deActivateUser(User user) {
197 Either<User, StorageOperationStatus> result;
198 user.setStatus(UserStatusEnum.INACTIVE);
199 Either<User, StorageOperationStatus> status = updateUserData(user);
200 if (status.isRight()) {
201 result = Either.right(status.right().value());
203 result = Either.left(user);
209 public Either<User, ActionStatus> deleteUserData(String id) {
210 Either<User, ActionStatus> result;
211 Either<UserData, JanusGraphOperationStatus> eitherGet = janusGraphGenericDao
212 .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), id, UserData.class);
213 if (eitherGet.isRight()) {
214 log.debug("Problem while retriving user with userId {}",id);
215 if (eitherGet.right().value() == JanusGraphOperationStatus.NOT_FOUND) {
216 result = Either.right(ActionStatus.USER_NOT_FOUND);
218 result = Either.right(ActionStatus.GENERAL_ERROR);
221 result = deleteUserLogic(eitherGet.left().value());
226 private Either<User, ActionStatus> deleteUserLogic(UserData userData) {
227 Wrapper<Either<User, ActionStatus>> resultWrapper = new Wrapper<>();
229 validateUserHasNoConnections(resultWrapper, userData);
230 if (resultWrapper.isEmpty()) {
231 deleteUser(resultWrapper, userData);
234 janusGraphGenericDao.commit();
236 return resultWrapper.getInnerElement();
239 private void deleteUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
240 Either<UserData, JanusGraphOperationStatus> eitherDelete = janusGraphGenericDao
241 .deleteNode(userData, UserData.class);
242 if (eitherDelete.isRight()) {
243 if (log.isDebugEnabled()) {
244 log.debug("Problem while deleting User {}. Reason - {}", userData.toString(), eitherDelete.right().value());
246 resultWrapper.setInnerElement(Either.right(ActionStatus.GENERAL_ERROR));
248 log.debug("User {} deleted successfully",userData.getUserId());
249 resultWrapper.setInnerElement(Either.left(convertToUser(eitherDelete.left().value())));
253 private void validateUserHasNoConnections(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) {
254 if (resultWrapper.isEmpty()) {
256 Either<List<Edge>, JanusGraphOperationStatus> edgesForNode = janusGraphGenericDao
257 .getEdgesForNode(userData, Direction.BOTH);
258 if (edgesForNode.isRight()) {
259 if (log.isDebugEnabled()) {
260 log.debug("Problem while deleting User {}. Reason - {}", userData.getUserId(), edgesForNode.right().value());
262 resultWrapper.setInnerElement(Either.right(ActionStatus.GENERAL_ERROR));
264 List<Edge> vertexEdges = edgesForNode.left().value();
265 if (!isEmpty(vertexEdges)) {
266 resultWrapper.setInnerElement(Either.right(ActionStatus.USER_HAS_ACTIVE_ELEMENTS));
272 public Either<List<Edge>, StorageOperationStatus> getUserPendingTasksList(User user, Map<String, Object> properties) {
274 Either<JanusGraphVertex, JanusGraphOperationStatus> vertexUser = janusGraphGenericDao
275 .getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), user.getUserId());
276 if (vertexUser.isRight()) {
277 JanusGraphOperationStatus tos = vertexUser.right().value();
278 log.debug("Failed to get User {} from graph while retrieving pending tasks. Reason - {}", user.getUserId(), tos);
279 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(tos));
281 List<Edge> pendingTasks = new ArrayList<>();
282 Either<List<Edge>, JanusGraphOperationStatus> edges = janusGraphGenericDao
283 .getOutgoingEdgesByCriteria(vertexUser.left().value(), GraphEdgeLabels.STATE, properties);
284 if (edges.isRight() || edges.left().value() == null) {
285 JanusGraphOperationStatus tos = edges.right().value();
286 if (tos == JanusGraphOperationStatus.NOT_FOUND) {
287 return Either.left(pendingTasks);
289 log.debug("Failed while retrieving pending tasks for user {} . Reason - {}", user.getUserId(), tos);
290 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(tos));
293 for (Edge edge : edges.left().value()) {
294 if (!isComponentDeleted(edge.inVertex())) {
295 pendingTasks.add(edge);
298 logPendingTasks(user, pendingTasks);
299 return Either.left(pendingTasks);
302 private boolean isComponentDeleted(Vertex componentVertex) {
303 VertexProperty<Object> property = componentVertex.property(GraphPropertiesDictionary.IS_DELETED.getProperty());
304 if (property.isPresent()) {
305 return BooleanUtils.isTrue((Boolean) property.value());
310 private void logPendingTasks(User user, List<Edge> pendingTasks) {
311 if (log.isDebugEnabled()) {
312 for (Edge edge : pendingTasks) {
313 Object resourceUuid = edge.inVertex().property(GraphPropertyEnum.UNIQUE_ID.getProperty()).value();
314 Object componentName = edge.inVertex().property(GraphPropertyEnum.NAME.getProperty()).value();
315 Object componentState = edge.inVertex().property(GraphPropertyEnum.STATE.getProperty()).value();
316 log.debug("The user userId = {} is working on the component name = {} uid = {} in state {}", user.getUserId(), componentName, resourceUuid, componentState);
322 public Either<List<User>, ActionStatus> getAllUsersWithRole(String role, String status) {
324 Map<String, Object> propertiesToMatch = new HashMap<>();
325 if (role != null && !role.trim().isEmpty()) {
326 propertiesToMatch.put(GraphPropertiesDictionary.ROLE.getProperty(), role);
328 if (status != null && !status.isEmpty()) {
329 propertiesToMatch.put(GraphPropertiesDictionary.USER_STATUS.getProperty(), status);
332 Either<List<UserData>, JanusGraphOperationStatus> userNodes = janusGraphGenericDao
333 .getByCriteria(NodeTypeEnum.User, propertiesToMatch, UserData.class);
335 janusGraphGenericDao.commit();
336 return convertToUsers(role, userNodes);
338 janusGraphGenericDao.commit();
342 private Either<List<User>, ActionStatus> convertToUsers(String role, Either<List<UserData>, JanusGraphOperationStatus> userNodes) {
344 if (userNodes.isRight()) {
345 // in case of NOT_FOUND from JanusGraph return empty list
346 JanusGraphOperationStatus tos = userNodes.right().value();
347 if (tos.equals(JanusGraphOperationStatus.NOT_FOUND)) {
348 return Either.left(Collections.emptyList());
350 log.error("Problem while getting all users with role {}. Reason - {}", role, tos);
351 return Either.right(ActionStatus.GENERAL_ERROR);
354 List<UserData> userDataList = userNodes.left().value();
355 if (userDataList != null) {
356 return Either.left(convertToUsers(userDataList));
358 log.debug("No users were found with role {}", role);
359 return Either.left(Collections.emptyList());
363 private List<User> convertToUsers(List<UserData> usersData) {
364 List<User> result = new ArrayList<>();
365 for (UserData userData : usersData) {
366 User user = convertToUser(userData);
372 private Either<User, ActionStatus> getUserNotFoundError(String uid, JanusGraphOperationStatus status) {
373 if (status == JanusGraphOperationStatus.NOT_FOUND) {
374 log.debug("User with userId {} not found", uid);
375 return Either.right(ActionStatus.USER_NOT_FOUND);
377 log.debug("Problem get User with userId {}. Reason - {}", uid, status);
378 return Either.right(ActionStatus.GENERAL_ERROR);
382 protected User convertToUser(UserData userData) {
383 User user = new User();
384 user.setUserId(userData.getUserId());
385 user.setEmail(userData.getEmail());
386 user.setFirstName(userData.getFirstName());
387 user.setLastName(userData.getLastName());
388 user.setRole(userData.getRole());
389 user.setLastLoginTime(userData.getLastLoginTime());
390 // Support backward compatibility - user status may not exist in old
392 Either<UserStatusEnum, MethodActivationStatusEnum> either = UserStatusEnum.findByName(userData.getStatus());
393 user.setStatus(either.isLeft() ? either.left().value() : UserStatusEnum.ACTIVE);
397 protected UserData convertToUserData(User user) {
398 UserData userData = new UserData();
399 userData.setUserId(user.getUserId().toLowerCase());
400 userData.setEmail(user.getEmail());
401 userData.setFirstName(user.getFirstName());
402 userData.setLastName(user.getLastName());
403 userData.setRole(user.getRole());
404 userData.setStatus(user.getStatus().name());
405 userData.setLastLoginTime(user.getLastLoginTime());