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=========================================================
19 * Modifications copyright (c) 2019 Nokia
20 * ================================================================================
22 package org.openecomp.sdc.be.components.impl;
24 import static org.apache.commons.lang.BooleanUtils.isTrue;
25 import static org.openecomp.sdc.be.components.impl.ImportUtils.Constants.DEFAULT_ICON;
27 import fj.data.Either;
28 import java.nio.charset.StandardCharsets;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.EnumMap;
32 import java.util.HashMap;
33 import java.util.HashSet;
34 import java.util.LinkedList;
35 import java.util.List;
37 import java.util.Objects;
38 import java.util.Optional;
40 import java.util.function.Predicate;
41 import java.util.regex.Matcher;
42 import java.util.regex.Pattern;
43 import java.util.stream.Collectors;
44 import org.apache.commons.collections4.CollectionUtils;
45 import org.apache.commons.collections4.MapUtils;
46 import org.apache.commons.lang3.StringUtils;
47 import org.apache.commons.lang3.tuple.ImmutablePair;
48 import org.apache.http.NameValuePair;
49 import org.apache.http.client.utils.URLEncodedUtils;
50 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
51 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
52 import org.openecomp.sdc.be.config.Configuration;
53 import org.openecomp.sdc.be.dao.api.ActionStatus;
54 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
55 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
56 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
57 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
58 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
59 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
60 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
61 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
62 import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum;
63 import org.openecomp.sdc.be.datamodel.utils.NodeTypeConvertUtils;
64 import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition;
65 import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition;
66 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
67 import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum;
68 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
69 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
70 import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
71 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
72 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
73 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
74 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
75 import org.openecomp.sdc.be.externalapi.servlet.representation.VersionFilterEnum;
76 import org.openecomp.sdc.be.model.ArtifactType;
77 import org.openecomp.sdc.be.model.BaseType;
78 import org.openecomp.sdc.be.model.CatalogUpdateTimestamp;
79 import org.openecomp.sdc.be.model.Component;
80 import org.openecomp.sdc.be.model.ComponentParametersView;
81 import org.openecomp.sdc.be.model.DistributionStatusEnum;
82 import org.openecomp.sdc.be.model.LifecycleStateEnum;
83 import org.openecomp.sdc.be.model.Product;
84 import org.openecomp.sdc.be.model.PropertyScope;
85 import org.openecomp.sdc.be.model.Resource;
86 import org.openecomp.sdc.be.model.Service;
87 import org.openecomp.sdc.be.model.Tag;
88 import org.openecomp.sdc.be.model.User;
89 import org.openecomp.sdc.be.model.catalog.CatalogComponent;
90 import org.openecomp.sdc.be.model.category.CategoryDefinition;
91 import org.openecomp.sdc.be.model.category.GroupingDefinition;
92 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
93 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
94 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
95 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
96 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
97 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
98 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
99 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
100 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
101 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
102 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
103 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
104 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
105 import org.openecomp.sdc.be.resources.data.category.CategoryData;
106 import org.openecomp.sdc.be.resources.data.category.SubCategoryData;
107 import org.openecomp.sdc.be.ui.model.UiCategories;
108 import org.openecomp.sdc.be.user.Role;
109 import org.openecomp.sdc.be.user.UserBusinessLogic;
110 import org.openecomp.sdc.common.datastructure.Wrapper;
111 import org.openecomp.sdc.common.log.wrappers.Logger;
112 import org.openecomp.sdc.common.util.ValidationUtils;
113 import org.openecomp.sdc.exception.ResponseFormat;
114 import org.springframework.beans.factory.annotation.Autowired;
116 @org.springframework.stereotype.Component("elementsBusinessLogic")
117 public class ElementBusinessLogic extends BaseBusinessLogic {
119 private static final Logger log = Logger.getLogger(ElementBusinessLogic.class);
120 private static final String SERVICES = "services";
121 private static final String RESOURCES = "resources";
122 private static final String VALIDATION_OF_USER_FAILED_USER_ID = "Validation of user failed, userId {}";
123 private static final String COMPONENT_TYPE_IS_INVALID = "Component type {} is invalid";
124 private static final String VALIDATION_OF_USER_ROLE_FAILED_USER_ID = "Validation of user role failed, userId {}";
125 private final IElementOperation elementOperation;
128 public ElementBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
129 IGroupTypeOperation groupTypeOperation, GroupBusinessLogic groupBusinessLogic, InterfaceOperation interfaceOperation,
130 InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsOperations artifactToscaOperation,
131 IElementOperation elementOperation, UserBusinessLogic userAdminManager) {
132 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
133 artifactToscaOperation);
134 this.elementOperation = elementOperation;
141 public Either<Map<String, List<? extends Component>>, ResponseFormat> getFollowed(User user) {
142 // Used for not getting duplicated followed. Cheaper than checking ArrayList.contains
143 Either<Map<String, Set<? extends Component>>, ResponseFormat> response = null;
145 String role = user.getRole();
146 String userId = user.getUserId();
147 Role currentRole = Role.valueOf(role);
148 switch (currentRole) {
150 response = handleDesigner(userId);
152 case PRODUCT_STRATEGIST:
153 response = handleProductStrategist();
155 case PRODUCT_MANAGER:
156 response = handleProductManager(userId);
159 response = handleAdmin();
162 response = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
165 // 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)
166 return convertedToListResponse(response);
169 private Either<Map<String, List<? extends Component>>, ResponseFormat> convertedToListResponse(
170 Either<Map<String, Set<? extends Component>>, ResponseFormat> setResponse) {
171 Map<String, List<? extends Component>> arrayResponse = new HashMap<>();
172 if (setResponse.isLeft()) {
173 for (Map.Entry<String, Set<? extends Component>> entry : setResponse.left().value().entrySet()) {
174 arrayResponse.put(entry.getKey(), new ArrayList(new HashSet(entry.getValue())));
176 return Either.left(arrayResponse);
178 return Either.right(setResponse.right().value());
181 private Either<Map<String, Set<? extends Component>>, ResponseFormat> handleAdmin() {
182 Either<Map<String, Set<? extends Component>>, ResponseFormat> response;
183 // userId should stay null
184 Set<LifecycleStateEnum> lifecycleStates = new HashSet<>();
185 lifecycleStates.add(LifecycleStateEnum.CERTIFIED);
186 response = getFollowedResourcesAndServices(null, lifecycleStates, new HashSet<>());
190 private Either<Map<String, Set<? extends Component>>, ResponseFormat> handleDesigner(String userId) {
191 Set<LifecycleStateEnum> lifecycleStates = new HashSet<>();
192 Set<LifecycleStateEnum> lastStateStates = new HashSet<>();
193 Either<Map<String, Set<? extends Component>>, ResponseFormat> response;
194 lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
195 lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
196 lifecycleStates.add(LifecycleStateEnum.CERTIFIED);
198 lastStateStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
199 response = getFollowedResourcesAndServices(userId, lifecycleStates, lastStateStates);
203 private Either<Map<String, Set<? extends Component>>, ResponseFormat> handleProductStrategist() {
204 // Should be empty list according to Ella, 13/03/16
205 Map<String, Set<? extends Component>> result = new HashMap<>();
206 result.put("products", new HashSet<>());
207 return Either.left(result);
210 private Either<Map<String, Set<? extends Component>>, ResponseFormat> handleProductManager(String userId) {
211 Set<LifecycleStateEnum> lifecycleStates = new HashSet<>();
212 Set<LifecycleStateEnum> lastStateStates = new HashSet<>();
213 Either<Map<String, Set<? extends Component>>, ResponseFormat> response;
214 lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
215 lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
216 lifecycleStates.add(LifecycleStateEnum.CERTIFIED);
218 lastStateStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
219 response = getFollowedProducts(userId, lifecycleStates, lastStateStates);
223 private Either<Map<String, Set<? extends Component>>, ResponseFormat> getFollowedResourcesAndServices(String userId,
224 Set<LifecycleStateEnum> lifecycleStates,
225 Set<LifecycleStateEnum> lastStateStates) {
227 Either<Set<Resource>, StorageOperationStatus> resources = toscaOperationFacade
228 .getFollowed(userId, lifecycleStates, lastStateStates, ComponentTypeEnum.RESOURCE);
229 if (resources.isLeft()) {
230 Either<Set<Service>, StorageOperationStatus> services = toscaOperationFacade
231 .getFollowed(userId, lifecycleStates, lastStateStates, ComponentTypeEnum.SERVICE);
232 if (services.isLeft()) {
233 Map<String, Set<? extends Component>> result = new HashMap<>();
234 result.put(SERVICES, services.left().value());
235 result.put(RESOURCES, resources.left().value());
236 return Either.left(result);
238 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(services.right().value())));
241 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resources.right().value())));
244 janusGraphDao.commit();
248 private Either<Map<String, Set<? extends Component>>, ResponseFormat> getFollowedProducts(String userId, Set<LifecycleStateEnum> lifecycleStates,
249 Set<LifecycleStateEnum> lastStateStates) {
250 Either<Set<Product>, StorageOperationStatus> products = toscaOperationFacade
251 .getFollowed(userId, lifecycleStates, lastStateStates, ComponentTypeEnum.PRODUCT);
252 if (products.isLeft()) {
253 Map<String, Set<? extends Component>> result = new HashMap<>();
254 result.put("products", products.left().value());
255 return Either.left(result);
257 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(products.right().value())));
262 * New categories flow - start
264 public Either<List<CategoryDefinition>, ActionStatus> getAllResourceCategories() {
265 return elementOperation.getAllResourceCategories();
269 public Either<CategoryDefinition, ResponseFormat> createCategory(CategoryDefinition category, String componentTypeParamName, String userId) {
270 AuditingActionEnum auditingAction = AuditingActionEnum.ADD_CATEGORY;
271 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
272 String componentType = componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue();
273 CategoryTypeEnum categoryType = CategoryTypeEnum.CATEGORY;
274 User user = validateUserExists(userId);
275 if (category == null) {
276 log.debug("Category json is invalid");
277 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
278 handleCategoryAuditing(responseFormat, user, null, auditingAction, componentType);
279 return Either.right(responseFormat);
281 String categoryName = category.getName();
282 // For auditing of failures we need the original non-normalized name
283 String origCategoryName = categoryName;
284 if (componentTypeEnum == null) {
285 log.debug(COMPONENT_TYPE_IS_INVALID, componentTypeParamName);
286 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
287 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
288 return Either.right(responseFormat);
290 Either<Boolean, ResponseFormat> validateUserRole = validateUserRole(user, componentTypeEnum);
291 if (validateUserRole.isRight()) {
292 log.debug(VALIDATION_OF_USER_ROLE_FAILED_USER_ID, userId);
293 ResponseFormat responseFormat = validateUserRole.right().value();
294 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
295 return Either.right(responseFormat);
297 if (!ValidationUtils.validateCategoryDisplayNameFormat(categoryName)) {
298 log.debug("Category display name format is invalid, name {}, componentType {}", categoryName, componentType);
299 ResponseFormat responseFormat = componentsUtils
300 .getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue());
301 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
302 return Either.right(responseFormat);
304 categoryName = ValidationUtils.normalizeCategoryName4Display(categoryName);
305 if (!ValidationUtils.validateCategoryDisplayNameLength(categoryName)) {
306 log.debug("Category display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", categoryName,
308 ResponseFormat responseFormat = componentsUtils
309 .getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue());
310 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
311 return Either.right(responseFormat);
313 category.setName(categoryName);
314 String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(categoryName);
315 category.setNormalizedName(normalizedName);
316 if (ValidationUtils.validateCategoryIconNotEmpty(category.getIcons())) {
317 log.debug("createCategory: setting category icon to default icon since service category was created without an icon ");
318 category.setIcons(Arrays.asList(DEFAULT_ICON));
320 NodeTypeEnum nodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, categoryType);
321 Either<Boolean, ActionStatus> categoryUniqueEither = elementOperation.isCategoryUniqueForType(nodeType, normalizedName);
322 if (categoryUniqueEither.isRight()) {
323 log.debug("Failed to check category uniqueness, name {}, componentType {}", categoryName, componentType);
324 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categoryUniqueEither.right().value());
325 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
326 return Either.right(responseFormat);
328 Boolean isCategoryUnique = categoryUniqueEither.left().value();
329 if (Boolean.FALSE.equals(isCategoryUnique)) {
330 log.debug("Category is not unique, name {}, componentType {}", categoryName, componentType);
331 ResponseFormat responseFormat = componentsUtils
332 .getResponseFormat(ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, componentType, categoryName);
333 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
334 return Either.right(responseFormat);
336 Either<CategoryDefinition, ActionStatus> createCategoryByType = elementOperation.createCategory(category, nodeType);
337 if (createCategoryByType.isRight()) {
338 log.debug("Failed to create category, name {}, componentType {}", categoryName, componentType);
339 ResponseFormat responseFormat = componentsUtils
340 .getResponseFormat(ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, componentType, categoryName);
341 handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType);
342 return Either.right(componentsUtils.getResponseFormat(createCategoryByType.right().value()));
344 category = createCategoryByType.left().value();
345 log.debug("Created category for component {}, name {}, uniqueId {}", componentType, categoryName, category.getUniqueId());
346 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
347 handleCategoryAuditing(responseFormat, user, category.getName(), auditingAction, componentType);
348 return Either.left(category);
351 public Either<SubCategoryDefinition, ResponseFormat> createSubCategory(SubCategoryDefinition subCategory, String componentTypeParamName,
352 String parentCategoryId, String userId) {
353 AuditingActionEnum auditingAction = AuditingActionEnum.ADD_SUB_CATEGORY;
354 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
355 String componentType = componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue();
356 CategoryTypeEnum categoryType = CategoryTypeEnum.SUBCATEGORY;
358 String parentCategoryName = parentCategoryId;
359 if (subCategory == null) {
360 log.debug("Sub-category json is invalid");
361 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
362 handleCategoryAuditing(responseFormat, null, parentCategoryName, null, auditingAction, componentType);
363 return Either.right(responseFormat);
365 String subCategoryName = subCategory.getName();
366 // For auditing of failures we need the original non-normalized name
367 String origSubCategoryName = subCategoryName;
370 user = validateUserExists(userId);
371 } catch (ByActionStatusComponentException e) {
372 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
373 handleComponentException(userId, auditingAction, componentType, parentCategoryName, origSubCategoryName, responseFormat);
375 } catch (ByResponseFormatComponentException e) {
376 ResponseFormat responseFormat = e.getResponseFormat();
377 handleComponentException(userId, auditingAction, componentType, parentCategoryName, origSubCategoryName, responseFormat);
380 if (componentTypeEnum == null) {
381 log.debug(COMPONENT_TYPE_IS_INVALID, componentTypeParamName);
382 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
383 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
384 return Either.right(responseFormat);
386 Either<Boolean, ResponseFormat> validateComponentType = validateComponentTypeForCategory(componentTypeEnum, categoryType);
387 if (validateComponentType.isRight()) {
388 log.debug("Validation of component type for sub-category failed");
389 ResponseFormat responseFormat = validateComponentType.right().value();
390 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
391 return Either.right(responseFormat);
393 Either<Boolean, ResponseFormat> validateUserRole = validateUserRole(user, componentTypeEnum);
394 if (validateUserRole.isRight()) {
395 log.debug(VALIDATION_OF_USER_ROLE_FAILED_USER_ID, userId);
396 ResponseFormat responseFormat = validateUserRole.right().value();
397 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
398 return Either.right(responseFormat);
400 NodeTypeEnum parentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY);
401 NodeTypeEnum childNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY);
402 CategoryDefinition categoryDefinition;
403 Either<CategoryDefinition, ResponseFormat> validateCategoryExists = validateCategoryExists(parentNodeType, parentCategoryId,
405 if (validateCategoryExists.isRight()) {
406 log.debug("Validation of parent category exists failed, parent categoryId {}", parentCategoryId);
407 ResponseFormat responseFormat = validateCategoryExists.right().value();
408 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
409 return Either.right(responseFormat);
411 categoryDefinition = validateCategoryExists.left().value();
412 parentCategoryName = categoryDefinition.getName();
413 if (!ValidationUtils.validateCategoryDisplayNameFormat(subCategoryName)) {
414 log.debug("Sub-category display name format is invalid, name {}, componentType {}", subCategoryName, componentType);
415 ResponseFormat responseFormat = componentsUtils
416 .getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue());
417 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
418 return Either.right(responseFormat);
420 subCategoryName = ValidationUtils.normalizeCategoryName4Display(subCategoryName);
421 if (!ValidationUtils.validateCategoryDisplayNameLength(subCategoryName)) {
422 log.debug("Sub-category display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", subCategoryName,
424 ResponseFormat responseFormat = componentsUtils
425 .getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue());
426 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
427 return Either.right(responseFormat);
429 String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(subCategoryName);
430 subCategory.setNormalizedName(normalizedName);
431 // Uniqueness under this category
432 Either<Boolean, ActionStatus> subCategoryUniqueForCategory = elementOperation
433 .isSubCategoryUniqueForCategory(childNodeType, normalizedName, parentCategoryId);
434 if (subCategoryUniqueForCategory.isRight()) {
435 log.debug("Failed to check sub-category uniqueness, parent name {}, subcategory norm name {}, componentType {}", parentCategoryName,
436 normalizedName, componentType);
437 ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForCategory.right().value());
438 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
439 return Either.right(responseFormat);
441 Boolean isSubUnique = subCategoryUniqueForCategory.left().value();
442 if (Boolean.FALSE.equals(isSubUnique)) {
443 log.debug("Sub-category is not unique for category, parent name {}, subcategory norm name {}, componentType {}", parentCategoryName,
444 normalizedName, componentType);
445 ResponseFormat responseFormat = componentsUtils
446 .getResponseFormat(ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY, componentType, subCategoryName, parentCategoryName);
447 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
448 return Either.right(responseFormat);
450 // Setting name of subcategory to fit the similar subcategory name
454 // For example if Network-->kUKU exists for service category Network,
456 // and user is trying to create Router-->Kuku for service category
460 // his subcategory name will be Router-->kUKU.
461 Either<SubCategoryDefinition, ActionStatus> subCategoryUniqueForType = elementOperation
462 .getSubCategoryUniqueForType(childNodeType, normalizedName);
463 if (subCategoryUniqueForType.isRight()) {
464 log.debug("Failed validation of whether similar sub-category exists, normalizedName {} componentType {}", normalizedName, componentType);
465 ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForType.right().value());
466 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
467 return Either.right(responseFormat);
469 SubCategoryDefinition subCategoryDefinition = subCategoryUniqueForType.left().value();
470 if (subCategoryDefinition != null) {
471 subCategoryName = subCategoryDefinition.getName();
473 subCategory.setName(subCategoryName);
474 ///////////////////////////////////////////// Validations end
475 Either<SubCategoryDefinition, ActionStatus> createSubCategory = elementOperation
476 .createSubCategory(parentCategoryId, subCategory, childNodeType);
477 if (createSubCategory.isRight()) {
478 log.debug("Failed to create sub-category, name {}, componentType {}", subCategoryName, componentType);
479 ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForType.right().value());
480 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
481 return Either.right(responseFormat);
483 SubCategoryDefinition subCategoryCreated = createSubCategory.left().value();
484 log.debug("Created sub-category for component {}, name {}, uniqueId {}", componentType, subCategoryName, subCategoryCreated.getUniqueId());
485 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
486 handleCategoryAuditing(responseFormat, user, parentCategoryName, subCategoryCreated.getName(), auditingAction, componentType);
487 return Either.left(subCategoryCreated);
490 private void handleComponentException(String userId, AuditingActionEnum auditingAction, String componentType, String parentCategoryName,
491 String origSubCategoryName, ResponseFormat responseFormat) {
493 log.debug(VALIDATION_OF_USER_FAILED_USER_ID, userId);
495 user.setUserId(userId);
496 handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType);
499 private void handleComponentException(GroupingDefinition grouping, String userId, AuditingActionEnum auditingAction, String componentType,
500 String parentCategoryName, String parentSubCategoryName, ResponseFormat responseFormat) {
502 log.debug(VALIDATION_OF_USER_FAILED_USER_ID, userId);
504 user.setUserId(userId);
505 String groupingNameForAudit = grouping == null ? null : grouping.getName();
506 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, groupingNameForAudit, auditingAction, componentType);
509 private void handleComponentException(String componentType, String userId, ResponseFormat responseFormat) {
512 user.setUserId(userId);
513 log.debug(VALIDATION_OF_USER_FAILED_USER_ID, userId);
514 componentsUtils.auditGetCategoryHierarchy(user, componentType, responseFormat);
517 public Either<GroupingDefinition, ResponseFormat> createGrouping(GroupingDefinition grouping, String componentTypeParamName,
518 String grandParentCategoryId, String parentSubCategoryId, String userId) {
519 AuditingActionEnum auditingAction = AuditingActionEnum.ADD_GROUPING;
520 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
521 String componentType = componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue();
522 CategoryTypeEnum categoryType = CategoryTypeEnum.GROUPING;
524 String parentCategoryName = grandParentCategoryId;
525 String parentSubCategoryName = parentSubCategoryId;
528 user = validateUserExists(userId);
529 } catch (ByResponseFormatComponentException e) {
530 ResponseFormat responseFormat = e.getResponseFormat();
531 handleComponentException(grouping, userId, auditingAction, componentType, parentCategoryName, parentSubCategoryName, responseFormat);
533 } catch (ByActionStatusComponentException e) {
534 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
535 handleComponentException(grouping, userId, auditingAction, componentType, parentCategoryName, parentSubCategoryName, responseFormat);
538 if (grouping == null) {
539 log.debug("Grouping json is invalid");
540 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
541 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, null, auditingAction, componentType);
542 return Either.right(responseFormat);
544 String groupingName = grouping.getName();
545 // For auditing of failures we need the original non-normalized name
546 String origGroupingName = groupingName;
547 if (componentTypeEnum == null) {
548 log.debug(COMPONENT_TYPE_IS_INVALID, componentTypeParamName);
549 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
550 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
551 return Either.right(responseFormat);
553 Either<Boolean, ResponseFormat> validateComponentType = validateComponentTypeForCategory(componentTypeEnum, categoryType);
554 if (validateComponentType.isRight()) {
555 log.debug("Validation of component type for grouping failed");
556 ResponseFormat responseFormat = validateComponentType.right().value();
557 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
558 return Either.right(responseFormat);
560 Either<Boolean, ResponseFormat> validateUserRole = validateUserRole(user, componentTypeEnum);
561 if (validateUserRole.isRight()) {
562 log.debug(VALIDATION_OF_USER_ROLE_FAILED_USER_ID, userId);
563 ResponseFormat responseFormat = validateUserRole.right().value();
564 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
565 return Either.right(responseFormat);
567 NodeTypeEnum grandParentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY);
568 NodeTypeEnum parentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY);
569 NodeTypeEnum childNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.GROUPING);
571 CategoryDefinition categoryDefinition;
572 Either<CategoryDefinition, ResponseFormat> validateCategoryExists = validateCategoryExists(grandParentNodeType, grandParentCategoryId,
574 if (validateCategoryExists.isRight()) {
575 log.debug("Validation of parent category exists failed, parent categoryId {}", grandParentCategoryId);
576 ResponseFormat responseFormat = validateCategoryExists.right().value();
577 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
578 return Either.right(responseFormat);
580 categoryDefinition = validateCategoryExists.left().value();
581 parentCategoryName = categoryDefinition.getName();
582 // Validate subcategory
583 SubCategoryDefinition subCategoryDefinition;
584 Either<SubCategoryDefinition, ResponseFormat> validateSubCategoryExists = validateSubCategoryExists(parentNodeType, parentSubCategoryId,
586 if (validateSubCategoryExists.isRight()) {
587 log.debug("Validation of parent sub-category exists failed, parent sub-category id {}", parentSubCategoryId);
588 ResponseFormat responseFormat = validateSubCategoryExists.right().value();
589 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
590 return Either.right(responseFormat);
592 subCategoryDefinition = validateSubCategoryExists.left().value();
593 parentSubCategoryName = subCategoryDefinition.getName();
594 if (!ValidationUtils.validateCategoryDisplayNameFormat(groupingName)) {
595 log.debug("Sub-category display name format is invalid, name {}, componentType {}", groupingName, componentType);
596 ResponseFormat responseFormat = componentsUtils
597 .getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue());
598 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
599 return Either.right(responseFormat);
601 groupingName = ValidationUtils.normalizeCategoryName4Display(groupingName);
602 if (!ValidationUtils.validateCategoryDisplayNameLength(groupingName)) {
603 log.debug("Grouping display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", groupingName,
605 ResponseFormat responseFormat = componentsUtils
606 .getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue());
607 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
608 return Either.right(responseFormat);
610 String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(groupingName);
611 grouping.setNormalizedName(normalizedName);
612 // Uniqueness under this category
613 Either<Boolean, ActionStatus> groupingUniqueForSubCategory = elementOperation
614 .isGroupingUniqueForSubCategory(childNodeType, normalizedName, parentSubCategoryId);
615 if (groupingUniqueForSubCategory.isRight()) {
616 log.debug("Failed to check grouping uniqueness, parent name {}, grouping norm name {}, componentType {}", parentSubCategoryName,
617 normalizedName, componentType);
618 ResponseFormat responseFormat = componentsUtils.getResponseFormat(groupingUniqueForSubCategory.right().value());
619 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
620 return Either.right(responseFormat);
622 Boolean isGroupingUnique = groupingUniqueForSubCategory.left().value();
623 if (Boolean.FALSE.equals(isGroupingUnique)) {
624 log.debug("Grouping is not unique for sub-category, parent name {}, grouping norm name {}, componentType {}", parentSubCategoryName,
625 normalizedName, componentType);
626 ResponseFormat responseFormat = componentsUtils
627 .getResponseFormat(ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY, componentType, groupingName, parentSubCategoryName);
628 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
629 return Either.right(responseFormat);
631 // Setting name of grouping to fit the similar grouping name ignoring
635 // For example if Network-->kUKU exists for service sub-category
637 // Network, and user is trying to create grouping Router-->Kuku for
639 // service sub-category Router,
641 // his grouping name will be Router-->kUKU.
642 Either<GroupingDefinition, ActionStatus> groupingUniqueForType = elementOperation.getGroupingUniqueForType(childNodeType, normalizedName);
643 if (groupingUniqueForType.isRight()) {
644 log.debug("Failed validation of whether similar grouping exists, normalizedName {} componentType {}", normalizedName, componentType);
645 ResponseFormat responseFormat = componentsUtils.getResponseFormat(groupingUniqueForType.right().value());
646 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
647 return Either.right(responseFormat);
649 GroupingDefinition groupingDefinition = groupingUniqueForType.left().value();
650 if (groupingDefinition != null) {
651 groupingName = groupingDefinition.getName();
653 grouping.setName(groupingName);
654 ///////////////////////////////////////////// Validations end
655 Either<GroupingDefinition, ActionStatus> createGrouping = elementOperation.createGrouping(parentSubCategoryId, grouping, childNodeType);
656 if (createGrouping.isRight()) {
657 log.debug("Failed to create grouping, name {}, componentType {}", groupingName, componentType);
658 ResponseFormat responseFormat = componentsUtils.getResponseFormat(createGrouping.right().value());
659 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType);
660 return Either.right(responseFormat);
662 GroupingDefinition groupingCreated = createGrouping.left().value();
663 log.debug("Created grouping for component {}, name {}, uniqueId {}", componentType, groupingName, groupingCreated.getUniqueId());
664 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
665 handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, groupingCreated.getName(), auditingAction,
667 return Either.left(groupingCreated);
670 public Either<List<CategoryDefinition>, ResponseFormat> getAllCategories(String componentType, String userId) {
671 ResponseFormat responseFormat;
672 User user = new User();
673 if (userId == null) {
674 user.setUserId("UNKNOWN");
675 responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION);
676 componentsUtils.auditGetCategoryHierarchy(user, componentType, responseFormat);
677 return Either.right(responseFormat);
680 user = validateUserExists(userId);
681 } catch (ByActionStatusComponentException e) {
682 responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
683 handleComponentException(componentType, userId, responseFormat);
685 } catch (ByResponseFormatComponentException e) {
686 responseFormat = e.getResponseFormat();
687 handleComponentException(componentType, userId, responseFormat);
690 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType);
691 if (componentTypeEnum == null) {
692 log.debug("Cannot create category for component type {}", componentType);
693 responseFormat = componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, "component type");
694 componentsUtils.auditGetCategoryHierarchy(user, componentType, responseFormat);
695 return Either.right(responseFormat);
697 NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY);
698 Either<List<CategoryDefinition>, ActionStatus> getAllCategoriesByType = elementOperation.getAllCategories(nodeTypeEnum, false);
699 if (getAllCategoriesByType.isRight()) {
700 responseFormat = componentsUtils.getResponseFormat(getAllCategoriesByType.right().value());
701 componentsUtils.auditGetCategoryHierarchy(user, componentType, responseFormat);
702 return Either.right(responseFormat);
704 List<CategoryDefinition> categories = getAllCategoriesByType.left().value();
705 responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
706 componentsUtils.auditGetCategoryHierarchy(user, componentType, responseFormat);
707 return Either.left(categories);
710 public Either<UiCategories, ResponseFormat> getAllCategories(String userId) {
711 ResponseFormat responseFormat;
712 UiCategories categories = new UiCategories();
713 User user = validateUserExists(userId);
714 // GET resource categories
715 Either<List<CategoryDefinition>, ActionStatus> getResourceCategoriesByType = elementOperation
716 .getAllCategories(NodeTypeEnum.ResourceNewCategory, false);
717 if (getResourceCategoriesByType.isRight()) {
718 responseFormat = componentsUtils.getResponseFormat(getResourceCategoriesByType.right().value());
719 componentsUtils.auditGetCategoryHierarchy(user, ComponentTypeEnum.RESOURCE.getValue(), responseFormat);
720 return Either.right(responseFormat);
722 categories.setResourceCategories(getResourceCategoriesByType.left().value());
723 // GET service categories
724 Either<List<CategoryDefinition>, ActionStatus> getServiceCategoriesByType = elementOperation
725 .getAllCategories(NodeTypeEnum.ServiceNewCategory, false);
726 if (getServiceCategoriesByType.isRight()) {
727 responseFormat = componentsUtils.getResponseFormat(getServiceCategoriesByType.right().value());
728 componentsUtils.auditGetCategoryHierarchy(user, ComponentTypeEnum.SERVICE.getValue(), responseFormat);
729 return Either.right(responseFormat);
731 categories.setServiceCategories(getServiceCategoriesByType.left().value());
732 categories.setProductCategories(new ArrayList<>());
733 return Either.left(categories);
736 public Either<CategoryDefinition, ResponseFormat> deleteCategory(String categoryId, String componentTypeParamName, String userId) {
737 validateUserExists(userId);
738 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
739 if (componentTypeEnum == null) {
740 log.debug("Cannot create category for component type {}", componentTypeParamName);
741 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
743 NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY);
744 Either<CategoryDefinition, ActionStatus> deleteCategoryByType = elementOperation.deleteCategory(nodeTypeEnum, categoryId);
745 if (deleteCategoryByType.isRight()) {
746 // auditing, logging here...
747 return Either.right(componentsUtils.getResponseFormat(deleteCategoryByType.right().value()));
749 CategoryDefinition category = deleteCategoryByType.left().value();
750 log.debug("Delete category for component {}, name {}, uniqueId {}", nodeTypeEnum, category.getName(), category.getUniqueId());
751 return Either.left(category);
754 public Either<SubCategoryDefinition, ResponseFormat> deleteSubCategory(String parentSubCategoryId, String componentTypeParamName, String userId) {
755 validateUserExists(userId);
756 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
757 if (componentTypeEnum == null) {
758 log.debug("Cannot delete sub-category for component type {}", componentTypeParamName);
759 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
761 NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY);
762 Either<SubCategoryDefinition, ActionStatus> deleteSubCategoryByType = elementOperation.deleteSubCategory(nodeTypeEnum, parentSubCategoryId);
763 if (deleteSubCategoryByType.isRight()) {
764 // auditing, logging here...
765 return Either.right(componentsUtils.getResponseFormat(deleteSubCategoryByType.right().value()));
767 SubCategoryDefinition subCategory = deleteSubCategoryByType.left().value();
768 log.debug("Deleted sub-category for component {}, name {}, uniqueId {}", nodeTypeEnum, subCategory.getName(), subCategory.getUniqueId());
769 return Either.left(subCategory);
772 public Either<GroupingDefinition, ResponseFormat> deleteGrouping(String groupingId, String componentTypeParamName, String userId) {
773 validateUserExists(userId);
774 ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName);
775 if (componentTypeEnum == null) {
776 log.debug("Cannot delete grouping for component type {}", componentTypeParamName);
777 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
779 NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.GROUPING);
780 Either<GroupingDefinition, ActionStatus> deleteGroupingByType = elementOperation.deleteGrouping(nodeTypeEnum, groupingId);
781 if (deleteGroupingByType.isRight()) {
782 // auditing, logging here...
783 return Either.right(componentsUtils.getResponseFormat(deleteGroupingByType.right().value()));
785 GroupingDefinition deletedGrouping = deleteGroupingByType.left().value();
786 log.debug("Deleted grouping for component {}, name {}, uniqueId {}", nodeTypeEnum, deletedGrouping.getName(), deletedGrouping.getUniqueId());
787 return Either.left(deletedGrouping);
790 private Either<Boolean, ResponseFormat> validateUserRole(User user, ComponentTypeEnum componentTypeEnum) {
791 String role = user.getRole();
792 boolean validAdminAction =
793 role.equals(Role.ADMIN.name()) && (componentTypeEnum == ComponentTypeEnum.SERVICE || componentTypeEnum == ComponentTypeEnum.RESOURCE);
794 boolean validProductAction = role.equals(Role.PRODUCT_STRATEGIST.name()) && (componentTypeEnum == ComponentTypeEnum.PRODUCT);
795 if (!(validAdminAction || validProductAction)) {
796 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
797 log.debug("User not permitted to perform operation on category, userId = {}, role = {}, componentType = {}", user.getUserId(), role,
799 return Either.right(responseFormat);
801 return Either.left(true);
804 private Either<Boolean, ResponseFormat> validateComponentTypeForCategory(ComponentTypeEnum componentType, CategoryTypeEnum categoryType) {
805 boolean validResourceAction = componentType == ComponentTypeEnum.RESOURCE && (categoryType == CategoryTypeEnum.CATEGORY
806 || categoryType == CategoryTypeEnum.SUBCATEGORY);
807 boolean validServiceAction = componentType == ComponentTypeEnum.SERVICE && categoryType == CategoryTypeEnum.CATEGORY;
808 boolean validProductAction = componentType == ComponentTypeEnum.PRODUCT; // can
817 if (!(validResourceAction || validServiceAction || validProductAction)) {
818 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
819 log.debug("It's not allowed to create category type {} for component type {}", categoryType, componentType);
820 return Either.right(responseFormat);
822 return Either.left(true);
825 private Either<CategoryDefinition, ResponseFormat> validateCategoryExists(NodeTypeEnum nodeType, String categoryId,
826 ComponentTypeEnum componentType) {
827 Either<CategoryDefinition, ActionStatus> categoryByTypeAndId = elementOperation.getCategory(nodeType, categoryId);
828 if (categoryByTypeAndId.isRight()) {
829 log.debug("Failed to fetch parent category, parent categoryId {}", categoryId);
830 ActionStatus actionStatus = categoryByTypeAndId.right().value();
831 ResponseFormat responseFormat;
832 if (actionStatus == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND) {
833 responseFormat = componentsUtils
834 .getResponseFormat(actionStatus, componentType.getValue().toLowerCase(), CategoryTypeEnum.CATEGORY.getValue(), "");
836 responseFormat = componentsUtils.getResponseFormat(actionStatus);
838 return Either.right(responseFormat);
840 return Either.left(categoryByTypeAndId.left().value());
843 private Either<SubCategoryDefinition, ResponseFormat> validateSubCategoryExists(NodeTypeEnum nodeType, String subCategoryId,
844 ComponentTypeEnum componentType) {
845 Either<SubCategoryDefinition, ActionStatus> subCategoryByTypeAndId = elementOperation.getSubCategory(nodeType, subCategoryId);
846 if (subCategoryByTypeAndId.isRight()) {
847 log.debug("Failed to fetch parent category, parent categoryId {}", subCategoryId);
848 ActionStatus actionStatus = subCategoryByTypeAndId.right().value();
849 ResponseFormat responseFormat;
850 if (actionStatus == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND) {
851 responseFormat = componentsUtils
852 .getResponseFormat(actionStatus, componentType.getValue().toLowerCase(), CategoryTypeEnum.SUBCATEGORY.getValue(), "");
854 responseFormat = componentsUtils.getResponseFormat(actionStatus);
856 return Either.right(responseFormat);
858 return Either.left(subCategoryByTypeAndId.left().value());
861 private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, AuditingActionEnum auditingAction,
862 String componentType) {
863 componentsUtils.auditCategory(responseFormat, user, category, null, null, auditingAction, componentType);
866 private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, String subCategory,
867 AuditingActionEnum auditingAction, String componentType) {
868 componentsUtils.auditCategory(responseFormat, user, category, subCategory, null, auditingAction, componentType);
871 private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, String subCategory, String grouping,
872 AuditingActionEnum auditingAction, String componentType) {
873 componentsUtils.auditCategory(responseFormat, user, category, subCategory, grouping, auditingAction, componentType);
877 * New categories flow - end
879 public Either<List<Tag>, ActionStatus> getAllTags(String userId) {
880 ActionStatus status = validateUserExistsActionStatus(userId);
881 if (ActionStatus.OK != status) {
882 return Either.right(status);
884 return elementOperation.getAllTags();
887 public Either<List<PropertyScope>, ActionStatus> getAllPropertyScopes(String userId) {
888 ActionStatus status = validateUserExistsActionStatus(userId);
889 if (ActionStatus.OK != status) {
890 return Either.right(status);
892 return elementOperation.getAllPropertyScopes();
895 public Either<List<ArtifactType>, ActionStatus> getAllArtifactTypes(final String userId) {
896 ActionStatus status = validateUserExistsActionStatus(userId);
897 if (ActionStatus.OK != status) {
898 return Either.right(status);
900 return Either.left(elementOperation.getAllArtifactTypes());
903 public Either<Configuration.HeatDeploymentArtifactTimeout, ActionStatus> getDefaultHeatTimeout() {
904 return elementOperation.getDefaultHeatTimeout();
907 public Either<Map<String, List<CatalogComponent>>, ResponseFormat> getCatalogComponents(List<OriginTypeEnum> excludeTypes) {
909 return toscaOperationFacade.getCatalogOrArchiveComponents(true, excludeTypes)
910 .bimap(this::groupByComponentType, err -> componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(err)));
912 janusGraphDao.commit();
916 private Map<String, List<CatalogComponent>> groupByComponentType(List<CatalogComponent> components) {
917 Map<String, List<CatalogComponent>> map = components.stream()
918 .collect(Collectors.groupingBy(cmpt -> cmptTypeToString(cmpt.getComponentType())));
919 // fixed response for UI!!! UI need to receive always map!
921 map = new HashMap<>();
923 map.computeIfAbsent(RESOURCES, k -> new ArrayList());
924 map.computeIfAbsent(SERVICES, k -> new ArrayList());
928 private String cmptTypeToString(ComponentTypeEnum componentTypeEnum) {
929 switch (componentTypeEnum) {
935 throw new IllegalStateException("resources or services only");
939 public Either<List<? extends Component>, ResponseFormat> getFilteredCatalogComponents(String assetType, Map<FilterKeyEnum, Object> filters,
941 ComponentTypeEnum assetTypeEnum = AssetTypeEnum.convertToComponentTypeEnum(assetType);
943 Optional<NameValuePair> invalidFilter = findInvalidFilter(query, assetTypeEnum);
944 if (invalidFilter.isPresent()) {
945 log.debug("getFilteredAssetList: invalid filter key");
946 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_FILTER_KEY, invalidFilter.get().getName(),
947 FilterKeyEnum.getValidFiltersByAssetType(assetTypeEnum).toString()));
950 if (MapUtils.isEmpty(filters)) {
951 Either<List<Component>, StorageOperationStatus> componentsList = toscaOperationFacade.getCatalogComponents(assetTypeEnum, null, false);
952 if (componentsList.isRight()) {
953 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(componentsList.right().value())));
955 return Either.left(componentsList.left().value());
957 Either<List<Component>, StorageOperationStatus> result = getFilteredComponents(filters, assetTypeEnum, false);
958 // category hierarchy mismatch or category/subCategory/distributionStatus not found
959 if (result.isRight()) {
960 List<String> params = getErrorResponseParams(filters, assetTypeEnum);
961 return Either.right(componentsUtils
962 .getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value()), params.get(0), params.get(1), params.get(2)));
964 if (result.left().value().isEmpty()) { // no assets found for requested criteria
965 return Either.right(componentsUtils.getResponseFormat(ActionStatus.NO_ASSETS_FOUND, assetType, query));
967 return Either.left(result.left().value());
970 private Either<List<Component>, StorageOperationStatus> getFilteredComponents(Map<FilterKeyEnum, Object> filters, ComponentTypeEnum assetType,
971 boolean inTransaction) {
972 Either<List<Component>, StorageOperationStatus> assetResult = Either.left(new LinkedList<>());
973 if (assetType == ComponentTypeEnum.RESOURCE) {
974 assetResult = getFilteredResources(filters, inTransaction);
975 } else if (assetType == ComponentTypeEnum.SERVICE) {
976 assetResult = getFilteredServices(filters);
981 private <T extends Component> Either<List<T>, StorageOperationStatus> getFilteredServices(Map<FilterKeyEnum, Object> filters) {
982 final String distributionStatus = (String) filters.get(FilterKeyEnum.DISTRIBUTION_STATUS);
983 final DistributionStatusEnum distEnum;
984 if (StringUtils.isNotBlank(distributionStatus)) {
985 distEnum = DistributionStatusEnum.findState(distributionStatus);
986 if (distEnum == null) {
987 return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
992 Either<List<Service>, StorageOperationStatus> components = toscaOperationFacade.getCatalogComponents(ComponentTypeEnum.SERVICE, null, false);
993 if (components.isRight()) { // not found == empty list
994 return Either.left(new ArrayList<>());
996 final String categoryName = (String) filters.get(FilterKeyEnum.CATEGORY);
997 Predicate<Service> servPredicate = Component::isService;
998 if (StringUtils.isNotBlank(categoryName)) { // primary filter
999 servPredicate = servPredicate.and(
1000 p -> p.getCategories().parallelStream().map(CategoryDataDefinition::getName).collect(Collectors.toList()).contains(categoryName));
1002 if (distEnum != null) {// secondary filter
1003 servPredicate = servPredicate.and(p -> p.getDistributionStatus() == distEnum);
1005 List<Service> serviceList = components.left().value().parallelStream().filter(servPredicate).collect(Collectors.toList());
1007 final String version = (String) filters.get(FilterKeyEnum.VERSION);
1008 if (StringUtils.isNotBlank(version)) {
1009 serviceList = filterServicesWithVersion(serviceList, version);
1011 final List<String> metadata = (List<String>) filters.get(FilterKeyEnum.METADATA);
1012 if (CollectionUtils.isNotEmpty(metadata)) {
1013 serviceList = filterServicesWithMetadata(serviceList, metadata);
1015 return Either.left((List<T>) serviceList);
1018 private List<Service> filterServicesWithMetadata(final List<Service> serviceList, final List<String> metadata) {
1019 Predicate<Service> predicate = Component::isService;
1020 final String regex = "[\\w\\.\\- ]";
1021 for (final String keyValuePair : metadata) {
1022 final Matcher matcher = Pattern.compile("(" + regex + "+)[:=](" + regex + "+)").matcher(keyValuePair);
1023 if (matcher.find()) {
1024 predicate = predicate.and(service -> matcher.group(2).equals(service.getCategorySpecificMetadata().get(matcher.group(1))));
1027 return serviceList.stream().filter(predicate).collect(Collectors.toList());
1030 private List<Service> filterServicesWithVersion(final List<Service> serviceList, final String version) {
1031 String trim = version.trim();
1032 final Optional<VersionFilterEnum> versionFilter = VersionFilterEnum.getFilter(trim);
1033 if (versionFilter.isPresent()) {
1034 return versionFilter.get().filter(serviceList, trim);
1039 public Either<List<? extends Component>, ResponseFormat> getCatalogComponentsByUuidAndAssetType(String assetType, String uuid) {
1040 if (assetType == null || uuid == null) {
1041 log.debug("getCatalogComponentsByUuidAndAssetType: One of the function parameteres is null");
1042 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1044 ComponentTypeEnum assetTypeEnum = AssetTypeEnum.convertToComponentTypeEnum(assetType);
1045 if (assetTypeEnum == null) {
1046 log.debug("getCatalogComponentsByUuidAndAssetType: Corresponding ComponentTypeEnum not found");
1047 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1049 Map<GraphPropertyEnum, Object> additionalPropertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
1050 switch (assetTypeEnum) {
1052 additionalPropertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
1055 additionalPropertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
1058 log.debug("getCatalogComponentsByUuidAndAssetType: Corresponding ComponentTypeEnum not allowed for this API");
1059 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1061 Either<List<Component>, StorageOperationStatus> componentsListByUuid = toscaOperationFacade
1062 .getComponentListByUuid(uuid, additionalPropertiesToMatch);
1063 if (componentsListByUuid.isRight()) {
1064 log.debug("getCatalogComponentsByUuidAndAssetType: " + assetTypeEnum.getValue() + " fetching failed");
1065 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(componentsListByUuid.right().value(), assetTypeEnum);
1066 return Either.right(componentsUtils.getResponseFormat(actionStatus, uuid));
1068 log.debug("getCatalogComponentsByUuidAndAssetType: " + assetTypeEnum.getValue() + assetTypeEnum.getValue() + "fetching successful");
1069 return Either.left(componentsListByUuid.left().value());
1072 public List<String> getAllComponentTypesParamNames() {
1073 List<String> paramNames = new ArrayList<>();
1074 paramNames.add(ComponentTypeEnum.SERVICE_PARAM_NAME);
1075 paramNames.add(ComponentTypeEnum.RESOURCE_PARAM_NAME);
1076 paramNames.add(ComponentTypeEnum.PRODUCT_PARAM_NAME);
1080 public List<String> getAllSupportedRoles() {
1081 Role[] values = Role.values();
1082 List<String> roleNames = new ArrayList<>();
1083 for (Role role : values) {
1084 roleNames.add(role.name());
1089 public Either<Map<String, String>, ActionStatus> getResourceTypesMap() {
1090 return elementOperation.getResourceTypesMap();
1093 private Optional<NameValuePair> findInvalidFilter(String query, ComponentTypeEnum assetType) {
1094 return URLEncodedUtils.parse(query, StandardCharsets.UTF_8)
1095 .stream().filter(p -> !FilterKeyEnum.getValidFiltersByAssetType(assetType).contains(p.getName())).findAny();
1098 private List<String> getErrorResponseParams(Map<FilterKeyEnum, Object> filters, ComponentTypeEnum assetType) {
1099 List<String> params = new ArrayList<>();
1100 if (1 == filters.size()) {
1101 params.add(assetType.getValue().toLowerCase());
1102 params.add(filters.keySet().iterator().next().getName());
1103 params.add((String) filters.values().iterator().next());
1105 params.add(assetType.getValue());
1106 params.add((String) filters.get(FilterKeyEnum.SUB_CATEGORY));
1107 params.add((String) filters.get(FilterKeyEnum.CATEGORY));
1112 public Either<List<Component>, StorageOperationStatus> getFilteredResources(Map<FilterKeyEnum, Object> filters, boolean inTransaction) {
1113 String subCategoryName = (String) filters.get(FilterKeyEnum.SUB_CATEGORY);
1114 String categoryName = (String) filters.get(FilterKeyEnum.CATEGORY);
1115 ResourceTypeEnum resourceType = ResourceTypeEnum.getType((String) filters.get(FilterKeyEnum.RESOURCE_TYPE));
1116 Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, StorageOperationStatus> subcategories = null;
1117 Optional<ImmutablePair<SubCategoryData, GraphEdge>> subCategoryData;
1118 if (categoryName != null) {
1119 subcategories = getAllSubCategories(categoryName);
1120 if (subcategories.isRight()) {
1121 filters.remove(FilterKeyEnum.SUB_CATEGORY);
1122 return Either.right(subcategories.right().value());
1125 if (subCategoryName != null) { // primary filter
1126 if (categoryName != null) {
1127 subCategoryData = validateCategoryHierarcy(subcategories.left().value(), subCategoryName);
1128 if (subCategoryData.isEmpty()) {
1129 return Either.right(StorageOperationStatus.MATCH_NOT_FOUND);
1131 return fetchByCategoryOrSubCategoryUid(subCategoryData.get().getLeft().getUniqueId(), NodeTypeEnum.Resource, inTransaction,
1134 return fetchByCategoryOrSubCategoryName(subCategoryName, NodeTypeEnum.ResourceSubcategory, NodeTypeEnum.Resource, inTransaction,
1137 if (subcategories != null) {
1138 return fetchByMainCategory(subcategories.left().value(), inTransaction, resourceType);
1140 return fetchComponentMetaDataByResourceType((String) filters.get(FilterKeyEnum.RESOURCE_TYPE), inTransaction);
1143 private Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, StorageOperationStatus> getAllSubCategories(String categoryName) {
1144 Either<CategoryData, StorageOperationStatus> categoryResult = elementOperation
1145 .getNewCategoryData(categoryName, NodeTypeEnum.ResourceNewCategory, CategoryData.class);
1146 if (categoryResult.isRight()) {
1147 return Either.right(categoryResult.right().value());
1149 CategoryData categoryData = categoryResult.left().value();
1150 Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, JanusGraphOperationStatus> childrenNodes = janusGraphGenericDao
1151 .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceNewCategory), categoryData.getUniqueId(),
1152 GraphEdgeLabels.SUB_CATEGORY, NodeTypeEnum.ResourceSubcategory, SubCategoryData.class);
1153 if (childrenNodes.isRight()) {
1154 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(childrenNodes.right().value()));
1156 return Either.left(childrenNodes.left().value());
1159 private Optional<ImmutablePair<SubCategoryData, GraphEdge>> validateCategoryHierarcy(List<ImmutablePair<SubCategoryData, GraphEdge>> childNodes,
1160 String subCategoryName) {
1161 Predicate<ImmutablePair<SubCategoryData, GraphEdge>> matchName = p -> p.getLeft().getSubCategoryDataDefinition().getName()
1162 .equals(subCategoryName);
1163 return childNodes.stream().filter(matchName).findAny();
1166 protected <T extends Component> Either<List<T>, StorageOperationStatus> fetchByCategoryOrSubCategoryUid(String categoryUid,
1167 NodeTypeEnum categoryType,
1168 boolean inTransaction,
1169 ResourceTypeEnum resourceType) {
1171 return collectComponents(categoryType, categoryUid, resourceType);
1173 if (!inTransaction) {
1174 janusGraphDao.commit();
1179 protected <T extends Component> Either<List<T>, StorageOperationStatus> fetchByCategoryOrSubCategoryName(String categoryName,
1180 NodeTypeEnum categoryType,
1181 NodeTypeEnum neededType,
1182 boolean inTransaction,
1183 ResourceTypeEnum resourceType) {
1184 List<T> components = new ArrayList<>();
1186 Class<? extends GraphNode> categoryClazz = categoryType == NodeTypeEnum.ServiceNewCategory ? CategoryData.class : SubCategoryData.class;
1187 Map<String, Object> props = new HashMap<>();
1188 props.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), ValidationUtils.normalizeCategoryName4Uniqueness(categoryName));
1189 Either<List<GraphNode>, JanusGraphOperationStatus> getCategory = janusGraphGenericDao.getByCriteria(categoryType, props,
1190 (Class<GraphNode>) categoryClazz);
1191 if (getCategory.isRight()) {
1192 return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND);
1194 for (GraphNode category : getCategory.left().value()) {
1195 Either<List<T>, StorageOperationStatus> result = collectComponents(neededType, category.getUniqueId(), resourceType);
1196 if (result.isRight() && result.right().value() != StorageOperationStatus.NOT_FOUND) {
1198 } else if (result.isLeft()) {
1199 components.addAll(result.left().value());
1202 if (components.isEmpty()) {
1203 return Either.right(StorageOperationStatus.NOT_FOUND);
1205 return Either.left(components);
1207 if (!inTransaction) {
1208 janusGraphDao.commit();
1213 private <T extends Component> Either<List<T>, StorageOperationStatus> collectComponents(NodeTypeEnum neededType, String categoryUid,
1214 ResourceTypeEnum resourceType) {
1215 List<T> components = new ArrayList<>();
1216 Either<GraphVertex, JanusGraphOperationStatus> categoryVertexById = janusGraphDao.getVertexById(categoryUid, JsonParseFlagEnum.NoParse);
1217 if (categoryVertexById.isRight()) {
1218 JanusGraphOperationStatus status = categoryVertexById.right().value();
1219 log.debug("#collectComponents Failed to get category vertex with uid {}, status is {}.", categoryUid, status);
1220 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
1222 GraphVertex categoryVertex = categoryVertexById.left().value();
1223 Either<List<GraphVertex>, JanusGraphOperationStatus> componentsVertices = janusGraphDao
1224 .getParentVertices(categoryVertex, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.ParseMetadata);
1225 if (componentsVertices.isRight()) {
1226 JanusGraphOperationStatus status = componentsVertices.right().value();
1227 log.debug("#collectComponents Failed to get components vertices of category {}, status is {}.", categoryVertex, status);
1228 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
1230 List<ComponentMetadataDataDefinition> componentsMetadataDataDefinition = componentsVertices.left().value().stream().filter(Objects::nonNull)
1231 .filter(componentsVertex -> Objects.nonNull(componentsVertex.getType())).map(ModelConverter::convertToComponentMetadataDataDefinition)
1232 .collect(Collectors.toList());
1233 for (ComponentMetadataDataDefinition component : componentsMetadataDataDefinition) {
1234 boolean isHighest = isTrue(component.isHighestVersion());
1235 boolean isMatchingResourceType = isMatchingByResourceType(neededType, resourceType, component);
1236 boolean isDeleted = isTrue(component.isDeleted());
1237 boolean isArchived = isTrue(component.isArchived());
1238 if (isHighest && isMatchingResourceType && !isDeleted && !isArchived) {
1239 Either<T, StorageOperationStatus> result = toscaOperationFacade
1240 .getToscaElement(component.getUniqueId(), JsonParseFlagEnum.ParseMetadata);
1241 if (result.isRight()) {
1242 return Either.right(result.right().value());
1244 components.add(result.left().value());
1247 return Either.left(components);
1250 private boolean isMatchingByResourceType(NodeTypeEnum componentType, ResourceTypeEnum resourceType,
1251 ComponentMetadataDataDefinition componentData) {
1253 if (componentType == NodeTypeEnum.Resource) {
1254 if (resourceType == null) {
1257 isMatching = resourceType == ((ResourceMetadataDataDefinition) componentData).getResourceType();
1265 private <T extends Component> Either<List<T>, StorageOperationStatus> fetchByMainCategory(
1266 List<ImmutablePair<SubCategoryData, GraphEdge>> subcategories, boolean inTransaction, ResourceTypeEnum resourceType) {
1267 List<T> components = new ArrayList<>();
1268 for (ImmutablePair<SubCategoryData, GraphEdge> subCategory : subcategories) {
1269 Either<List<T>, StorageOperationStatus> fetched = fetchByCategoryOrSubCategoryUid(subCategory.getLeft().getUniqueId(),
1270 NodeTypeEnum.Resource, inTransaction, resourceType);
1271 if (fetched.isRight()) {
1274 components.addAll(fetched.left().value());
1276 return Either.left(components);
1279 private Either<List<Component>, StorageOperationStatus> fetchComponentMetaDataByResourceType(String resourceType, boolean inTransaction) {
1280 List<Component> components = null;
1281 StorageOperationStatus status;
1282 Wrapper<StorageOperationStatus> statusWrapper = new Wrapper<>();
1284 ComponentParametersView fetchUsersAndCategoriesFilter = new ComponentParametersView(
1285 Arrays.asList(ComponentFieldsEnum.USERS.getValue(), ComponentFieldsEnum.CATEGORIES.getValue()));
1286 Either<List<Component>, StorageOperationStatus> getResources = toscaOperationFacade
1287 .fetchMetaDataByResourceType(resourceType, fetchUsersAndCategoriesFilter);
1288 if (getResources.isRight()) {
1289 status = getResources.right().value();
1290 if (status != StorageOperationStatus.NOT_FOUND) {
1291 statusWrapper.setInnerElement(getResources.right().value());
1293 components = new ArrayList<>();
1296 components = getResources.left().value();
1298 if (statusWrapper.isEmpty()) {
1299 return Either.left(components);
1301 return Either.right(statusWrapper.getInnerElement());
1304 if (!inTransaction) {
1305 janusGraphDao.commit();
1310 public CatalogUpdateTimestamp getCatalogUpdateTime() {
1312 return toscaOperationFacade.getCatalogTimes();
1314 janusGraphDao.commit();
1318 public Either<List<BaseType>, ActionStatus> getBaseTypes(final String categoryName, final String userId, final String modelName) {
1319 final ActionStatus status = validateUserExistsActionStatus(userId);
1320 if (ActionStatus.OK != status) {
1321 return Either.right(status);
1323 return Either.left(elementOperation.getServiceBaseTypes(categoryName, modelName));
1327 * Checks if a category requires a base type.
1329 * @param categoryName the category name
1330 * @return {@code true} if a base type is required, {@code false} otherwise.
1332 public boolean isBaseTypeRequired(final String categoryName) {
1333 return elementOperation.isBaseTypeRequired(categoryName);
1337 * Fetches default baseType from the template.
1339 * @param categoryName the category name
1340 * @return defaultBaseType mapped to the corresponding category name.
1342 public String getDefaultBaseType(final String categoryName) {
1343 return elementOperation.getDefaultBaseType(categoryName);
1346 public boolean isDoNotExtendBaseType(final String categoryName) {
1347 return elementOperation.isDoNotExtendBaseType(categoryName);