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 java.nio.charset.StandardCharsets;
24 import java.util.ArrayList;
25 import java.util.EnumMap;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.List;
30 import java.util.Optional;
32 import java.util.function.Predicate;
33 import java.util.stream.Collectors;
35 import org.apache.commons.lang3.tuple.ImmutablePair;
36 import org.apache.http.NameValuePair;
37 import org.apache.http.client.utils.URLEncodedUtils;
38 import org.openecomp.sdc.be.dao.api.ActionStatus;
39 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
40 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
41 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
42 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
43 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
44 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
45 import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum;
46 import org.openecomp.sdc.be.datamodel.utils.NodeTypeConvertUtils;
47 import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition;
48 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
49 import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum;
50 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
51 import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
52 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
53 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
54 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
55 import org.openecomp.sdc.be.impl.ComponentsUtils;
56 import org.openecomp.sdc.be.model.ArtifactType;
57 import org.openecomp.sdc.be.model.Component;
58 import org.openecomp.sdc.be.model.DistributionStatusEnum;
59 import org.openecomp.sdc.be.model.LifecycleStateEnum;
60 import org.openecomp.sdc.be.model.Product;
61 import org.openecomp.sdc.be.model.PropertyScope;
62 import org.openecomp.sdc.be.model.Resource;
63 import org.openecomp.sdc.be.model.ResourceMetadataDefinition;
64 import org.openecomp.sdc.be.model.Service;
65 import org.openecomp.sdc.be.model.Tag;
66 import org.openecomp.sdc.be.model.User;
67 import org.openecomp.sdc.be.model.category.CategoryDefinition;
68 import org.openecomp.sdc.be.model.category.GroupingDefinition;
69 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
70 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
71 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
72 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
73 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
74 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
75 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
76 import org.openecomp.sdc.be.resources.data.ServiceMetadataData;
77 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
78 import org.openecomp.sdc.be.resources.data.category.CategoryData;
79 import org.openecomp.sdc.be.resources.data.category.SubCategoryData;
80 import org.openecomp.sdc.be.ui.model.UiCategories;
81 import org.openecomp.sdc.be.user.Role;
82 import org.openecomp.sdc.be.user.UserBusinessLogic;
83 import org.openecomp.sdc.common.datastructure.Wrapper;
84 import org.openecomp.sdc.common.util.ValidationUtils;
85 import org.openecomp.sdc.exception.ResponseFormat;
86 import org.slf4j.Logger;
87 import org.slf4j.LoggerFactory;
89 import com.thinkaurelius.titan.core.TitanGraph;
91 import fj.data.Either;
93 @org.springframework.stereotype.Component("elementsBusinessLogic")
94 public class ElementBusinessLogic extends BaseBusinessLogic {
96 private static Logger log = LoggerFactory.getLogger(ElementBusinessLogic.class.getName());
98 @javax.annotation.Resource
99 private IElementOperation elementOperation;
101 @javax.annotation.Resource
102 private ComponentsUtils componentsUtils;
104 @javax.annotation.Resource
105 private UserBusinessLogic userAdminManager;
112 public Either<Map<String, List<? extends Component>>, ResponseFormat> getFollowed(User user) {
113 Either<Map<String, List<? extends Component>>, ResponseFormat> response = null;
115 String role = user.getRole();
116 String userId = null;
117 Role currentRole = Role.valueOf(role);
119 switch (currentRole) {
121 userId = user.getUserId();
122 response = handleDesigner(userId);
126 userId = user.getUserId();
127 response = handleTester(userId);
131 userId = user.getUserId();
132 response = handleGovernor(userId);
136 userId = user.getUserId();
137 response = handleOps(userId);
140 case PRODUCT_STRATEGIST:
141 userId = user.getUserId();
142 response = handleProductStrategist(userId);
145 case PRODUCT_MANAGER:
146 userId = user.getUserId();
147 response = handleProductManager(userId);
151 response = handleAdmin();
155 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
162 private Either<Map<String, List<? extends Component>>, ResponseFormat> handleAdmin() {
163 Either<Map<String, List<? extends Component>>, ResponseFormat> response;
164 // userId should stay null
165 Set<LifecycleStateEnum> lifecycleStates = new HashSet<LifecycleStateEnum>();
166 Set<LifecycleStateEnum> lastStateStates = new HashSet<LifecycleStateEnum>();
167 lifecycleStates.add(LifecycleStateEnum.CERTIFIED);
168 response = getFollowedResourcesAndServices(null, lifecycleStates, lastStateStates);
172 private Either<Map<String, List<? extends Component>>, ResponseFormat> handleDesigner(String userId) {
173 Set<LifecycleStateEnum> lifecycleStates = new HashSet<LifecycleStateEnum>();
174 Set<LifecycleStateEnum> lastStateStates = new HashSet<LifecycleStateEnum>();
175 Either<Map<String, List<? extends Component>>, ResponseFormat> response;
176 lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
177 lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
178 lifecycleStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION);
179 lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
180 lifecycleStates.add(LifecycleStateEnum.CERTIFIED);
182 lastStateStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION);
183 response = getFollowedResourcesAndServices(userId, lifecycleStates, lastStateStates);
187 private Either<Map<String, List<? extends Component>>, ResponseFormat> handleGovernor(String userId) {
188 Either<Map<String, List<? extends Component>>, ResponseFormat> result = handleFollowedCertifiedServices(null);
192 private Either<Map<String, List<? extends Component>>, ResponseFormat> handleProductStrategist(String userId) {
193 // Should be empty list according to Ella, 13/03/16
194 Map<String, List<? extends Component>> result = new HashMap<String, List<? extends Component>>();
195 result.put("products", new ArrayList<>());
196 return Either.left(result);
199 private Either<Map<String, List<? extends Component>>, ResponseFormat> handleProductManager(String userId) {
200 Set<LifecycleStateEnum> lifecycleStates = new HashSet<LifecycleStateEnum>();
201 Set<LifecycleStateEnum> lastStateStates = new HashSet<LifecycleStateEnum>();
202 Either<Map<String, List<? extends Component>>, ResponseFormat> response;
203 lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
204 lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
205 lifecycleStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION);
206 lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
207 lifecycleStates.add(LifecycleStateEnum.CERTIFIED);
209 lastStateStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION);
210 response = getFollowedProducts(userId, lifecycleStates, lastStateStates);
214 private Either<Map<String, List<? extends Component>>, ResponseFormat> handleOps(String userId) {
215 Set<DistributionStatusEnum> distStatus = new HashSet<DistributionStatusEnum>();
216 distStatus.add(DistributionStatusEnum.DISTRIBUTION_APPROVED);
217 distStatus.add(DistributionStatusEnum.DISTRIBUTED);
219 Either<Map<String, List<? extends Component>>, ResponseFormat> result = handleFollowedCertifiedServices(distStatus);
223 private Either<Map<String, List<? extends Component>>, ResponseFormat> handleFollowedCertifiedServices(Set<DistributionStatusEnum> distStatus) {
225 Either<List<Service>, StorageOperationStatus> services = toscaOperationFacade.getCertifiedServicesWithDistStatus(distStatus);
226 if (services.isLeft()) {
227 Map<String, List<? extends Component>> result = new HashMap<String, List<? extends Component>>();
228 List<Service> list = new ArrayList<>();
229 list.addAll(services.left().value());
230 result.put("services", list);
231 return Either.left(result);
233 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(services.right().value())));
237 private Either<Map<String, List<? extends Component>>, ResponseFormat> handleTester(String userId) {
238 Set<LifecycleStateEnum> lifecycleStates = new HashSet<LifecycleStateEnum>();
239 lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
240 lifecycleStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION);
241 Either<Map<String, List<? extends Component>>, ResponseFormat> result = getFollowedResourcesAndServices(null, lifecycleStates, null);
246 private Either<Map<String, List<? extends Component>>, ResponseFormat> getFollowedResourcesAndServices(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates) {
249 Either<List<Resource>, StorageOperationStatus> resources = toscaOperationFacade.getFollowed(userId, lifecycleStates, lastStateStates, ComponentTypeEnum.RESOURCE);
251 if (resources.isLeft()) {
252 Either<List<Service>, StorageOperationStatus> services = toscaOperationFacade.getFollowed(userId, lifecycleStates, lastStateStates, ComponentTypeEnum.SERVICE);
253 if (services.isLeft()) {
254 Map<String, List<? extends Component>> result = new HashMap<String, List<? extends Component>>();
255 result.put("services", services.left().value());
256 result.put("resources", resources.left().value());
257 return Either.left(result);
259 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(services.right().value())));
262 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resources.right().value())));
269 private Either<Map<String, List<? extends Component>>, ResponseFormat> getFollowedProducts(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates) {
270 Either<List<Product>, StorageOperationStatus> products = toscaOperationFacade.getFollowed(userId, lifecycleStates, lastStateStates, ComponentTypeEnum.PRODUCT);
271 if (products.isLeft()) {
272 Map<String, List<? extends Component>> result = new HashMap<String, List<? extends Component>>();
273 result.put("products", products.left().value());
274 return Either.left(result);
276 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(products.right().value())));
281 * New categories flow - start
283 public Either<List<CategoryDefinition>, ActionStatus> getAllResourceCategories() {
284 return elementOperation.getAllResourceCategories();
287 public Either<List<CategoryDefinition>, ActionStatus> getAllServiceCategories() {
288 return elementOperation.getAllServiceCategories();
291 public Either<CategoryDefinition, ResponseFormat> createCategory(CategoryDefinition category, String componentTypeParamName, String userId) {
293 AuditingActionEnum auditingAction = AuditingActionEnum.ADD_CATEGORY;
294 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
295 String componentType = (componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue());
296 CategoryTypeEnum categoryType = CategoryTypeEnum.CATEGORY;
298 User user = new User();
299 Either<User, ResponseFormat> validateUser = validateUser(userId);
300 if (validateUser.isRight()) {
301 log.debug("Validation of user failed, userId {}", userId);
302 ResponseFormat responseFormat = validateUser.right().value();
304 user.setUserId(userId);
305 String currCategoryName = (category == null ? null : category.getName());
306 handleCategoryAuditing(responseFormat, user, currCategoryName, auditingAction, componentType);
307 return Either.right(responseFormat);
310 user = validateUser.left().value();
312 if (category == null) {
313 log.debug("Category json is invalid");
314 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
315 handleCategoryAuditing(responseFormat, user, null, auditingAction, componentType);
316 return Either.right(responseFormat);
319 String categoryName = category.getName();
320 // For auditing of failures we need the original non-normalized name
321 String origCategoryName = categoryName;
322 if (componentTypeEnum == null) {
323 log.debug("Component type {} is invalid", componentTypeParamName);
324 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
325 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
326 return Either.right(responseFormat);
329 Either<Boolean, ResponseFormat> validateUserRole = validateUserRole(user, componentTypeEnum);
330 if (validateUserRole.isRight()) {
331 log.debug("Validation of user role failed, userId {}", userId);
332 ResponseFormat responseFormat = validateUserRole.right().value();
333 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
334 return Either.right(responseFormat);
337 if (!ValidationUtils.validateCategoryDisplayNameFormat(categoryName)) {
338 log.debug("Category display name format is invalid, name {}, componentType {}", categoryName, componentType);
339 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue());
340 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
341 return Either.right(responseFormat);
344 categoryName = ValidationUtils.normalizeCategoryName4Display(categoryName);
346 if (!ValidationUtils.validateCategoryDisplayNameLength(categoryName)) {
347 log.debug("Category display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", categoryName, componentType);
348 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue());
349 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
350 return Either.right(responseFormat);
353 category.setName(categoryName);
355 String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(categoryName);
356 category.setNormalizedName(normalizedName);
358 NodeTypeEnum nodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, categoryType);
360 Either<Boolean, ActionStatus> categoryUniqueEither = elementOperation.isCategoryUniqueForType(nodeType, normalizedName);
361 if (categoryUniqueEither.isRight()) {
362 log.debug("Failed to check category uniqueness, name {}, componentType {}", categoryName, componentType);
363 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categoryUniqueEither.right().value());
364 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
365 return Either.right(responseFormat);
368 Boolean isCategoryUnique = categoryUniqueEither.left().value();
369 if (!isCategoryUnique) {
370 log.debug("Category is not unique, name {}, componentType {}", categoryName, componentType);
371 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, componentType, categoryName);
372 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
373 return Either.right(responseFormat);
376 Either<CategoryDefinition, ActionStatus> createCategoryByType = elementOperation.createCategory(category, nodeType);
377 if (createCategoryByType.isRight()) {
378 log.debug("Failed to create category, name {}, componentType {}", categoryName, componentType);
379 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, componentType, categoryName);
380 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
381 return Either.right(componentsUtils.getResponseFormat(createCategoryByType.right().value()));
383 category = createCategoryByType.left().value();
384 log.debug("Created category for component {}, name {}, uniqueId {}", componentType, categoryName, category.getUniqueId());
385 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
386 handleCategoryAuditing(responseFormat, user, category.getName(), auditingAction, componentType);
387 return Either.left(category);
390 public Either<SubCategoryDefinition, ResponseFormat> createSubCategory(SubCategoryDefinition subCategory, String componentTypeParamName, String parentCategoryId, String userId) {
392 AuditingActionEnum auditingAction = AuditingActionEnum.ADD_SUB_CATEGORY;
393 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
394 String componentType = (componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue());
395 CategoryTypeEnum categoryType = CategoryTypeEnum.SUBCATEGORY;
397 String parentCategoryName = parentCategoryId;
399 if (subCategory == null) {
400 log.debug("Sub-category json is invalid");
401 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
402 handleCategoryAuditing(responseFormat, null, parentCategoryName, null, auditingAction, componentType);
403 return Either.right(responseFormat);
406 String subCategoryName = subCategory.getName();
407 // For auditing of failures we need the original non-normalized name
408 String origSubCategoryName = subCategoryName;
410 User user = new User();
411 Either<User, ResponseFormat> validateUser = validateUserExists(userId, "createSubCategory", false);
412 if (validateUser.isRight()) {
413 log.debug("Validation of user failed, userId {}", userId);
414 ResponseFormat responseFormat = validateUser.right().value();
416 user.setUserId(userId);
417 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
418 return Either.right(responseFormat);
421 user = validateUser.left().value();
423 if (componentTypeEnum == null) {
424 log.debug("Component type {} is invalid", componentTypeParamName);
425 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
426 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
427 return Either.right(responseFormat);
430 Either<Boolean, ResponseFormat> validateComponentType = validateComponentTypeForCategory(componentTypeEnum, categoryType);
431 if (validateComponentType.isRight()) {
432 log.debug("Validation of component type for sub-category failed");
433 ResponseFormat responseFormat = validateComponentType.right().value();
434 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
435 return Either.right(responseFormat);
438 Either<Boolean, ResponseFormat> validateUserRole = validateUserRole(user, componentTypeEnum);
439 if (validateUserRole.isRight()) {
440 log.debug("Validation of user role failed, userId {}", userId);
441 ResponseFormat responseFormat = validateUserRole.right().value();
442 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
443 return Either.right(responseFormat);
446 NodeTypeEnum parentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY);
447 NodeTypeEnum childNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY);
449 CategoryDefinition categoryDefinition;
450 Either<CategoryDefinition, ResponseFormat> validateCategoryExists = validateCategoryExists(parentNodeType, parentCategoryId, componentTypeEnum);
451 if (validateCategoryExists.isRight()) {
452 log.debug("Validation of parent category exists failed, parent categoryId {}", parentCategoryId);
453 ResponseFormat responseFormat = validateCategoryExists.right().value();
454 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
455 return Either.right(responseFormat);
458 categoryDefinition = validateCategoryExists.left().value();
459 parentCategoryName = categoryDefinition.getName();
461 if (!ValidationUtils.validateCategoryDisplayNameFormat(subCategoryName)) {
462 log.debug("Sub-category display name format is invalid, name {}, componentType {}", subCategoryName, componentType);
463 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue());
464 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
465 return Either.right(responseFormat);
468 subCategoryName = ValidationUtils.normalizeCategoryName4Display(subCategoryName);
470 if (!ValidationUtils.validateCategoryDisplayNameLength(subCategoryName)) {
471 log.debug("Sub-category display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", subCategoryName, componentType);
472 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue());
473 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
474 return Either.right(responseFormat);
477 String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(subCategoryName);
478 subCategory.setNormalizedName(normalizedName);
480 // Uniqueness under this category
481 Either<Boolean, ActionStatus> subCategoryUniqueForCategory = elementOperation.isSubCategoryUniqueForCategory(childNodeType, normalizedName, parentCategoryId);
482 if (subCategoryUniqueForCategory.isRight()) {
483 log.debug("Failed to check sub-category uniqueness, parent name {}, subcategory norm name {}, componentType {}", parentCategoryName, normalizedName, componentType);
484 ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForCategory.right().value());
485 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
486 return Either.right(responseFormat);
489 Boolean isSubUnique = subCategoryUniqueForCategory.left().value();
491 log.debug("Sub-category is not unique for category, parent name {}, subcategory norm name {}, componentType {}", parentCategoryName, normalizedName, componentType);
492 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY, componentType, subCategoryName, parentCategoryName);
493 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
494 return Either.right(responseFormat);
497 // Setting name of subcategory to fit the similar subcategory name
499 // For example if Network-->kUKU exists for service category Network,
500 // and user is trying to create Router-->Kuku for service category
502 // his subcategory name will be Router-->kUKU.
503 Either<SubCategoryDefinition, ActionStatus> subCategoryUniqueForType = elementOperation.getSubCategoryUniqueForType(childNodeType, normalizedName);
504 if (subCategoryUniqueForType.isRight()) {
505 log.debug("Failed validation of whether similar sub-category exists, normalizedName {} componentType {}", normalizedName, componentType);
506 ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForType.right().value());
507 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
508 return Either.right(responseFormat);
510 SubCategoryDefinition subCategoryDefinition = subCategoryUniqueForType.left().value();
511 if (subCategoryDefinition != null) {
512 subCategoryName = subCategoryDefinition.getName();
515 subCategory.setName(subCategoryName);
516 ///////////////////////////////////////////// Validations end
518 Either<SubCategoryDefinition, ActionStatus> createSubCategory = elementOperation.createSubCategory(parentCategoryId, subCategory, childNodeType);
519 if (createSubCategory.isRight()) {
520 log.debug("Failed to create sub-category, name {}, componentType {}", subCategoryName, componentType);
521 ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForType.right().value());
522 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
523 return Either.right(responseFormat);
526 SubCategoryDefinition subCategoryCreated = createSubCategory.left().value();
527 log.debug("Created sub-category for component {}, name {}, uniqueId {}", componentType, subCategoryName, subCategoryCreated.getUniqueId());
528 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
529 handleCategoryAuditing(responseFormat, user, parentCategoryName, subCategoryCreated.getName(), auditingAction, componentType);
530 return Either.left(subCategoryCreated);
533 public Either<GroupingDefinition, ResponseFormat> createGrouping(GroupingDefinition grouping, String componentTypeParamName, String grandParentCategoryId, String parentSubCategoryId, String userId) {
535 AuditingActionEnum auditingAction = AuditingActionEnum.ADD_GROUPING;
536 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
537 String componentType = (componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue());
538 CategoryTypeEnum categoryType = CategoryTypeEnum.GROUPING;
540 String parentCategoryName = grandParentCategoryId;
541 String parentSubCategoryName = parentSubCategoryId;
544 Either<User, ResponseFormat> validateUser = validateUserExists(userId, "create Grouping", false);
545 if (validateUser.isRight()) {
546 log.debug("Validation of user failed, userId {}", userId);
547 ResponseFormat responseFormat = validateUser.right().value();
549 user.setUserId(userId);
550 String groupingNameForAudit = (grouping == null ? null : grouping.getName());
551 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, groupingNameForAudit, auditingAction, componentType);
552 return Either.right(responseFormat);
555 user = validateUser.left().value();
557 if (grouping == null) {
558 log.debug("Grouping json is invalid");
559 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
560 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, null, auditingAction, componentType);
561 return Either.right(responseFormat);
564 String groupingName = grouping.getName();
565 // For auditing of failures we need the original non-normalized name
566 String origGroupingName = groupingName;
568 if (componentTypeEnum == null) {
569 log.debug("Component type {} is invalid", componentTypeParamName);
570 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
571 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
572 return Either.right(responseFormat);
575 Either<Boolean, ResponseFormat> validateComponentType = validateComponentTypeForCategory(componentTypeEnum, categoryType);
576 if (validateComponentType.isRight()) {
577 log.debug("Validation of component type for grouping failed");
578 ResponseFormat responseFormat = validateComponentType.right().value();
579 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
580 return Either.right(responseFormat);
583 Either<Boolean, ResponseFormat> validateUserRole = validateUserRole(user, componentTypeEnum);
584 if (validateUserRole.isRight()) {
585 log.debug("Validation of user role failed, userId {}", userId);
586 ResponseFormat responseFormat = validateUserRole.right().value();
587 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
588 return Either.right(responseFormat);
591 NodeTypeEnum grandParentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY);
592 NodeTypeEnum parentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY);
593 NodeTypeEnum childNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.GROUPING);
596 CategoryDefinition categoryDefinition;
597 Either<CategoryDefinition, ResponseFormat> validateCategoryExists = validateCategoryExists(grandParentNodeType, grandParentCategoryId, componentTypeEnum);
598 if (validateCategoryExists.isRight()) {
599 log.debug("Validation of parent category exists failed, parent categoryId {}", grandParentCategoryId);
600 ResponseFormat responseFormat = validateCategoryExists.right().value();
601 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
602 return Either.right(responseFormat);
605 categoryDefinition = validateCategoryExists.left().value();
606 parentCategoryName = categoryDefinition.getName();
608 // Validate subcategory
609 SubCategoryDefinition subCategoryDefinition;
610 Either<SubCategoryDefinition, ResponseFormat> validateSubCategoryExists = validateSubCategoryExists(parentNodeType, parentSubCategoryId, componentTypeEnum);
611 if (validateSubCategoryExists.isRight()) {
612 log.debug("Validation of parent sub-category exists failed, parent sub-category id {}", parentSubCategoryId);
613 ResponseFormat responseFormat = validateSubCategoryExists.right().value();
614 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
615 return Either.right(responseFormat);
618 subCategoryDefinition = validateSubCategoryExists.left().value();
619 parentSubCategoryName = subCategoryDefinition.getName();
621 if (!ValidationUtils.validateCategoryDisplayNameFormat(groupingName)) {
622 log.debug("Sub-category display name format is invalid, name {}, componentType {}", groupingName, componentType);
623 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue());
624 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
625 return Either.right(responseFormat);
628 groupingName = ValidationUtils.normalizeCategoryName4Display(groupingName);
630 if (!ValidationUtils.validateCategoryDisplayNameLength(groupingName)) {
631 log.debug("Grouping display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", groupingName, componentType);
632 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue());
633 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
634 return Either.right(responseFormat);
637 String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(groupingName);
638 grouping.setNormalizedName(normalizedName);
640 // Uniqueness under this category
641 Either<Boolean, ActionStatus> groupingUniqueForSubCategory = elementOperation.isGroupingUniqueForSubCategory(childNodeType, normalizedName, parentSubCategoryId);
642 if (groupingUniqueForSubCategory.isRight()) {
643 log.debug("Failed to check grouping uniqueness, parent name {}, grouping norm name {}, componentType {}", parentSubCategoryName, normalizedName, componentType);
644 ResponseFormat responseFormat = componentsUtils.getResponseFormat(groupingUniqueForSubCategory.right().value());
645 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
646 return Either.right(responseFormat);
649 Boolean isGroupingUnique = groupingUniqueForSubCategory.left().value();
650 if (!isGroupingUnique) {
651 log.debug("Grouping is not unique for sub-category, parent name {}, grouping norm name {}, componentType {}", parentSubCategoryName, normalizedName, componentType);
652 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY, componentType, groupingName, parentSubCategoryName);
653 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
654 return Either.right(responseFormat);
657 // Setting name of grouping to fit the similar grouping name ignoring
659 // For example if Network-->kUKU exists for service sub-category
660 // Network, and user is trying to create grouping Router-->Kuku for
661 // service sub-category Router,
662 // his grouping name will be Router-->kUKU.
663 Either<GroupingDefinition, ActionStatus> groupingUniqueForType = elementOperation.getGroupingUniqueForType(childNodeType, normalizedName);
664 if (groupingUniqueForType.isRight()) {
665 log.debug("Failed validation of whether similar grouping exists, normalizedName {} componentType {}", normalizedName, componentType);
666 ResponseFormat responseFormat = componentsUtils.getResponseFormat(groupingUniqueForType.right().value());
667 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
668 return Either.right(responseFormat);
670 GroupingDefinition groupingDefinition = groupingUniqueForType.left().value();
671 if (groupingDefinition != null) {
672 groupingName = groupingDefinition.getName();
675 grouping.setName(groupingName);
676 ///////////////////////////////////////////// Validations end
678 Either<GroupingDefinition, ActionStatus> createGrouping = elementOperation.createGrouping(parentSubCategoryId, grouping, childNodeType);
679 if (createGrouping.isRight()) {
680 log.debug("Failed to create grouping, name {}, componentType {}", groupingName, componentType);
681 ResponseFormat responseFormat = componentsUtils.getResponseFormat(createGrouping.right().value());
682 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
683 return Either.right(responseFormat);
686 GroupingDefinition groupingCreated = createGrouping.left().value();
687 log.debug("Created grouping for component {}, name {}, uniqueId {}", componentType, groupingName, groupingCreated.getUniqueId());
688 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
689 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, groupingCreated.getName(), auditingAction, componentType);
690 return Either.left(groupingCreated);
693 public Either<List<CategoryDefinition>, ResponseFormat> getAllCategories(String componentType, String userId) {
694 AuditingActionEnum auditingAction = AuditingActionEnum.GET_CATEGORY_HIERARCHY;
695 ResponseFormat responseFormat;
696 User user = new User();
697 if (userId == null) {
698 user.setUserId("UNKNOWN");
699 responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION);
700 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat);
701 return Either.right(responseFormat);
704 Either<User, ResponseFormat> validateUser = validateUserExists(userId, "get All Categories", false);
705 if (validateUser.isRight()) {
706 user.setUserId(userId);
707 log.debug("Validation of user failed, userId {}", userId);
708 responseFormat = validateUser.right().value();
709 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat);
710 return Either.right(responseFormat);
712 user = validateUser.left().value();
714 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
715 if (componentTypeEnum == null) {
716 log.debug("Cannot create category for component type {}", componentType);
717 responseFormat = componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, "component type");
718 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat);
719 return Either.right(responseFormat);
722 NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY);
723 Either<List<CategoryDefinition>, ActionStatus> getAllCategoriesByType = elementOperation.getAllCategories(nodeTypeEnum, false);
724 if (getAllCategoriesByType.isRight()) {
725 responseFormat = componentsUtils.getResponseFormat(getAllCategoriesByType.right().value());
726 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat);
727 return Either.right(responseFormat);
729 List<CategoryDefinition> categories = getAllCategoriesByType.left().value();
730 responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
731 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat);
732 return Either.left(categories);
735 public Either<UiCategories, ResponseFormat> getAllCategories(String userId) {
736 AuditingActionEnum auditingAction = AuditingActionEnum.GET_CATEGORY_HIERARCHY;
737 ResponseFormat responseFormat;
738 UiCategories categories = new UiCategories();
740 Either<User, ResponseFormat> userResponse = validateUserExists(userId, "get all categories", false);
742 if (userResponse.isRight()) {
743 return Either.right(userResponse.right().value());
745 User user = userResponse.left().value();
747 //GET resource categories
748 Either<List<CategoryDefinition>, ActionStatus> getResourceCategoriesByType = elementOperation.getAllCategories(NodeTypeEnum.ResourceNewCategory, false);
749 if (getResourceCategoriesByType.isRight()) {
750 responseFormat = componentsUtils.getResponseFormat(getResourceCategoriesByType.right().value());
751 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, ComponentTypeEnum.RESOURCE.getValue(), responseFormat);
752 return Either.right(responseFormat);
754 categories.setResourceCategories(getResourceCategoriesByType.left().value());
756 //GET service categories
757 Either<List<CategoryDefinition>, ActionStatus> getServiceCategoriesByType = elementOperation.getAllCategories(NodeTypeEnum.ServiceNewCategory, false);
758 if (getServiceCategoriesByType.isRight()) {
759 responseFormat = componentsUtils.getResponseFormat(getServiceCategoriesByType.right().value());
760 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, ComponentTypeEnum.SERVICE.getValue(), responseFormat);
761 return Either.right(responseFormat);
763 categories.setServiceCategories(getServiceCategoriesByType.left().value());
765 //GET product categories
766 Either<List<CategoryDefinition>, ActionStatus> getProductCategoriesByType = elementOperation.getAllCategories(NodeTypeEnum.ProductCategory, false);
767 if (getProductCategoriesByType.isRight()) {
768 responseFormat = componentsUtils.getResponseFormat(getProductCategoriesByType.right().value());
769 componentsUtils.auditGetCategoryHierarchy(auditingAction, user, ComponentTypeEnum.PRODUCT.getValue(), responseFormat);
770 return Either.right(responseFormat);
773 categories.setProductCategories(getProductCategoriesByType.left().value());
774 return Either.left(categories);
778 public Either<CategoryDefinition, ResponseFormat> deleteCategory(String categoryId, String componentTypeParamName, String userId) {
780 Either<User, ResponseFormat> resp = validateUserExists(userId, "delete Category", false);
781 if (resp.isRight()) {
782 return Either.right(resp.right().value());
785 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
786 if (componentTypeEnum == null) {
787 log.debug("Cannot create category for component type {}", componentTypeParamName);
788 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
791 NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY);
793 Either<CategoryDefinition, ActionStatus> deleteCategoryByType = elementOperation.deleteCategory(nodeTypeEnum, categoryId);
794 if (deleteCategoryByType.isRight()) {
795 // auditing, logging here...
796 return Either.right(componentsUtils.getResponseFormat(deleteCategoryByType.right().value()));
798 CategoryDefinition category = deleteCategoryByType.left().value();
799 log.debug("Delete category for component {}, name {}, uniqueId {}", nodeTypeEnum, category.getName(), category.getUniqueId());
800 return Either.left(category);
803 public Either<SubCategoryDefinition, ResponseFormat> deleteSubCategory(String grandParentCategoryId, String parentSubCategoryId, String componentTypeParamName, String userId) {
805 Either<User, ResponseFormat> resp = validateUserExists(userId, "delete Sub Category", false);
806 if (resp.isRight()) {
807 return Either.right(resp.right().value());
810 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
811 if (componentTypeEnum == null) {
812 log.debug("Cannot delete sub-category for component type {}", componentTypeParamName);
813 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
816 NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY);
818 Either<SubCategoryDefinition, ActionStatus> deleteSubCategoryByType = elementOperation.deleteSubCategory(nodeTypeEnum, parentSubCategoryId);
819 if (deleteSubCategoryByType.isRight()) {
820 // auditing, logging here...
821 return Either.right(componentsUtils.getResponseFormat(deleteSubCategoryByType.right().value()));
823 SubCategoryDefinition subCategory = deleteSubCategoryByType.left().value();
824 log.debug("Deleted sub-category for component {}, name {}, uniqueId {}", nodeTypeEnum, subCategory.getName(), subCategory.getUniqueId());
825 return Either.left(subCategory);
828 public Either<GroupingDefinition, ResponseFormat> deleteGrouping(String grandParentCategoryId, String parentSubCategoryId, String groupingId, String componentTypeParamName, String userId) {
830 Either<User, ResponseFormat> resp = validateUserExists(userId, "delete Grouping", false);
831 if (resp.isRight()) {
832 return Either.right(resp.right().value());
835 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
836 if (componentTypeEnum == null) {
837 log.debug("Cannot delete grouping for component type {}", componentTypeParamName);
838 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
841 NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.GROUPING);
843 Either<GroupingDefinition, ActionStatus> deleteGroupingByType = elementOperation.deleteGrouping(nodeTypeEnum, groupingId);
844 if (deleteGroupingByType.isRight()) {
845 // auditing, logging here...
846 return Either.right(componentsUtils.getResponseFormat(deleteGroupingByType.right().value()));
848 GroupingDefinition deletedGrouping = deleteGroupingByType.left().value();
849 log.debug("Deleted grouping for component {}, name {}, uniqueId {}", nodeTypeEnum, deletedGrouping.getName(), deletedGrouping.getUniqueId());
850 return Either.left(deletedGrouping);
853 private Either<User, ResponseFormat> validateUser(String userId) {
855 // validate user exists
856 if (userId == null) {
857 log.debug("UserId is null");
858 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION));
861 Either<User, ActionStatus> userResult = userAdminManager.getUser(userId, false);
862 if (userResult.isRight()) {
863 ResponseFormat responseFormat;
864 if (userResult.right().value().equals(ActionStatus.USER_NOT_FOUND)) {
865 log.debug("Not authorized user, userId = {}", userId);
866 responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
868 log.debug("Failed to authorize user, userId = {}", userId);
869 responseFormat = componentsUtils.getResponseFormat(userResult.right().value());
872 return Either.right(responseFormat);
874 return Either.left(userResult.left().value());
875 // ========================================-
878 private Either<Boolean, ResponseFormat> validateUserRole(User user, ComponentTypeEnum componentTypeEnum) {
879 String role = user.getRole();
880 boolean validAdminAction = (role.equals(Role.ADMIN.name()) && (componentTypeEnum == ComponentTypeEnum.SERVICE || componentTypeEnum == ComponentTypeEnum.RESOURCE));
881 boolean validProductAction = (role.equals(Role.PRODUCT_STRATEGIST.name()) && (componentTypeEnum == ComponentTypeEnum.PRODUCT));
883 if (!(validAdminAction || validProductAction)) {
884 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
885 log.debug("User not permitted to perform operation on category, userId = {}, role = {}, componentType = {}", user.getUserId(), role, componentTypeEnum);
886 return Either.right(responseFormat);
888 return Either.left(true);
891 private Either<Boolean, ResponseFormat> validateComponentTypeForCategory(ComponentTypeEnum componentType, CategoryTypeEnum categoryType) {
892 boolean validResourceAction = (componentType == ComponentTypeEnum.RESOURCE && (categoryType == CategoryTypeEnum.CATEGORY || categoryType == CategoryTypeEnum.SUBCATEGORY));
893 boolean validServiceAction = (componentType == ComponentTypeEnum.SERVICE && categoryType == CategoryTypeEnum.CATEGORY);
894 boolean validProductAction = (componentType == ComponentTypeEnum.PRODUCT); // can
900 if (!(validResourceAction || validServiceAction || validProductAction)) {
901 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
902 log.debug("It's not allowed to create category type {} for component type {}", categoryType, componentType);
903 return Either.right(responseFormat);
905 return Either.left(true);
908 private Either<CategoryDefinition, ResponseFormat> validateCategoryExists(NodeTypeEnum nodeType, String categoryId, ComponentTypeEnum componentType) {
909 Either<CategoryDefinition, ActionStatus> categoryByTypeAndId = elementOperation.getCategory(nodeType, categoryId);
910 if (categoryByTypeAndId.isRight()) {
911 log.debug("Failed to fetch parent category, parent categoryId {}", categoryId);
912 ActionStatus actionStatus = categoryByTypeAndId.right().value();
913 ResponseFormat responseFormat;
914 if (actionStatus == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND) {
915 responseFormat = componentsUtils.getResponseFormat(actionStatus, componentType.getValue().toLowerCase(), CategoryTypeEnum.CATEGORY.getValue(), "");
917 responseFormat = componentsUtils.getResponseFormat(actionStatus);
919 return Either.right(responseFormat);
921 return Either.left(categoryByTypeAndId.left().value());
924 private Either<SubCategoryDefinition, ResponseFormat> validateSubCategoryExists(NodeTypeEnum nodeType, String subCategoryId, ComponentTypeEnum componentType) {
925 Either<SubCategoryDefinition, ActionStatus> subCategoryByTypeAndId = elementOperation.getSubCategory(nodeType, subCategoryId);
926 if (subCategoryByTypeAndId.isRight()) {
927 log.debug("Failed to fetch parent category, parent categoryId {}", subCategoryId);
928 ActionStatus actionStatus = subCategoryByTypeAndId.right().value();
929 ResponseFormat responseFormat;
930 if (actionStatus == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND) {
931 responseFormat = componentsUtils.getResponseFormat(actionStatus, componentType.getValue().toLowerCase(), CategoryTypeEnum.SUBCATEGORY.getValue(), "");
933 responseFormat = componentsUtils.getResponseFormat(actionStatus);
935 return Either.right(responseFormat);
937 return Either.left(subCategoryByTypeAndId.left().value());
940 private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, AuditingActionEnum auditingAction, String componentType) {
941 componentsUtils.auditCategory(responseFormat, user, category, null, null, auditingAction, componentType);
944 private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, String subCategory, AuditingActionEnum auditingAction, String componentType) {
945 componentsUtils.auditCategory(responseFormat, user, category, subCategory, null, auditingAction, componentType);
948 private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, String subCategory, String grouping, AuditingActionEnum auditingAction, String componentType) {
949 componentsUtils.auditCategory(responseFormat, user, category, subCategory, grouping, auditingAction, componentType);
953 * New categories flow - end
956 public Either<List<Tag>, ActionStatus> getAllTags(String userId) {
957 Either<User, ActionStatus> resp = validateUserExistsActionStatus(userId, "get All Tags");
958 if (resp.isRight()) {
959 return Either.right(resp.right().value());
961 return elementOperation.getAllTags();
964 public Either<List<PropertyScope>, ActionStatus> getAllPropertyScopes(String userId) {
965 Either<User, ActionStatus> resp = validateUserExistsActionStatus(userId, "get All Property Scopes");
966 if (resp.isRight()) {
967 return Either.right(resp.right().value());
969 return elementOperation.getAllPropertyScopes();
972 public Either<List<ArtifactType>, ActionStatus> getAllArtifactTypes(String userId) {
973 Either<User, ActionStatus> resp = validateUserExistsActionStatus(userId, "get All Artifact Types");
974 if (resp.isRight()) {
975 return Either.right(resp.right().value());
977 return elementOperation.getAllArtifactTypes();
980 public Either<Map<String, Object>, ActionStatus> getAllDeploymentArtifactTypes() {
981 return elementOperation.getAllDeploymentArtifactTypes();
984 public Either<Integer, ActionStatus> getDefaultHeatTimeout() {
985 return elementOperation.getDefaultHeatTimeout();
988 public Either<Map<String, List<? extends Component>>, ResponseFormat> getCatalogComponents(String userId) {
989 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Catalog Components", false);
990 if (resp.isRight()) {
991 return Either.right(resp.right().value());
993 Map<String, List<? extends Component>> resMap = new HashMap<>();
995 Either<List<Resource>, StorageOperationStatus> resResources = toscaOperationFacade.getCatalogComponents(ComponentTypeEnum.RESOURCE, true);
996 if (resResources.isLeft()) {
997 Either<List<Service>, StorageOperationStatus> resServices = toscaOperationFacade.getCatalogComponents(ComponentTypeEnum.SERVICE, true);
998 if (resServices.isLeft()) {
999 // Either<List<Product>, StorageOperationStatus> resProducts = productOperation.getProductCatalogData(false);
1000 // if (resProducts.isLeft()) {
1001 resMap.put("resources", resResources.left().value());
1002 resMap.put("services", resServices.left().value());
1003 resMap.put("products", new ArrayList<>());
1005 return Either.left(resMap);
1007 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resServices.right().value())));
1010 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resResources.right().value())));
1014 public Either<List<? extends Component>, ResponseFormat> getFilteredCatalogComponents(String assetType, Map<FilterKeyEnum, String> filters, String query) {
1015 ComponentTypeEnum assetTypeEnum = AssetTypeEnum.convertToComponentTypeEnum(assetType);
1017 if (query != null) {
1018 Optional<NameValuePair> invalidFilter = findInvalidFilter(query, assetTypeEnum);
1019 if (invalidFilter.isPresent()) {
1020 log.debug("getFilteredAssetList: invalid filter key");
1021 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_FILTER_KEY, invalidFilter.get().getName(), FilterKeyEnum.getValidFiltersByAssetType(assetTypeEnum).toString()));
1025 if (filters == null || filters.isEmpty()) {
1026 Either<List<Component>, StorageOperationStatus> componentsList = toscaOperationFacade.getCatalogComponents(assetTypeEnum, false);
1027 if(componentsList.isRight()) {
1028 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(componentsList.right().value())));
1030 return Either.left(componentsList.left().value());
1033 Either<List<Component>, StorageOperationStatus> result = getFilteredComponents(filters, assetTypeEnum, false);
1035 if (result.isRight()) {// category hierarchy mismatch or
1036 // category/subCategory/distributionStatus not
1038 List<String> params = getErrorResponseParams(filters, assetTypeEnum);
1039 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value()), params.get(0), params.get(1), params.get(2)));
1041 if (result.left().value().isEmpty()) {// no assets found for requested
1043 return Either.right(componentsUtils.getResponseFormat(ActionStatus.NO_ASSETS_FOUND, assetType, query));
1045 return Either.left(result.left().value());
1048 private Either<List<Component>, StorageOperationStatus> getFilteredComponents(Map<FilterKeyEnum, String> filters, ComponentTypeEnum assetType, boolean inTransaction) {
1049 Either<List<Component>, StorageOperationStatus> assetResult = null;
1050 if(assetType == ComponentTypeEnum.RESOURCE){
1052 assetResult = getFilteredResouces(filters, inTransaction);
1054 } else if (assetType == ComponentTypeEnum.SERVICE){
1056 assetResult = getFilteredServices(filters, inTransaction);
1061 private <T> Either<List<T>, StorageOperationStatus> getFilteredServices(Map<FilterKeyEnum, String> filters, boolean inTransaction) {
1063 Either<List<T>, StorageOperationStatus> components = null;
1065 String categoryName = filters.get(FilterKeyEnum.CATEGORY);
1066 String distributionStatus = filters.get(FilterKeyEnum.DISTRIBUTION_STATUS);
1067 DistributionStatusEnum distEnum = DistributionStatusEnum.findState(distributionStatus);
1068 if (distributionStatus != null && distEnum == null) {
1069 filters.remove(FilterKeyEnum.CATEGORY);
1070 return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
1073 if (categoryName != null) { // primary filter
1074 components = fetchByCategoryOrSubCategoryName(categoryName, NodeTypeEnum.ServiceNewCategory, GraphEdgeLabels.CATEGORY.getProperty(), NodeTypeEnum.Service, inTransaction, ServiceMetadataData.class, null);
1075 if (components.isLeft() && distEnum != null) {// secondary filter
1076 Predicate<T> statusFilter = p -> ((Service) p).getDistributionStatus().equals(distEnum);
1077 return Either.left(components.left().value().stream().filter(statusFilter).collect(Collectors.toList()));
1079 filters.remove(FilterKeyEnum.DISTRIBUTION_STATUS);
1083 Set<DistributionStatusEnum> distStatusSet = new HashSet<>();
1084 distStatusSet.add(distEnum);
1085 Either<List<Service>, StorageOperationStatus> servicesWithDistStatus = toscaOperationFacade.getServicesWithDistStatus(distStatusSet, null);
1086 if (servicesWithDistStatus.isRight()) { // not found == empty list
1087 return Either.left(new ArrayList<>());
1090 return Either.left((List<T>)servicesWithDistStatus.left().value());
1093 public Either<List<? extends Component>, ResponseFormat> getCatalogComponentsByUuidAndAssetType(String assetType, String uuid) {
1095 if (assetType == null || assetType == null) {
1096 log.debug("getCatalogComponentsByUuidAndAssetType: One of the function parameteres is null");
1097 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1100 ComponentTypeEnum assetTypeEnum = AssetTypeEnum.convertToComponentTypeEnum(assetType);
1102 if (assetTypeEnum == null) {
1103 log.debug("getCatalogComponentsByUuidAndAssetType: Corresponding ComponentTypeEnum not found");
1104 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1107 Map<GraphPropertyEnum, Object> additionalPropertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
1109 switch (assetTypeEnum) {
1111 additionalPropertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
1114 additionalPropertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
1117 log.debug("getCatalogComponentsByUuidAndAssetType: Corresponding ComponentTypeEnum not allowed for this API");
1118 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1121 Either<List<Component>, StorageOperationStatus> componentsListByUuid = toscaOperationFacade.getComponentListByUuid(uuid, additionalPropertiesToMatch);
1122 if(componentsListByUuid.isRight()) {
1123 log.debug("getCatalogComponentsByUuidAndAssetType: Service fetching failed");
1124 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(componentsListByUuid.right().value(), ComponentTypeEnum.SERVICE);
1125 return Either.right(componentsUtils.getResponseFormat(actionStatus, uuid));
1128 log.debug("getCatalogComponentsByUuidAndAssetType: " + assetTypeEnum.getValue() + "Service fetching successful");
1129 return Either.left(componentsListByUuid.left().value());
1132 public List<String> getAllComponentTypesParamNames() {
1133 List<String> paramNames = new ArrayList<>();
1134 paramNames.add(ComponentTypeEnum.SERVICE_PARAM_NAME);
1135 paramNames.add(ComponentTypeEnum.RESOURCE_PARAM_NAME);
1136 paramNames.add(ComponentTypeEnum.PRODUCT_PARAM_NAME);
1140 public List<String> getAllSupportedRoles() {
1141 Role[] values = Role.values();
1142 List<String> roleNames = new ArrayList<>();
1143 for (Role role : values) {
1144 roleNames.add(role.name());
1149 public Either<Map<String, String>, ActionStatus> getResourceTypesMap() {
1150 return elementOperation.getResourceTypesMap();
1153 private Optional<NameValuePair> findInvalidFilter(String query, ComponentTypeEnum assetType) {
1154 List<NameValuePair> params = URLEncodedUtils.parse(query, StandardCharsets.UTF_8);
1155 List<String> validKeys = FilterKeyEnum.getValidFiltersByAssetType(assetType);
1156 Predicate<NameValuePair> noMatch = p -> !validKeys.contains(p.getName());
1157 return params.stream().filter(noMatch).findAny();
1160 private List<String> getErrorResponseParams(Map<FilterKeyEnum, String> filters, ComponentTypeEnum assetType) {
1161 List<String> params = new ArrayList<String>();
1162 if (1 == filters.size()) {
1163 params.add(assetType.getValue().toLowerCase());
1164 params.add(filters.keySet().iterator().next().getName());
1165 params.add(filters.values().iterator().next());
1167 params.add(assetType.getValue());
1168 params.add(filters.get(FilterKeyEnum.SUB_CATEGORY));
1169 params.add(filters.get(FilterKeyEnum.CATEGORY));
1174 public Either<List<Component>, StorageOperationStatus> getFilteredResouces(Map<FilterKeyEnum, String> filters, boolean inTransaction) {
1176 String subCategoryName = filters.get(FilterKeyEnum.SUB_CATEGORY);
1177 String categoryName = filters.get(FilterKeyEnum.CATEGORY);
1178 ResourceTypeEnum resourceType = ResourceTypeEnum.getType( filters.get(FilterKeyEnum.RESOURCE_TYPE));
1179 Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, StorageOperationStatus> subcategories = null;
1180 Optional<ImmutablePair<SubCategoryData, GraphEdge>> subCategoryData;
1182 if (categoryName != null) {
1183 subcategories = getAllSubCategories(categoryName);
1184 if (subcategories.isRight()) {
1185 filters.remove(FilterKeyEnum.SUB_CATEGORY);
1186 return Either.right(subcategories.right().value());
1189 if (subCategoryName != null) { // primary filter
1190 if (categoryName != null) {
1191 subCategoryData = validateCategoryHierarcy(subcategories.left().value(), subCategoryName);
1192 if (!subCategoryData.isPresent()) {
1193 return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1195 return fetchByCategoryOrSubCategoryUid((String) subCategoryData.get().getLeft().getUniqueId(), NodeTypeEnum.ResourceSubcategory, GraphEdgeLabels.SUB_CATEGORY.getProperty(), NodeTypeEnum.Resource, inTransaction,
1196 ResourceMetadataData.class, resourceType);
1199 return fetchByCategoryOrSubCategoryName(subCategoryName, NodeTypeEnum.ResourceSubcategory, GraphEdgeLabels.SUB_CATEGORY.getProperty(), NodeTypeEnum.Resource, inTransaction, ResourceMetadataData.class, resourceType);
1201 if(subcategories != null){
1202 return fetchByMainCategory(subcategories.left().value(), inTransaction, resourceType);
1204 return fetchByResourceType(filters.get(FilterKeyEnum.RESOURCE_TYPE), inTransaction);
1207 private Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, StorageOperationStatus> getAllSubCategories(String categoryName) {
1208 Either<CategoryData, StorageOperationStatus> categoryResult = elementOperation.getNewCategoryData(categoryName, NodeTypeEnum.ResourceNewCategory, CategoryData.class);
1209 if (categoryResult.isRight()) {
1210 return Either.right(categoryResult.right().value());
1212 CategoryData categoryData = categoryResult.left().value();
1214 Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceNewCategory), (String) categoryData.getUniqueId(),
1215 GraphEdgeLabels.SUB_CATEGORY, NodeTypeEnum.ResourceSubcategory, SubCategoryData.class);
1216 if (childrenNodes.isRight()) {
1217 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenNodes.right().value()));
1219 return Either.left(childrenNodes.left().value());
1222 private Optional<ImmutablePair<SubCategoryData, GraphEdge>> validateCategoryHierarcy(List<ImmutablePair<SubCategoryData, GraphEdge>> childNodes, String subCategoryName) {
1223 Predicate<ImmutablePair<SubCategoryData, GraphEdge>> matchName = p -> p.getLeft().getSubCategoryDataDefinition().getName().equals(subCategoryName);
1224 return childNodes.stream().filter(matchName).findAny();
1227 protected <T, S extends ComponentMetadataData> Either<List<T>, StorageOperationStatus> fetchByCategoryOrSubCategoryUid(String categoryUid, NodeTypeEnum categoryType, String categoryLabel, NodeTypeEnum neededType, boolean inTransaction,
1228 Class<S> clazz, ResourceTypeEnum resourceType) {
1230 Either<TitanGraph, TitanOperationStatus> graph = titanDao.getGraph();
1231 if (graph.isRight()) {
1232 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value()));
1235 return collectComponents(graph.left().value(), neededType, categoryUid, categoryType, clazz, resourceType);
1238 if (false == inTransaction) {
1244 protected <T, S extends ComponentMetadataData> Either<List<T>, StorageOperationStatus> fetchByCategoryOrSubCategoryName(String categoryName, NodeTypeEnum categoryType, String categoryLabel, NodeTypeEnum neededType, boolean inTransaction,
1245 Class<S> clazz, ResourceTypeEnum resourceType) {
1246 List<T> components = new ArrayList<>();
1248 Class categoryClazz = categoryType == NodeTypeEnum.ServiceNewCategory ? CategoryData.class : SubCategoryData.class;
1249 Map<String, Object> props = new HashMap<String, Object>();
1250 props.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), ValidationUtils.normalizeCategoryName4Uniqueness(categoryName));
1251 Either<List<GraphNode>, TitanOperationStatus> getCategory = titanGenericDao.getByCriteria(categoryType, props, categoryClazz);
1252 if (getCategory.isRight()) {
1253 return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
1255 Either<TitanGraph, TitanOperationStatus> graph = titanDao.getGraph();
1256 if (graph.isRight()) {
1257 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value()));
1260 for (GraphNode category : getCategory.left().value()) {
1261 Either<List<T>, StorageOperationStatus> result = collectComponents(graph.left().value(), neededType, (String) category.getUniqueId(), categoryType, clazz, resourceType);
1262 if (result.isRight()) {
1265 components.addAll(result.left().value());
1268 return Either.left(components);
1270 if (false == inTransaction) {
1276 private <T, S extends ComponentMetadataData> Either<List<T>, StorageOperationStatus> collectComponents(TitanGraph graph, NodeTypeEnum neededType, String categoryUid, NodeTypeEnum categoryType, Class<S> clazz, ResourceTypeEnum resourceType) {
1277 List<T> components = new ArrayList<>();
1278 Either<List<ImmutablePair<S, GraphEdge>>, TitanOperationStatus> parentNodes = titanGenericDao.getParentNodes(UniqueIdBuilder.getKeyByNodeType(categoryType), categoryUid, GraphEdgeLabels.CATEGORY, neededType, clazz);
1279 if (parentNodes.isLeft()) {
1280 for (ImmutablePair<S, GraphEdge> component : parentNodes.left().value()) {
1281 ComponentMetadataDataDefinition componentData = component.getLeft().getMetadataDataDefinition();
1282 Boolean isHighest = componentData.isHighestVersion();
1283 boolean isMatchingResourceType = isMatchingByResourceType(neededType, resourceType, componentData);
1285 if (isHighest && isMatchingResourceType) {
1286 Either<T, StorageOperationStatus> result = (Either<T, StorageOperationStatus>) toscaOperationFacade.getToscaElement(componentData.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
1287 if (result.isRight()) {
1288 return Either.right(result.right().value());
1290 components.add(result.left().value());
1294 return Either.left(components);
1297 private boolean isMatchingByResourceType(NodeTypeEnum componentType, ResourceTypeEnum resourceType,
1298 ComponentMetadataDataDefinition componentData) {
1301 if (componentType == NodeTypeEnum.Resource) {
1302 if (resourceType == null) {
1305 isMatching = resourceType == ((ResourceMetadataDataDefinition)componentData).getResourceType();
1313 private <T> Either<List<T>, StorageOperationStatus> fetchByMainCategory(List<ImmutablePair<SubCategoryData, GraphEdge>> subcategories, boolean inTransaction, ResourceTypeEnum resourceType) {
1314 List<T> components = new ArrayList<>();
1316 for (ImmutablePair<SubCategoryData, GraphEdge> subCategory : subcategories) {
1317 Either<List<T>, StorageOperationStatus> fetched = fetchByCategoryOrSubCategoryUid((String) subCategory.getLeft().getUniqueId(), NodeTypeEnum.ResourceSubcategory, GraphEdgeLabels.SUB_CATEGORY.getProperty(), NodeTypeEnum.Resource,
1318 inTransaction, ResourceMetadataData.class, resourceType);
1319 if (fetched.isRight()) {
1323 components.addAll(fetched.left().value());
1325 return Either.left(components);
1328 private Either<List<Component>, StorageOperationStatus> fetchByResourceType(String resourceType, boolean inTransaction) {
1329 List<Component> components = null;
1330 StorageOperationStatus status;
1331 Wrapper<StorageOperationStatus> statusWrapper = new Wrapper<>();
1332 Either<List<Component>, StorageOperationStatus> result;
1335 Either<List<Component>, StorageOperationStatus> getResources = toscaOperationFacade.fetchByResourceType(resourceType); //titanGenericDao.getByCriteria(nodeType, props, clazz);
1336 if (getResources.isRight()) {
1337 status = getResources.right().value();
1338 if(status != StorageOperationStatus.NOT_FOUND){
1339 statusWrapper.setInnerElement(getResources.right().value());
1341 components = new ArrayList<>();
1344 components = getResources.left().value();
1346 if(!statusWrapper.isEmpty()){
1347 result = Either.right(statusWrapper.getInnerElement());
1349 result = Either.left(components);
1353 if (!inTransaction) {
1359 Component convertComponentMetadataDataToComponent(ComponentMetadataData componentMetadataData) {
1360 return convertResourceDataToResource((ResourceMetadataData) componentMetadataData);
1362 private Resource convertResourceDataToResource(ResourceMetadataData resourceData) {
1364 ResourceMetadataDefinition resourceMetadataDataDefinition = new ResourceMetadataDefinition((ResourceMetadataDataDefinition) resourceData.getMetadataDataDefinition());
1366 Resource resource = new Resource(resourceMetadataDataDefinition);
1370 private <T> Either<List<T>, StorageOperationStatus> fetchByDistributionStatus(String status, boolean inTransaction) {
1371 Map<String, Object> props = new HashMap<String, Object>();
1372 props.put(GraphPropertiesDictionary.DISTRIBUTION_STATUS.getProperty(), status);
1373 props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true);
1374 return (Either<List<T>, StorageOperationStatus>) (Either<?, StorageOperationStatus>) getServiceListByCriteria(props, inTransaction);
1377 private Either<List<Service>, StorageOperationStatus> getServiceListByCriteria(Map<String, Object> props, boolean inTransaction) {
1378 props.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Service.getName());
1379 Either<List<ServiceMetadataData>, TitanOperationStatus> byCriteria = titanGenericDao.getByCriteria(NodeTypeEnum.Service, props, ServiceMetadataData.class);
1381 if (byCriteria.isRight()) {
1382 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value()));
1384 List<Service> services = new ArrayList<Service>();
1385 List<ServiceMetadataData> servicesDataList = byCriteria.left().value();
1386 for (ServiceMetadataData data : servicesDataList) {
1387 Either<Component, StorageOperationStatus> service = toscaOperationFacade.getToscaElement(data.getMetadataDataDefinition().getUniqueId());
1388 if (service.isLeft()) {
1389 services.add((Service)service.left().value());
1391 log.debug("Failed to fetch resource for name = {} and id = {}",data.getMetadataDataDefinition().getName(),data.getUniqueId());
1394 return Either.left(services);