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.components.impl;
23 import com.thinkaurelius.titan.core.TitanGraph;
24 import fj.data.Either;
25 import java.util.EnumMap;
26 import java.util.LinkedList;
27 import org.apache.commons.lang3.tuple.ImmutablePair;
28 import org.apache.http.NameValuePair;
29 import org.apache.http.client.utils.URLEncodedUtils;
30 import org.openecomp.sdc.be.dao.api.ActionStatus;
31 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
32 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
33 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
34 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
35 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
36 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
37 import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum;
38 import org.openecomp.sdc.be.datamodel.utils.NodeTypeConvertUtils;
39 import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition;
40 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
41 import org.openecomp.sdc.be.datatypes.enums.*;
42 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
43 import org.openecomp.sdc.be.impl.ComponentsUtils;
44 import org.openecomp.sdc.be.model.*;
45 import org.openecomp.sdc.be.model.category.CategoryDefinition;
46 import org.openecomp.sdc.be.model.category.GroupingDefinition;
47 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
48 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
49 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
50 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
51 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
52 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
53 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
54 import org.openecomp.sdc.be.resources.data.ServiceMetadataData;
55 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
56 import org.openecomp.sdc.be.resources.data.category.CategoryData;
57 import org.openecomp.sdc.be.resources.data.category.SubCategoryData;
58 import org.openecomp.sdc.be.ui.model.UiCategories;
59 import org.openecomp.sdc.be.user.Role;
60 import org.openecomp.sdc.be.user.UserBusinessLogic;
61 import org.openecomp.sdc.common.datastructure.Wrapper;
62 import org.openecomp.sdc.common.util.ValidationUtils;
63 import org.openecomp.sdc.exception.ResponseFormat;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
67 import java.nio.charset.StandardCharsets;
69 import java.util.function.Predicate;
70 import java.util.stream.Collectors;
72 @org.springframework.stereotype.Component("elementsBusinessLogic")
73 public class ElementBusinessLogic extends BaseBusinessLogic {
75 private static Logger log = LoggerFactory.getLogger(ElementBusinessLogic.class.getName());
77 @javax.annotation.Resource
78 private IElementOperation elementOperation;
80 @javax.annotation.Resource
81 private ComponentsUtils componentsUtils;
83 @javax.annotation.Resource
84 private UserBusinessLogic userAdminManager;
91 public Either<Map<String, List<? extends Component>>, ResponseFormat> getFollowed(User user) {
92 // Used for not getting duplicated followed. Cheaper than checking ArrayList.contains
93 Either<Map<String, Set<? extends Component>>, ResponseFormat> response = null;
94 // Used for returning as the code requires.
95 Either<Map<String, List<? extends Component>>, ResponseFormat> arrayResponse = null;
98 String role = user.getRole();
100 Role currentRole = Role.valueOf(role);
102 switch (currentRole) {
104 userId = user.getUserId();
105 response = handleDesigner(userId);
109 userId = user.getUserId();
110 response = handleTester(userId);
114 userId = user.getUserId();
115 response = handleGovernor(userId);
119 userId = user.getUserId();
120 response = handleOps(userId);
123 case PRODUCT_STRATEGIST:
124 userId = user.getUserId();
125 response = handleProductStrategist(userId);
128 case PRODUCT_MANAGER:
129 userId = user.getUserId();
130 response = handleProductManager(userId);
134 response = handleAdmin();
138 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
141 //converting the Set to List so the rest of the code will handle it normally (Was changed because the same element with the same uuid was returned twice)
142 return convertedToListResponse(response);
146 private Either<Map<String,List<? extends Component>>,ResponseFormat> convertedToListResponse(Either<Map<String, Set<? extends Component>>, ResponseFormat> setResponse) {
148 Map<String, List<? extends Component>> arrayResponse = new HashMap<>();
149 if (setResponse.isLeft()) {
150 for (Map.Entry<String, Set<? extends Component>> entry : setResponse.left().value().entrySet()) {
151 arrayResponse.put(entry.getKey(), (new ArrayList(new HashSet(entry.getValue()))));
153 return Either.left(arrayResponse);
155 return Either.right(setResponse.right().value());
158 private Either<Map<String, Set<? extends Component>>, ResponseFormat> handleAdmin() {
159 Either<Map<String, Set<? extends Component>>, ResponseFormat> response;
160 // userId should stay null
161 Set<LifecycleStateEnum> lifecycleStates = new HashSet<LifecycleStateEnum>();
162 Set<LifecycleStateEnum> lastStateStates = new HashSet<LifecycleStateEnum>();
163 lifecycleStates.add(LifecycleStateEnum.CERTIFIED);
164 response = getFollowedResourcesAndServices(null, lifecycleStates, lastStateStates);
168 private Either<Map<String, Set<? extends Component>>, ResponseFormat> handleDesigner(String userId) {
169 Set<LifecycleStateEnum> lifecycleStates = new HashSet<LifecycleStateEnum>();
170 Set<LifecycleStateEnum> lastStateStates = new HashSet<LifecycleStateEnum>();
171 Either<Map<String, Set<? extends Component>>, ResponseFormat> response;
172 lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
173 lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
174 lifecycleStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION);
175 lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
176 lifecycleStates.add(LifecycleStateEnum.CERTIFIED);
178 lastStateStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION);
179 response = getFollowedResourcesAndServices(userId, lifecycleStates, lastStateStates);
183 private Either<Map<String, Set<? extends Component>>, ResponseFormat> handleGovernor(String userId) {
184 Either<Map<String, Set<? extends Component>>, ResponseFormat> result = handleFollowedCertifiedServices(null);
188 private Either<Map<String, Set<? extends Component>>, ResponseFormat> handleProductStrategist(String userId) {
189 // Should be empty list according to Ella, 13/03/16
190 Map<String, Set<? extends Component>> result = new HashMap<String, Set<? extends Component>>();
191 result.put("products", new HashSet<>());
192 return Either.left(result);
195 private Either<Map<String, Set<? extends Component>>, ResponseFormat> handleProductManager(String userId) {
196 Set<LifecycleStateEnum> lifecycleStates = new HashSet<LifecycleStateEnum>();
197 Set<LifecycleStateEnum> lastStateStates = new HashSet<LifecycleStateEnum>();
198 Either<Map<String, Set<? extends Component>>, ResponseFormat> response;
199 lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
200 lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
201 lifecycleStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION);
202 lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
203 lifecycleStates.add(LifecycleStateEnum.CERTIFIED);
205 lastStateStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION);
206 response = getFollowedProducts(userId, lifecycleStates, lastStateStates);
210 private Either<Map<String, Set<? extends Component>>, ResponseFormat> handleOps(String userId) {
211 Set<DistributionStatusEnum> distStatus = new HashSet<DistributionStatusEnum>();
212 distStatus.add(DistributionStatusEnum.DISTRIBUTION_APPROVED);
213 distStatus.add(DistributionStatusEnum.DISTRIBUTED);
215 Either<Map<String, Set<? extends Component>>, ResponseFormat> result = handleFollowedCertifiedServices(distStatus);
219 private Either<Map<String, Set<? extends Component>>, ResponseFormat> handleFollowedCertifiedServices(Set<DistributionStatusEnum> distStatus) {
221 Either<List<Service>, StorageOperationStatus> services = toscaOperationFacade.getCertifiedServicesWithDistStatus(distStatus);
222 if (services.isLeft()) {
223 Map<String, Set<? extends Component>> result = new HashMap<>();
224 Set<Service> set = new HashSet<>();
225 set.addAll(services.left().value());
226 result.put("services", set);
227 return Either.left(result);
229 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(services.right().value())));
233 private Either<Map<String, Set<? extends Component>>, ResponseFormat> handleTester(String userId) {
234 Set<LifecycleStateEnum> lifecycleStates = new HashSet<LifecycleStateEnum>();
235 lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
236 lifecycleStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION);
237 Either<Map<String, Set<? extends Component>>, ResponseFormat> result = getFollowedResourcesAndServices(null, lifecycleStates, null);
242 private Either<Map<String, Set<? extends Component>>, ResponseFormat> getFollowedResourcesAndServices(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates) {
245 Either<Set<Resource>, StorageOperationStatus> resources = toscaOperationFacade.getFollowed(userId, lifecycleStates, lastStateStates, ComponentTypeEnum.RESOURCE);
247 if (resources.isLeft()) {
248 Either<Set<Service>, StorageOperationStatus> services = toscaOperationFacade.getFollowed(userId, lifecycleStates, lastStateStates, ComponentTypeEnum.SERVICE);
249 if (services.isLeft()) {
250 Map<String, Set<? extends Component>> result = new HashMap<String, Set<? extends Component>>();
251 result.put("services", services.left().value());
252 result.put("resources", resources.left().value());
253 return Either.left(result);
255 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(services.right().value())));
258 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resources.right().value())));
265 private Either<Map<String, Set<? extends Component>>, ResponseFormat> getFollowedProducts(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates) {
266 Either<Set<Product>, StorageOperationStatus> products = toscaOperationFacade.getFollowed(userId, lifecycleStates, lastStateStates, ComponentTypeEnum.PRODUCT);
267 if (products.isLeft()) {
268 Map<String, Set<? extends Component>> result = new HashMap<>();
269 result.put("products", products.left().value());
270 return Either.left(result);
272 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(products.right().value())));
277 * New categories flow - start
279 public Either<List<CategoryDefinition>, ActionStatus> getAllResourceCategories() {
280 return elementOperation.getAllResourceCategories();
283 public Either<List<CategoryDefinition>, ActionStatus> getAllServiceCategories() {
284 return elementOperation.getAllServiceCategories();
287 public Either<CategoryDefinition, ResponseFormat> createCategory(CategoryDefinition category, String componentTypeParamName, String userId) {
289 AuditingActionEnum auditingAction = AuditingActionEnum.ADD_CATEGORY;
290 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
291 String componentType = (componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue());
292 CategoryTypeEnum categoryType = CategoryTypeEnum.CATEGORY;
294 User user = new User();
295 Either<User, ResponseFormat> validateUser = validateUser(userId);
296 if (validateUser.isRight()) {
297 log.debug("Validation of user failed, userId {}", userId);
298 ResponseFormat responseFormat = validateUser.right().value();
300 user.setUserId(userId);
301 String currCategoryName = (category == null ? null : category.getName());
302 handleCategoryAuditing(responseFormat, user, currCategoryName, auditingAction, componentType);
303 return Either.right(responseFormat);
306 user = validateUser.left().value();
308 if (category == null) {
309 log.debug("Category json is invalid");
310 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
311 handleCategoryAuditing(responseFormat, user, null, auditingAction, componentType);
312 return Either.right(responseFormat);
315 String categoryName = category.getName();
316 // For auditing of failures we need the original non-normalized name
317 String origCategoryName = categoryName;
318 if (componentTypeEnum == null) {
319 log.debug("Component type {} is invalid", componentTypeParamName);
320 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
321 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
322 return Either.right(responseFormat);
325 Either<Boolean, ResponseFormat> validateUserRole = validateUserRole(user, componentTypeEnum);
326 if (validateUserRole.isRight()) {
327 log.debug("Validation of user role failed, userId {}", userId);
328 ResponseFormat responseFormat = validateUserRole.right().value();
329 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
330 return Either.right(responseFormat);
333 if (!ValidationUtils.validateCategoryDisplayNameFormat(categoryName)) {
334 log.debug("Category display name format is invalid, name {}, componentType {}", categoryName, componentType);
335 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue());
336 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
337 return Either.right(responseFormat);
340 categoryName = ValidationUtils.normalizeCategoryName4Display(categoryName);
342 if (!ValidationUtils.validateCategoryDisplayNameLength(categoryName)) {
343 log.debug("Category display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", categoryName, componentType);
344 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue());
345 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
346 return Either.right(responseFormat);
349 category.setName(categoryName);
351 String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(categoryName);
352 category.setNormalizedName(normalizedName);
354 NodeTypeEnum nodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, categoryType);
356 Either<Boolean, ActionStatus> categoryUniqueEither = elementOperation.isCategoryUniqueForType(nodeType, normalizedName);
357 if (categoryUniqueEither.isRight()) {
358 log.debug("Failed to check category uniqueness, name {}, componentType {}", categoryName, componentType);
359 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categoryUniqueEither.right().value());
360 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
361 return Either.right(responseFormat);
364 Boolean isCategoryUnique = categoryUniqueEither.left().value();
365 if (!isCategoryUnique) {
366 log.debug("Category is not unique, name {}, componentType {}", categoryName, componentType);
367 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, componentType, categoryName);
368 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
369 return Either.right(responseFormat);
372 Either<CategoryDefinition, ActionStatus> createCategoryByType = elementOperation.createCategory(category, nodeType);
373 if (createCategoryByType.isRight()) {
374 log.debug("Failed to create category, name {}, componentType {}", categoryName, componentType);
375 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, componentType, categoryName);
376 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
377 return Either.right(componentsUtils.getResponseFormat(createCategoryByType.right().value()));
379 category = createCategoryByType.left().value();
380 log.debug("Created category for component {}, name {}, uniqueId {}", componentType, categoryName, category.getUniqueId());
381 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
382 handleCategoryAuditing(responseFormat, user, category.getName(), auditingAction, componentType);
383 return Either.left(category);
386 public Either<SubCategoryDefinition, ResponseFormat> createSubCategory(SubCategoryDefinition subCategory, String componentTypeParamName, String parentCategoryId, String userId) {
388 AuditingActionEnum auditingAction = AuditingActionEnum.ADD_SUB_CATEGORY;
389 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
390 String componentType = (componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue());
391 CategoryTypeEnum categoryType = CategoryTypeEnum.SUBCATEGORY;
393 String parentCategoryName = parentCategoryId;
395 if (subCategory == null) {
396 log.debug("Sub-category json is invalid");
397 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
398 handleCategoryAuditing(responseFormat, null, parentCategoryName, null, auditingAction, componentType);
399 return Either.right(responseFormat);
402 String subCategoryName = subCategory.getName();
403 // For auditing of failures we need the original non-normalized name
404 String origSubCategoryName = subCategoryName;
406 User user = new User();
407 Either<User, ResponseFormat> validateUser = validateUserExists(userId, "createSubCategory", false);
408 if (validateUser.isRight()) {
409 log.debug("Validation of user failed, userId {}", userId);
410 ResponseFormat responseFormat = validateUser.right().value();
412 user.setUserId(userId);
413 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
414 return Either.right(responseFormat);
417 user = validateUser.left().value();
419 if (componentTypeEnum == null) {
420 log.debug("Component type {} is invalid", componentTypeParamName);
421 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
422 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
423 return Either.right(responseFormat);
426 Either<Boolean, ResponseFormat> validateComponentType = validateComponentTypeForCategory(componentTypeEnum, categoryType);
427 if (validateComponentType.isRight()) {
428 log.debug("Validation of component type for sub-category failed");
429 ResponseFormat responseFormat = validateComponentType.right().value();
430 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
431 return Either.right(responseFormat);
434 Either<Boolean, ResponseFormat> validateUserRole = validateUserRole(user, componentTypeEnum);
435 if (validateUserRole.isRight()) {
436 log.debug("Validation of user role failed, userId {}", userId);
437 ResponseFormat responseFormat = validateUserRole.right().value();
438 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
439 return Either.right(responseFormat);
442 NodeTypeEnum parentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY);
443 NodeTypeEnum childNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY);
445 CategoryDefinition categoryDefinition;
446 Either<CategoryDefinition, ResponseFormat> validateCategoryExists = validateCategoryExists(parentNodeType, parentCategoryId, componentTypeEnum);
447 if (validateCategoryExists.isRight()) {
448 log.debug("Validation of parent category exists failed, parent categoryId {}", parentCategoryId);
449 ResponseFormat responseFormat = validateCategoryExists.right().value();
450 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
451 return Either.right(responseFormat);
454 categoryDefinition = validateCategoryExists.left().value();
455 parentCategoryName = categoryDefinition.getName();
457 if (!ValidationUtils.validateCategoryDisplayNameFormat(subCategoryName)) {
458 log.debug("Sub-category display name format is invalid, name {}, componentType {}", subCategoryName, componentType);
459 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue());
460 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
461 return Either.right(responseFormat);
464 subCategoryName = ValidationUtils.normalizeCategoryName4Display(subCategoryName);
466 if (!ValidationUtils.validateCategoryDisplayNameLength(subCategoryName)) {
467 log.debug("Sub-category display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", subCategoryName, componentType);
468 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue());
469 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
470 return Either.right(responseFormat);
473 String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(subCategoryName);
474 subCategory.setNormalizedName(normalizedName);
476 // Uniqueness under this category
477 Either<Boolean, ActionStatus> subCategoryUniqueForCategory = elementOperation.isSubCategoryUniqueForCategory(childNodeType, normalizedName, parentCategoryId);
478 if (subCategoryUniqueForCategory.isRight()) {
479 log.debug("Failed to check sub-category uniqueness, parent name {}, subcategory norm name {}, componentType {}", parentCategoryName, normalizedName, componentType);
480 ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForCategory.right().value());
481 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
482 return Either.right(responseFormat);
485 Boolean isSubUnique = subCategoryUniqueForCategory.left().value();
487 log.debug("Sub-category is not unique for category, parent name {}, subcategory norm name {}, componentType {}", parentCategoryName, normalizedName, componentType);
488 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY, componentType, subCategoryName, parentCategoryName);
489 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
490 return Either.right(responseFormat);
493 // Setting name of subcategory to fit the similar subcategory name
495 // For example if Network-->kUKU exists for service category Network,
496 // and user is trying to create Router-->Kuku for service category
498 // his subcategory name will be Router-->kUKU.
499 Either<SubCategoryDefinition, ActionStatus> subCategoryUniqueForType = elementOperation.getSubCategoryUniqueForType(childNodeType, normalizedName);
500 if (subCategoryUniqueForType.isRight()) {
501 log.debug("Failed validation of whether similar sub-category exists, normalizedName {} componentType {}", normalizedName, componentType);
502 ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForType.right().value());
503 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
504 return Either.right(responseFormat);
506 SubCategoryDefinition subCategoryDefinition = subCategoryUniqueForType.left().value();
507 if (subCategoryDefinition != null) {
508 subCategoryName = subCategoryDefinition.getName();
511 subCategory.setName(subCategoryName);
512 ///////////////////////////////////////////// Validations end
514 Either<SubCategoryDefinition, ActionStatus> createSubCategory = elementOperation.createSubCategory(parentCategoryId, subCategory, childNodeType);
515 if (createSubCategory.isRight()) {
516 log.debug("Failed to create sub-category, name {}, componentType {}", subCategoryName, componentType);
517 ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForType.right().value());
518 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
519 return Either.right(responseFormat);
522 SubCategoryDefinition subCategoryCreated = createSubCategory.left().value();
523 log.debug("Created sub-category for component {}, name {}, uniqueId {}", componentType, subCategoryName, subCategoryCreated.getUniqueId());
524 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
525 handleCategoryAuditing(responseFormat, user, parentCategoryName, subCategoryCreated.getName(), auditingAction, componentType);
526 return Either.left(subCategoryCreated);
529 public Either<GroupingDefinition, ResponseFormat> createGrouping(GroupingDefinition grouping, String componentTypeParamName, String grandParentCategoryId, String parentSubCategoryId, String userId) {
531 AuditingActionEnum auditingAction = AuditingActionEnum.ADD_GROUPING;
532 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
533 String componentType = (componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue());
534 CategoryTypeEnum categoryType = CategoryTypeEnum.GROUPING;
536 String parentCategoryName = grandParentCategoryId;
537 String parentSubCategoryName = parentSubCategoryId;
540 Either<User, ResponseFormat> validateUser = validateUserExists(userId, "create Grouping", false);
541 if (validateUser.isRight()) {
542 log.debug("Validation of user failed, userId {}", userId);
543 ResponseFormat responseFormat = validateUser.right().value();
545 user.setUserId(userId);
546 String groupingNameForAudit = (grouping == null ? null : grouping.getName());
547 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, groupingNameForAudit, auditingAction, componentType);
548 return Either.right(responseFormat);
551 user = validateUser.left().value();
553 if (grouping == null) {
554 log.debug("Grouping json is invalid");
555 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
556 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, null, auditingAction, componentType);
557 return Either.right(responseFormat);
560 String groupingName = grouping.getName();
561 // For auditing of failures we need the original non-normalized name
562 String origGroupingName = groupingName;
564 if (componentTypeEnum == null) {
565 log.debug("Component type {} is invalid", componentTypeParamName);
566 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
567 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
568 return Either.right(responseFormat);
571 Either<Boolean, ResponseFormat> validateComponentType = validateComponentTypeForCategory(componentTypeEnum, categoryType);
572 if (validateComponentType.isRight()) {
573 log.debug("Validation of component type for grouping failed");
574 ResponseFormat responseFormat = validateComponentType.right().value();
575 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
576 return Either.right(responseFormat);
579 Either<Boolean, ResponseFormat> validateUserRole = validateUserRole(user, componentTypeEnum);
580 if (validateUserRole.isRight()) {
581 log.debug("Validation of user role failed, userId {}", userId);
582 ResponseFormat responseFormat = validateUserRole.right().value();
583 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
584 return Either.right(responseFormat);
587 NodeTypeEnum grandParentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY);
588 NodeTypeEnum parentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY);
589 NodeTypeEnum childNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.GROUPING);
592 CategoryDefinition categoryDefinition;
593 Either<CategoryDefinition, ResponseFormat> validateCategoryExists = validateCategoryExists(grandParentNodeType, grandParentCategoryId, componentTypeEnum);
594 if (validateCategoryExists.isRight()) {
595 log.debug("Validation of parent category exists failed, parent categoryId {}", grandParentCategoryId);
596 ResponseFormat responseFormat = validateCategoryExists.right().value();
597 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
598 return Either.right(responseFormat);
601 categoryDefinition = validateCategoryExists.left().value();
602 parentCategoryName = categoryDefinition.getName();
604 // Validate subcategory
605 SubCategoryDefinition subCategoryDefinition;
606 Either<SubCategoryDefinition, ResponseFormat> validateSubCategoryExists = validateSubCategoryExists(parentNodeType, parentSubCategoryId, componentTypeEnum);
607 if (validateSubCategoryExists.isRight()) {
608 log.debug("Validation of parent sub-category exists failed, parent sub-category id {}", parentSubCategoryId);
609 ResponseFormat responseFormat = validateSubCategoryExists.right().value();
610 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
611 return Either.right(responseFormat);
614 subCategoryDefinition = validateSubCategoryExists.left().value();
615 parentSubCategoryName = subCategoryDefinition.getName();
617 if (!ValidationUtils.validateCategoryDisplayNameFormat(groupingName)) {
618 log.debug("Sub-category display name format is invalid, name {}, componentType {}", groupingName, componentType);
619 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue());
620 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
621 return Either.right(responseFormat);
624 groupingName = ValidationUtils.normalizeCategoryName4Display(groupingName);
626 if (!ValidationUtils.validateCategoryDisplayNameLength(groupingName)) {
627 log.debug("Grouping display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", groupingName, componentType);
628 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue());
629 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
630 return Either.right(responseFormat);
633 String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(groupingName);
634 grouping.setNormalizedName(normalizedName);
636 // Uniqueness under this category
637 Either<Boolean, ActionStatus> groupingUniqueForSubCategory = elementOperation.isGroupingUniqueForSubCategory(childNodeType, normalizedName, parentSubCategoryId);
638 if (groupingUniqueForSubCategory.isRight()) {
639 log.debug("Failed to check grouping uniqueness, parent name {}, grouping norm name {}, componentType {}", parentSubCategoryName, normalizedName, componentType);
640 ResponseFormat responseFormat = componentsUtils.getResponseFormat(groupingUniqueForSubCategory.right().value());
641 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
642 return Either.right(responseFormat);
645 Boolean isGroupingUnique = groupingUniqueForSubCategory.left().value();
646 if (!isGroupingUnique) {
647 log.debug("Grouping is not unique for sub-category, parent name {}, grouping norm name {}, componentType {}", parentSubCategoryName, normalizedName, componentType);
648 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY, componentType, groupingName, parentSubCategoryName);
649 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
650 return Either.right(responseFormat);
653 // Setting name of grouping to fit the similar grouping name ignoring
655 // For example if Network-->kUKU exists for service sub-category
656 // Network, and user is trying to create grouping Router-->Kuku for
657 // service sub-category Router,
658 // his grouping name will be Router-->kUKU.
659 Either<GroupingDefinition, ActionStatus> groupingUniqueForType = elementOperation.getGroupingUniqueForType(childNodeType, normalizedName);
660 if (groupingUniqueForType.isRight()) {
661 log.debug("Failed validation of whether similar grouping exists, normalizedName {} componentType {}", normalizedName, componentType);
662 ResponseFormat responseFormat = componentsUtils.getResponseFormat(groupingUniqueForType.right().value());
663 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
664 return Either.right(responseFormat);
666 GroupingDefinition groupingDefinition = groupingUniqueForType.left().value();
667 if (groupingDefinition != null) {
668 groupingName = groupingDefinition.getName();
671 grouping.setName(groupingName);
672 ///////////////////////////////////////////// Validations end
674 Either<GroupingDefinition, ActionStatus> createGrouping = elementOperation.createGrouping(parentSubCategoryId, grouping, childNodeType);
675 if (createGrouping.isRight()) {
676 log.debug("Failed to create grouping, name {}, componentType {}", groupingName, componentType);
677 ResponseFormat responseFormat = componentsUtils.getResponseFormat(createGrouping.right().value());
678 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
679 return Either.right(responseFormat);
682 GroupingDefinition groupingCreated = createGrouping.left().value();
683 log.debug("Created grouping for component {}, name {}, uniqueId {}", componentType, groupingName, groupingCreated.getUniqueId());
684 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
685 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, groupingCreated.getName(), auditingAction, componentType);
686 return Either.left(groupingCreated);
689 public Either<List<CategoryDefinition>, ResponseFormat> getAllCategories(String componentType, String userId) {
690 AuditingActionEnum auditingAction = AuditingActionEnum.GET_CATEGORY_HIERARCHY;
691 ResponseFormat responseFormat;
692 User user = new User();
693 if (userId == null) {
694 user.setUserId("UNKNOWN");
695 responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION);
696 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat);
697 return Either.right(responseFormat);
700 Either<User, ResponseFormat> validateUser = validateUserExists(userId, "get All Categories", false);
701 if (validateUser.isRight()) {
702 user.setUserId(userId);
703 log.debug("Validation of user failed, userId {}", userId);
704 responseFormat = validateUser.right().value();
705 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat);
706 return Either.right(responseFormat);
708 user = validateUser.left().value();
710 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
711 if (componentTypeEnum == null) {
712 log.debug("Cannot create category for component type {}", componentType);
713 responseFormat = componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, "component type");
714 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat);
715 return Either.right(responseFormat);
718 NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY);
719 Either<List<CategoryDefinition>, ActionStatus> getAllCategoriesByType = elementOperation.getAllCategories(nodeTypeEnum, false);
720 if (getAllCategoriesByType.isRight()) {
721 responseFormat = componentsUtils.getResponseFormat(getAllCategoriesByType.right().value());
722 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat);
723 return Either.right(responseFormat);
725 List<CategoryDefinition> categories = getAllCategoriesByType.left().value();
726 responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
727 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat);
728 return Either.left(categories);
731 public Either<UiCategories, ResponseFormat> getAllCategories(String userId) {
732 AuditingActionEnum auditingAction = AuditingActionEnum.GET_CATEGORY_HIERARCHY;
733 ResponseFormat responseFormat;
734 UiCategories categories = new UiCategories();
736 Either<User, ResponseFormat> userResponse = validateUserExists(userId, "get all categories", false);
738 if (userResponse.isRight()) {
739 return Either.right(userResponse.right().value());
741 User user = userResponse.left().value();
743 //GET resource categories
744 Either<List<CategoryDefinition>, ActionStatus> getResourceCategoriesByType = elementOperation.getAllCategories(NodeTypeEnum.ResourceNewCategory, false);
745 if (getResourceCategoriesByType.isRight()) {
746 responseFormat = componentsUtils.getResponseFormat(getResourceCategoriesByType.right().value());
747 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, ComponentTypeEnum.RESOURCE.getValue(), responseFormat);
748 return Either.right(responseFormat);
750 categories.setResourceCategories(getResourceCategoriesByType.left().value());
752 //GET service categories
753 Either<List<CategoryDefinition>, ActionStatus> getServiceCategoriesByType = elementOperation.getAllCategories(NodeTypeEnum.ServiceNewCategory, false);
754 if (getServiceCategoriesByType.isRight()) {
755 responseFormat = componentsUtils.getResponseFormat(getServiceCategoriesByType.right().value());
756 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, ComponentTypeEnum.SERVICE.getValue(), responseFormat);
757 return Either.right(responseFormat);
759 categories.setServiceCategories(getServiceCategoriesByType.left().value());
761 //GET product categories
762 Either<List<CategoryDefinition>, ActionStatus> getProductCategoriesByType = elementOperation.getAllCategories(NodeTypeEnum.ProductCategory, false);
763 if (getProductCategoriesByType.isRight()) {
764 responseFormat = componentsUtils.getResponseFormat(getProductCategoriesByType.right().value());
765 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, ComponentTypeEnum.PRODUCT.getValue(), responseFormat);
766 return Either.right(responseFormat);
769 categories.setProductCategories(getProductCategoriesByType.left().value());
770 return Either.left(categories);
774 public Either<CategoryDefinition, ResponseFormat> deleteCategory(String categoryId, String componentTypeParamName, String userId) {
776 Either<User, ResponseFormat> resp = validateUserExists(userId, "delete Category", false);
777 if (resp.isRight()) {
778 return Either.right(resp.right().value());
781 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
782 if (componentTypeEnum == null) {
783 log.debug("Cannot create category for component type {}", componentTypeParamName);
784 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
787 NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY);
789 Either<CategoryDefinition, ActionStatus> deleteCategoryByType = elementOperation.deleteCategory(nodeTypeEnum, categoryId);
790 if (deleteCategoryByType.isRight()) {
791 // auditing, logging here...
792 return Either.right(componentsUtils.getResponseFormat(deleteCategoryByType.right().value()));
794 CategoryDefinition category = deleteCategoryByType.left().value();
795 log.debug("Delete category for component {}, name {}, uniqueId {}", nodeTypeEnum, category.getName(), category.getUniqueId());
796 return Either.left(category);
799 public Either<SubCategoryDefinition, ResponseFormat> deleteSubCategory(String grandParentCategoryId, String parentSubCategoryId, String componentTypeParamName, String userId) {
801 Either<User, ResponseFormat> resp = validateUserExists(userId, "delete Sub Category", false);
802 if (resp.isRight()) {
803 return Either.right(resp.right().value());
806 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
807 if (componentTypeEnum == null) {
808 log.debug("Cannot delete sub-category for component type {}", componentTypeParamName);
809 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
812 NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY);
814 Either<SubCategoryDefinition, ActionStatus> deleteSubCategoryByType = elementOperation.deleteSubCategory(nodeTypeEnum, parentSubCategoryId);
815 if (deleteSubCategoryByType.isRight()) {
816 // auditing, logging here...
817 return Either.right(componentsUtils.getResponseFormat(deleteSubCategoryByType.right().value()));
819 SubCategoryDefinition subCategory = deleteSubCategoryByType.left().value();
820 log.debug("Deleted sub-category for component {}, name {}, uniqueId {}", nodeTypeEnum, subCategory.getName(), subCategory.getUniqueId());
821 return Either.left(subCategory);
824 public Either<GroupingDefinition, ResponseFormat> deleteGrouping(String grandParentCategoryId, String parentSubCategoryId, String groupingId, String componentTypeParamName, String userId) {
826 Either<User, ResponseFormat> resp = validateUserExists(userId, "delete Grouping", false);
827 if (resp.isRight()) {
828 return Either.right(resp.right().value());
831 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
832 if (componentTypeEnum == null) {
833 log.debug("Cannot delete grouping for component type {}", componentTypeParamName);
834 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
837 NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.GROUPING);
839 Either<GroupingDefinition, ActionStatus> deleteGroupingByType = elementOperation.deleteGrouping(nodeTypeEnum, groupingId);
840 if (deleteGroupingByType.isRight()) {
841 // auditing, logging here...
842 return Either.right(componentsUtils.getResponseFormat(deleteGroupingByType.right().value()));
844 GroupingDefinition deletedGrouping = deleteGroupingByType.left().value();
845 log.debug("Deleted grouping for component {}, name {}, uniqueId {}", nodeTypeEnum, deletedGrouping.getName(), deletedGrouping.getUniqueId());
846 return Either.left(deletedGrouping);
849 private Either<User, ResponseFormat> validateUser(String userId) {
851 // validate user exists
852 if (userId == null) {
853 log.debug("UserId is null");
854 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION));
857 Either<User, ActionStatus> userResult = userAdminManager.getUser(userId, false);
858 if (userResult.isRight()) {
859 ResponseFormat responseFormat;
860 if (userResult.right().value().equals(ActionStatus.USER_NOT_FOUND)) {
861 log.debug("Not authorized user, userId = {}", userId);
862 responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
864 log.debug("Failed to authorize user, userId = {}", userId);
865 responseFormat = componentsUtils.getResponseFormat(userResult.right().value());
868 return Either.right(responseFormat);
870 return Either.left(userResult.left().value());
871 // ========================================-
874 private Either<Boolean, ResponseFormat> validateUserRole(User user, ComponentTypeEnum componentTypeEnum) {
875 String role = user.getRole();
876 boolean validAdminAction = (role.equals(Role.ADMIN.name()) && (componentTypeEnum == ComponentTypeEnum.SERVICE || componentTypeEnum == ComponentTypeEnum.RESOURCE));
877 boolean validProductAction = (role.equals(Role.PRODUCT_STRATEGIST.name()) && (componentTypeEnum == ComponentTypeEnum.PRODUCT));
879 if (!(validAdminAction || validProductAction)) {
880 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
881 log.debug("User not permitted to perform operation on category, userId = {}, role = {}, componentType = {}", user.getUserId(), role, componentTypeEnum);
882 return Either.right(responseFormat);
884 return Either.left(true);
887 private Either<Boolean, ResponseFormat> validateComponentTypeForCategory(ComponentTypeEnum componentType, CategoryTypeEnum categoryType) {
888 boolean validResourceAction = (componentType == ComponentTypeEnum.RESOURCE && (categoryType == CategoryTypeEnum.CATEGORY || categoryType == CategoryTypeEnum.SUBCATEGORY));
889 boolean validServiceAction = (componentType == ComponentTypeEnum.SERVICE && categoryType == CategoryTypeEnum.CATEGORY);
890 boolean validProductAction = (componentType == ComponentTypeEnum.PRODUCT); // can
896 if (!(validResourceAction || validServiceAction || validProductAction)) {
897 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
898 log.debug("It's not allowed to create category type {} for component type {}", categoryType, componentType);
899 return Either.right(responseFormat);
901 return Either.left(true);
904 private Either<CategoryDefinition, ResponseFormat> validateCategoryExists(NodeTypeEnum nodeType, String categoryId, ComponentTypeEnum componentType) {
905 Either<CategoryDefinition, ActionStatus> categoryByTypeAndId = elementOperation.getCategory(nodeType, categoryId);
906 if (categoryByTypeAndId.isRight()) {
907 log.debug("Failed to fetch parent category, parent categoryId {}", categoryId);
908 ActionStatus actionStatus = categoryByTypeAndId.right().value();
909 ResponseFormat responseFormat;
910 if (actionStatus == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND) {
911 responseFormat = componentsUtils.getResponseFormat(actionStatus, componentType.getValue().toLowerCase(), CategoryTypeEnum.CATEGORY.getValue(), "");
913 responseFormat = componentsUtils.getResponseFormat(actionStatus);
915 return Either.right(responseFormat);
917 return Either.left(categoryByTypeAndId.left().value());
920 private Either<SubCategoryDefinition, ResponseFormat> validateSubCategoryExists(NodeTypeEnum nodeType, String subCategoryId, ComponentTypeEnum componentType) {
921 Either<SubCategoryDefinition, ActionStatus> subCategoryByTypeAndId = elementOperation.getSubCategory(nodeType, subCategoryId);
922 if (subCategoryByTypeAndId.isRight()) {
923 log.debug("Failed to fetch parent category, parent categoryId {}", subCategoryId);
924 ActionStatus actionStatus = subCategoryByTypeAndId.right().value();
925 ResponseFormat responseFormat;
926 if (actionStatus == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND) {
927 responseFormat = componentsUtils.getResponseFormat(actionStatus, componentType.getValue().toLowerCase(), CategoryTypeEnum.SUBCATEGORY.getValue(), "");
929 responseFormat = componentsUtils.getResponseFormat(actionStatus);
931 return Either.right(responseFormat);
933 return Either.left(subCategoryByTypeAndId.left().value());
936 private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, AuditingActionEnum auditingAction, String componentType) {
937 componentsUtils.auditCategory(responseFormat, user, category, null, null, auditingAction, componentType);
940 private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, String subCategory, AuditingActionEnum auditingAction, String componentType) {
941 componentsUtils.auditCategory(responseFormat, user, category, subCategory, null, auditingAction, componentType);
944 private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, String subCategory, String grouping, AuditingActionEnum auditingAction, String componentType) {
945 componentsUtils.auditCategory(responseFormat, user, category, subCategory, grouping, auditingAction, componentType);
949 * New categories flow - end
952 public Either<List<Tag>, ActionStatus> getAllTags(String userId) {
953 Either<User, ActionStatus> resp = validateUserExistsActionStatus(userId, "get All Tags");
954 if (resp.isRight()) {
955 return Either.right(resp.right().value());
957 return elementOperation.getAllTags();
960 public Either<List<PropertyScope>, ActionStatus> getAllPropertyScopes(String userId) {
961 Either<User, ActionStatus> resp = validateUserExistsActionStatus(userId, "get All Property Scopes");
962 if (resp.isRight()) {
963 return Either.right(resp.right().value());
965 return elementOperation.getAllPropertyScopes();
968 public Either<List<ArtifactType>, ActionStatus> getAllArtifactTypes(String userId) {
969 Either<User, ActionStatus> resp = validateUserExistsActionStatus(userId, "get All Artifact Types");
970 if (resp.isRight()) {
971 return Either.right(resp.right().value());
973 return elementOperation.getAllArtifactTypes();
976 public Either<Map<String, Object>, ActionStatus> getAllDeploymentArtifactTypes() {
977 return elementOperation.getAllDeploymentArtifactTypes();
980 public Either<Integer, ActionStatus> getDefaultHeatTimeout() {
981 return elementOperation.getDefaultHeatTimeout();
984 public Either<Map<String, List<? extends Component>>, ResponseFormat> getCatalogComponents(String userId, List<OriginTypeEnum> excludeTypes) {
985 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Catalog Components", false);
986 if (resp.isRight()) {
987 return Either.right(resp.right().value());
989 Map<String, List<? extends Component>> resMap = new HashMap<>();
991 Either<List<Resource>, StorageOperationStatus> resResources = toscaOperationFacade.getCatalogComponents(ComponentTypeEnum.RESOURCE,excludeTypes, true);
992 if (resResources.isLeft()) {
993 Either<List<Service>, StorageOperationStatus> resServices = toscaOperationFacade.getCatalogComponents(ComponentTypeEnum.SERVICE,excludeTypes, true);
994 if (resServices.isLeft()) {
995 // Either<List<Product>, StorageOperationStatus> resProducts = productOperation.getProductCatalogData(false);
996 // if (resProducts.isLeft()) {
997 resMap.put("resources", resResources.left().value());
998 resMap.put("services", resServices.left().value());
999 resMap.put("products", new ArrayList<>());
1001 return Either.left(resMap);
1003 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resServices.right().value())));
1006 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resResources.right().value())));
1010 public Either<List<? extends Component>, ResponseFormat> getFilteredCatalogComponents(String assetType, Map<FilterKeyEnum, String> filters, String query) {
1011 ComponentTypeEnum assetTypeEnum = AssetTypeEnum.convertToComponentTypeEnum(assetType);
1013 if (query != null) {
1014 Optional<NameValuePair> invalidFilter = findInvalidFilter(query, assetTypeEnum);
1015 if (invalidFilter.isPresent()) {
1016 log.debug("getFilteredAssetList: invalid filter key");
1017 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_FILTER_KEY, invalidFilter.get().getName(), FilterKeyEnum.getValidFiltersByAssetType(assetTypeEnum).toString()));
1021 if (filters == null || filters.isEmpty()) {
1022 Either<List<Component>, StorageOperationStatus> componentsList = toscaOperationFacade.getCatalogComponents(assetTypeEnum,null, false);
1023 if(componentsList.isRight()) {
1024 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(componentsList.right().value())));
1026 return Either.left(componentsList.left().value());
1029 Either<List<Component>, StorageOperationStatus> result = getFilteredComponents(filters, assetTypeEnum, false);
1031 // category hierarchy mismatch or category/subCategory/distributionStatus not found
1032 if (result.isRight()) {
1033 List<String> params = getErrorResponseParams(filters, assetTypeEnum);
1034 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value()), params.get(0), params.get(1), params.get(2)));
1036 if (result.left().value().isEmpty()) {// no assets found for requested
1038 return Either.right(componentsUtils.getResponseFormat(ActionStatus.NO_ASSETS_FOUND, assetType, query));
1040 return Either.left(result.left().value());
1043 private Either<List<Component>, StorageOperationStatus> getFilteredComponents(Map<FilterKeyEnum, String> filters, ComponentTypeEnum assetType, boolean inTransaction) {
1044 Either<List<Component>, StorageOperationStatus> assetResult = Either.left(new LinkedList<>());
1045 if(assetType == ComponentTypeEnum.RESOURCE){
1047 assetResult = getFilteredResouces(filters, inTransaction);
1049 } else if (assetType == ComponentTypeEnum.SERVICE){
1051 assetResult = getFilteredServices(filters, inTransaction);
1056 private <T> Either<List<T>, StorageOperationStatus> getFilteredServices(Map<FilterKeyEnum, String> filters, boolean inTransaction) {
1058 Either<List<T>, StorageOperationStatus> components = null;
1060 String categoryName = filters.get(FilterKeyEnum.CATEGORY);
1061 String distributionStatus = filters.get(FilterKeyEnum.DISTRIBUTION_STATUS);
1062 DistributionStatusEnum distEnum = DistributionStatusEnum.findState(distributionStatus);
1063 if (distributionStatus != null && distEnum == null) {
1064 filters.remove(FilterKeyEnum.CATEGORY);
1065 return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
1068 if (categoryName != null) { // primary filter
1069 components = fetchByCategoryOrSubCategoryName(categoryName, NodeTypeEnum.ServiceNewCategory, GraphEdgeLabels.CATEGORY.getProperty(), NodeTypeEnum.Service, inTransaction, ServiceMetadataData.class, null);
1070 if (components.isLeft() && distEnum != null) {// secondary filter
1071 Predicate<T> statusFilter = p -> ((Service) p).getDistributionStatus().equals(distEnum);
1072 return Either.left(components.left().value().stream().filter(statusFilter).collect(Collectors.toList()));
1074 filters.remove(FilterKeyEnum.DISTRIBUTION_STATUS);
1078 Set<DistributionStatusEnum> distStatusSet = new HashSet<>();
1079 distStatusSet.add(distEnum);
1080 Either<List<Service>, StorageOperationStatus> servicesWithDistStatus = toscaOperationFacade.getServicesWithDistStatus(distStatusSet, null);
1081 if (servicesWithDistStatus.isRight()) { // not found == empty list
1082 return Either.left(new ArrayList<>());
1085 return Either.left((List<T>)servicesWithDistStatus.left().value());
1088 public Either<List<? extends Component>, ResponseFormat> getCatalogComponentsByUuidAndAssetType(String assetType, String uuid) {
1090 if (assetType == null || assetType == null) {
1091 log.debug("getCatalogComponentsByUuidAndAssetType: One of the function parameteres is null");
1092 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1095 ComponentTypeEnum assetTypeEnum = AssetTypeEnum.convertToComponentTypeEnum(assetType);
1097 if (assetTypeEnum == null) {
1098 log.debug("getCatalogComponentsByUuidAndAssetType: Corresponding ComponentTypeEnum not found");
1099 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1102 Map<GraphPropertyEnum, Object> additionalPropertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
1104 switch (assetTypeEnum) {
1106 additionalPropertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
1109 additionalPropertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
1112 log.debug("getCatalogComponentsByUuidAndAssetType: Corresponding ComponentTypeEnum not allowed for this API");
1113 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1116 Either<List<Component>, StorageOperationStatus> componentsListByUuid = toscaOperationFacade.getComponentListByUuid(uuid, additionalPropertiesToMatch);
1117 if(componentsListByUuid.isRight()) {
1118 log.debug("getCatalogComponentsByUuidAndAssetType: " + assetTypeEnum.getValue()+ " fetching failed");
1119 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(componentsListByUuid.right().value(), assetTypeEnum);
1120 return Either.right(componentsUtils.getResponseFormat(actionStatus, uuid));
1123 log.debug("getCatalogComponentsByUuidAndAssetType: " + assetTypeEnum.getValue() + assetTypeEnum.getValue() + "fetching successful");
1124 return Either.left(componentsListByUuid.left().value());
1127 public List<String> getAllComponentTypesParamNames() {
1128 List<String> paramNames = new ArrayList<>();
1129 paramNames.add(ComponentTypeEnum.SERVICE_PARAM_NAME);
1130 paramNames.add(ComponentTypeEnum.RESOURCE_PARAM_NAME);
1131 paramNames.add(ComponentTypeEnum.PRODUCT_PARAM_NAME);
1135 public List<String> getAllSupportedRoles() {
1136 Role[] values = Role.values();
1137 List<String> roleNames = new ArrayList<>();
1138 for (Role role : values) {
1139 roleNames.add(role.name());
1144 public Either<Map<String, String>, ActionStatus> getResourceTypesMap() {
1145 return elementOperation.getResourceTypesMap();
1148 private Optional<NameValuePair> findInvalidFilter(String query, ComponentTypeEnum assetType) {
1149 List<NameValuePair> params = URLEncodedUtils.parse(query, StandardCharsets.UTF_8);
1150 List<String> validKeys = FilterKeyEnum.getValidFiltersByAssetType(assetType);
1151 Predicate<NameValuePair> noMatch = p -> !validKeys.contains(p.getName());
1152 return params.stream().filter(noMatch).findAny();
1155 private List<String> getErrorResponseParams(Map<FilterKeyEnum, String> filters, ComponentTypeEnum assetType) {
1156 List<String> params = new ArrayList<String>();
1157 if (1 == filters.size()) {
1158 params.add(assetType.getValue().toLowerCase());
1159 params.add(filters.keySet().iterator().next().getName());
1160 params.add(filters.values().iterator().next());
1162 params.add(assetType.getValue());
1163 params.add(filters.get(FilterKeyEnum.SUB_CATEGORY));
1164 params.add(filters.get(FilterKeyEnum.CATEGORY));
1169 public Either<List<Component>, StorageOperationStatus> getFilteredResouces(Map<FilterKeyEnum, String> filters, boolean inTransaction) {
1171 String subCategoryName = filters.get(FilterKeyEnum.SUB_CATEGORY);
1172 String categoryName = filters.get(FilterKeyEnum.CATEGORY);
1173 ResourceTypeEnum resourceType = ResourceTypeEnum.getType( filters.get(FilterKeyEnum.RESOURCE_TYPE));
1174 Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, StorageOperationStatus> subcategories = null;
1175 Optional<ImmutablePair<SubCategoryData, GraphEdge>> subCategoryData;
1177 if (categoryName != null) {
1178 subcategories = getAllSubCategories(categoryName);
1179 if (subcategories.isRight()) {
1180 filters.remove(FilterKeyEnum.SUB_CATEGORY);
1181 return Either.right(subcategories.right().value());
1184 if (subCategoryName != null) { // primary filter
1185 if (categoryName != null) {
1186 subCategoryData = validateCategoryHierarcy(subcategories.left().value(), subCategoryName);
1187 if (!subCategoryData.isPresent()) {
1188 return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1190 return fetchByCategoryOrSubCategoryUid((String) subCategoryData.get().getLeft().getUniqueId(), NodeTypeEnum.ResourceSubcategory, GraphEdgeLabels.SUB_CATEGORY.getProperty(), NodeTypeEnum.Resource, inTransaction,
1191 ResourceMetadataData.class, resourceType);
1194 return fetchByCategoryOrSubCategoryName(subCategoryName, NodeTypeEnum.ResourceSubcategory, GraphEdgeLabels.SUB_CATEGORY.getProperty(), NodeTypeEnum.Resource, inTransaction, ResourceMetadataData.class, resourceType);
1196 if(subcategories != null){
1197 return fetchByMainCategory(subcategories.left().value(), inTransaction, resourceType);
1199 return fetchComponentMetaDataByResourceType(filters.get(FilterKeyEnum.RESOURCE_TYPE), inTransaction);
1202 private Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, StorageOperationStatus> getAllSubCategories(String categoryName) {
1203 Either<CategoryData, StorageOperationStatus> categoryResult = elementOperation.getNewCategoryData(categoryName, NodeTypeEnum.ResourceNewCategory, CategoryData.class);
1204 if (categoryResult.isRight()) {
1205 return Either.right(categoryResult.right().value());
1207 CategoryData categoryData = categoryResult.left().value();
1209 Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceNewCategory), (String) categoryData.getUniqueId(),
1210 GraphEdgeLabels.SUB_CATEGORY, NodeTypeEnum.ResourceSubcategory, SubCategoryData.class);
1211 if (childrenNodes.isRight()) {
1212 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenNodes.right().value()));
1214 return Either.left(childrenNodes.left().value());
1217 private Optional<ImmutablePair<SubCategoryData, GraphEdge>> validateCategoryHierarcy(List<ImmutablePair<SubCategoryData, GraphEdge>> childNodes, String subCategoryName) {
1218 Predicate<ImmutablePair<SubCategoryData, GraphEdge>> matchName = p -> p.getLeft().getSubCategoryDataDefinition().getName().equals(subCategoryName);
1219 return childNodes.stream().filter(matchName).findAny();
1222 protected <T, S extends ComponentMetadataData> Either<List<T>, StorageOperationStatus> fetchByCategoryOrSubCategoryUid(String categoryUid, NodeTypeEnum categoryType, String categoryLabel, NodeTypeEnum neededType, boolean inTransaction,
1223 Class<S> clazz, ResourceTypeEnum resourceType) {
1225 Either<TitanGraph, TitanOperationStatus> graph = titanDao.getGraph();
1226 if (graph.isRight()) {
1227 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value()));
1230 return collectComponents(graph.left().value(), neededType, categoryUid, categoryType, clazz, resourceType);
1233 if (false == inTransaction) {
1239 protected <T, S extends ComponentMetadataData> Either<List<T>, StorageOperationStatus> fetchByCategoryOrSubCategoryName(String categoryName, NodeTypeEnum categoryType, String categoryLabel, NodeTypeEnum neededType, boolean inTransaction,
1240 Class<S> clazz, ResourceTypeEnum resourceType) {
1241 List<T> components = new ArrayList<>();
1243 Class categoryClazz = categoryType == NodeTypeEnum.ServiceNewCategory ? CategoryData.class : SubCategoryData.class;
1244 Map<String, Object> props = new HashMap<String, Object>();
1245 props.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), ValidationUtils.normalizeCategoryName4Uniqueness(categoryName));
1246 Either<List<GraphNode>, TitanOperationStatus> getCategory = titanGenericDao.getByCriteria(categoryType, props, categoryClazz);
1247 if (getCategory.isRight()) {
1248 return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
1250 Either<TitanGraph, TitanOperationStatus> graph = titanDao.getGraph();
1251 if (graph.isRight()) {
1252 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value()));
1255 for (GraphNode category : getCategory.left().value()) {
1256 Either<List<T>, StorageOperationStatus> result = collectComponents(graph.left().value(), neededType, (String) category.getUniqueId(), categoryType, clazz, resourceType);
1257 if (result.isRight()) {
1260 components.addAll(result.left().value());
1263 return Either.left(components);
1265 if (false == inTransaction) {
1271 private <T, S extends ComponentMetadataData> Either<List<T>, StorageOperationStatus> collectComponents(TitanGraph graph, NodeTypeEnum neededType, String categoryUid, NodeTypeEnum categoryType, Class<S> clazz, ResourceTypeEnum resourceType) {
1272 List<T> components = new ArrayList<>();
1273 Either<List<ImmutablePair<S, GraphEdge>>, TitanOperationStatus> parentNodes = titanGenericDao.getParentNodes(UniqueIdBuilder.getKeyByNodeType(categoryType), categoryUid, GraphEdgeLabels.CATEGORY, neededType, clazz);
1274 if (parentNodes.isLeft()) {
1275 for (ImmutablePair<S, GraphEdge> component : parentNodes.left().value()) {
1276 ComponentMetadataDataDefinition componentData = component.getLeft().getMetadataDataDefinition();
1277 Boolean isHighest = componentData.isHighestVersion();
1278 boolean isMatchingResourceType = isMatchingByResourceType(neededType, resourceType, componentData);
1280 if (isHighest && isMatchingResourceType) {
1281 Either<T, StorageOperationStatus> result = (Either<T, StorageOperationStatus>) toscaOperationFacade.getToscaElement(componentData.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
1282 if (result.isRight()) {
1283 return Either.right(result.right().value());
1285 components.add(result.left().value());
1289 return Either.left(components);
1292 private boolean isMatchingByResourceType(NodeTypeEnum componentType, ResourceTypeEnum resourceType,
1293 ComponentMetadataDataDefinition componentData) {
1296 if (componentType == NodeTypeEnum.Resource) {
1297 if (resourceType == null) {
1300 isMatching = resourceType == ((ResourceMetadataDataDefinition)componentData).getResourceType();
1308 private <T> Either<List<T>, StorageOperationStatus> fetchByMainCategory(List<ImmutablePair<SubCategoryData, GraphEdge>> subcategories, boolean inTransaction, ResourceTypeEnum resourceType) {
1309 List<T> components = new ArrayList<>();
1311 for (ImmutablePair<SubCategoryData, GraphEdge> subCategory : subcategories) {
1312 Either<List<T>, StorageOperationStatus> fetched = fetchByCategoryOrSubCategoryUid((String) subCategory.getLeft().getUniqueId(), NodeTypeEnum.ResourceSubcategory, GraphEdgeLabels.SUB_CATEGORY.getProperty(), NodeTypeEnum.Resource,
1313 inTransaction, ResourceMetadataData.class, resourceType);
1314 if (fetched.isRight()) {
1318 components.addAll(fetched.left().value());
1320 return Either.left(components);
1323 private Either<List<Component>, StorageOperationStatus> fetchComponentMetaDataByResourceType(String resourceType, boolean inTransaction) {
1324 List<Component> components = null;
1325 StorageOperationStatus status;
1326 Wrapper<StorageOperationStatus> statusWrapper = new Wrapper<>();
1327 Either<List<Component>, StorageOperationStatus> result;
1329 ComponentParametersView fetchUsersAndCategoriesFilter = new ComponentParametersView(Arrays.asList(ComponentFieldsEnum.USERS.getValue(), ComponentFieldsEnum.CATEGORIES.getValue()));
1330 Either<List<Component>, StorageOperationStatus> getResources = toscaOperationFacade.fetchMetaDataByResourceType(resourceType, fetchUsersAndCategoriesFilter);
1331 if (getResources.isRight()) {
1332 status = getResources.right().value();
1333 if(status != StorageOperationStatus.NOT_FOUND){
1334 statusWrapper.setInnerElement(getResources.right().value());
1336 components = new ArrayList<>();
1339 components = getResources.left().value();
1341 if(!statusWrapper.isEmpty()){
1342 result = Either.right(statusWrapper.getInnerElement());
1344 result = Either.left(components);
1348 if (!inTransaction) {
1354 Component convertComponentMetadataDataToComponent(ComponentMetadataData componentMetadataData) {
1355 return convertResourceDataToResource((ResourceMetadataData) componentMetadataData);
1357 private Resource convertResourceDataToResource(ResourceMetadataData resourceData) {
1359 ResourceMetadataDefinition resourceMetadataDataDefinition = new ResourceMetadataDefinition((ResourceMetadataDataDefinition) resourceData.getMetadataDataDefinition());
1361 Resource resource = new Resource(resourceMetadataDataDefinition);
1365 private <T> Either<List<T>, StorageOperationStatus> fetchByDistributionStatus(String status, boolean inTransaction) {
1366 Map<String, Object> props = new HashMap<String, Object>();
1367 props.put(GraphPropertiesDictionary.DISTRIBUTION_STATUS.getProperty(), status);
1368 props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true);
1369 return (Either<List<T>, StorageOperationStatus>) (Either<?, StorageOperationStatus>) getServiceListByCriteria(props, inTransaction);
1372 private Either<List<Service>, StorageOperationStatus> getServiceListByCriteria(Map<String, Object> props, boolean inTransaction) {
1373 props.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Service.getName());
1374 Either<List<ServiceMetadataData>, TitanOperationStatus> byCriteria = titanGenericDao.getByCriteria(NodeTypeEnum.Service, props, ServiceMetadataData.class);
1376 if (byCriteria.isRight()) {
1377 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value()));
1379 List<Service> services = new ArrayList<Service>();
1380 List<ServiceMetadataData> servicesDataList = byCriteria.left().value();
1381 for (ServiceMetadataData data : servicesDataList) {
1382 Either<Component, StorageOperationStatus> service = toscaOperationFacade.getToscaElement(data.getMetadataDataDefinition().getUniqueId());
1383 if (service.isLeft()) {
1384 services.add((Service)service.left().value());
1386 log.debug("Failed to fetch resource for name = {} and id = {}",data.getMetadataDataDefinition().getName(),data.getUniqueId());
1389 return Either.left(services);