X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=catalog-be%2Fsrc%2Fmain%2Fjava%2Forg%2Fopenecomp%2Fsdc%2Fbe%2Fcomponents%2Fimpl%2FElementBusinessLogic.java;h=4156e3da3521fe351057fda6e53751241973473d;hb=5d7ca5c1e86d7633a1954ae89334df18d264f82b;hp=5ebb86f1bac7eafc66689ec4908365b6171b4054;hpb=451a3400b76511393c62a444f588a4ed15f4a549;p=sdc.git diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java index 5ebb86f1ba..4156e3da35 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java @@ -7,42 +7,77 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END========================================================= + * Modifications copyright (c) 2019 Nokia + * ================================================================================ */ - package org.openecomp.sdc.be.components.impl; +import static org.apache.commons.lang.BooleanUtils.isTrue; +import static org.openecomp.sdc.be.components.impl.ImportUtils.Constants.DEFAULT_ICON; + +import fj.data.Either; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.function.Predicate; - +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; +import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; +import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException; +import org.openecomp.sdc.be.config.Configuration; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; +import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum; import org.openecomp.sdc.be.datamodel.utils.NodeTypeConvertUtils; +import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition; +import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; -import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.externalapi.servlet.representation.VersionFilterEnum; import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.BaseType; +import org.openecomp.sdc.be.model.CatalogUpdateTimestamp; import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentParametersView; import org.openecomp.sdc.be.model.DistributionStatusEnum; import org.openecomp.sdc.be.model.LifecycleStateEnum; import org.openecomp.sdc.be.model.Product; @@ -51,1075 +86,1264 @@ import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.model.Tag; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.catalog.CatalogComponent; import org.openecomp.sdc.be.model.category.CategoryDefinition; import org.openecomp.sdc.be.model.category.GroupingDefinition; import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation; +import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter; import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation; +import org.openecomp.sdc.be.model.operations.api.IGroupOperation; +import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; -import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; +import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.be.resources.data.category.SubCategoryData; +import org.openecomp.sdc.be.ui.model.UiCategories; import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.common.util.ValidationUtils; import org.openecomp.sdc.exception.ResponseFormat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import fj.data.Either; +import org.springframework.beans.factory.annotation.Autowired; @org.springframework.stereotype.Component("elementsBusinessLogic") public class ElementBusinessLogic extends BaseBusinessLogic { - private static Logger log = LoggerFactory.getLogger(ElementBusinessLogic.class.getName()); - - @javax.annotation.Resource - private IElementOperation elementOperation; - - @javax.annotation.Resource - private ComponentsUtils componentsUtils; - - @javax.annotation.Resource - private UserBusinessLogic userAdminManager; - - /** - * - * @param user - * @return - */ - public Either>, ResponseFormat> getFollowed(User user) { - Either>, ResponseFormat> response = null; - // Getting the role - String role = user.getRole(); - String userId = null; - Role currentRole = Role.valueOf(role); - - switch (currentRole) { - case DESIGNER: - userId = user.getUserId(); - response = handleDesigner(userId); - break; - - case TESTER: - userId = user.getUserId(); - response = handleTester(userId); - break; - - case GOVERNOR: - userId = user.getUserId(); - response = handleGovernor(userId); - break; - - case OPS: - userId = user.getUserId(); - response = handleOps(userId); - break; - - case PRODUCT_STRATEGIST: - userId = user.getUserId(); - response = handleProductStrategist(userId); - break; - - case PRODUCT_MANAGER: - userId = user.getUserId(); - response = handleProductManager(userId); - break; - - case ADMIN: - response = handleAdmin(); - break; - - default: - response = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); - break; - } - return response; - - } - - private Either>, ResponseFormat> handleAdmin() { - Either>, ResponseFormat> response; - // userId should stay null - Set lifecycleStates = new HashSet(); - Set lastStateStates = new HashSet(); - lifecycleStates.add(LifecycleStateEnum.CERTIFIED); - response = getFollowedResourcesAndServices(null, lifecycleStates, lastStateStates); - return response; - } - - private Either>, ResponseFormat> handleDesigner(String userId) { - Set lifecycleStates = new HashSet(); - Set lastStateStates = new HashSet(); - Either>, ResponseFormat> response; - lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); - lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); - lifecycleStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION); - lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); - lifecycleStates.add(LifecycleStateEnum.CERTIFIED); - // more states - lastStateStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION); - response = getFollowedResourcesAndServices(userId, lifecycleStates, lastStateStates); - return response; - } - - private Either>, ResponseFormat> handleGovernor(String userId) { - Either>, ResponseFormat> result = handleFollowedCertifiedServices(null); - return result; - } - - private Either>, ResponseFormat> handleProductStrategist(String userId) { - // Should be empty list according to Ella, 13/03/16 - Map> result = new HashMap>(); - result.put("products", new ArrayList<>()); - return Either.left(result); - } - - private Either>, ResponseFormat> handleProductManager(String userId) { - Set lifecycleStates = new HashSet(); - Set lastStateStates = new HashSet(); - Either>, ResponseFormat> response; - lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); - lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); - lifecycleStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION); - lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); - lifecycleStates.add(LifecycleStateEnum.CERTIFIED); - // more states - lastStateStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION); - response = getFollowedProducts(userId, lifecycleStates, lastStateStates); - return response; - } - - private Either>, ResponseFormat> handleOps(String userId) { - Set distStatus = new HashSet(); - distStatus.add(DistributionStatusEnum.DISTRIBUTION_APPROVED); - distStatus.add(DistributionStatusEnum.DISTRIBUTED); - - Either>, ResponseFormat> result = handleFollowedCertifiedServices(distStatus); - return result; - } - - private Either>, ResponseFormat> handleFollowedCertifiedServices(Set distStatus) { - Map propertiesToMatch = new HashMap<>(); - propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); - - Either, StorageOperationStatus> services = serviceOperation.getCertifiedServicesWithDistStatus(propertiesToMatch, distStatus, false); - if (services.isLeft()) { - Map> result = new HashMap>(); - List list = new ArrayList<>(); - list.addAll(services.left().value()); - result.put("services", list); - return Either.left(result); - } else { - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(services.right().value()))); - } - } - - private Either>, ResponseFormat> handleTester(String userId) { - Set lifecycleStates = new HashSet(); - lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); - Either, StorageOperationStatus> resources = resourceOperation.getTesterFollowed(userId, lifecycleStates, false); - - if (resources.isLeft()) { - Either, StorageOperationStatus> services = serviceOperation.getTesterFollowed(userId, lifecycleStates, false); - if (services.isLeft()) { - Map> result = new HashMap>(); - result.put("services", services.left().value()); - result.put("resources", resources.left().value()); - return Either.left(result); - } else { - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(services.right().value()))); - } - } else { - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resources.right().value()))); - } - } - - private Either>, ResponseFormat> getFollowedResourcesAndServices(String userId, Set lifecycleStates, Set lastStateStates) { - Either, StorageOperationStatus> resources = resourceOperation.getFollowed(userId, lifecycleStates, lastStateStates, false); - - if (resources.isLeft()) { - Either, StorageOperationStatus> services = serviceOperation.getFollowed(userId, lifecycleStates, lastStateStates, false); - if (services.isLeft()) { - Map> result = new HashMap>(); - result.put("services", services.left().value()); - result.put("resources", resources.left().value()); - return Either.left(result); - } else { - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(services.right().value()))); - } - } else { - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resources.right().value()))); - } - } - - private Either>, ResponseFormat> getFollowedProducts(String userId, Set lifecycleStates, Set lastStateStates) { - Either, StorageOperationStatus> products = productOperation.getFollowed(userId, lifecycleStates, lastStateStates, false); - if (products.isLeft()) { - Map> result = new HashMap>(); - result.put("products", products.left().value()); - return Either.left(result); - } else { - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(products.right().value()))); - } - } - - /* - * New categories flow - start - */ - public Either, ActionStatus> getAllResourceCategories() { - return elementOperation.getAllResourceCategories(); - } - - public Either, ActionStatus> getAllServiceCategories() { - return elementOperation.getAllServiceCategories(); - } - - public Either createCategory(CategoryDefinition category, String componentTypeParamName, String userId) { - - AuditingActionEnum auditingAction = AuditingActionEnum.ADD_CATEGORY; - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); - String componentType = (componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue()); - CategoryTypeEnum categoryType = CategoryTypeEnum.CATEGORY; - - User user = new User(); - Either validateUser = validateUser(userId); - if (validateUser.isRight()) { - log.debug("Validation of user failed, userId {}", userId); - ResponseFormat responseFormat = validateUser.right().value(); - user = new User(); - user.setUserId(userId); - String currCategoryName = (category == null ? null : category.getName()); - handleCategoryAuditing(responseFormat, user, currCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - user = validateUser.left().value(); - - if (category == null) { - log.debug("Category json is invalid"); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); - handleCategoryAuditing(responseFormat, user, null, auditingAction, componentType); - return Either.right(responseFormat); - } - - String categoryName = category.getName(); - // For auditing of failures we need the original non-normalized name - String origCategoryName = categoryName; - if (componentTypeEnum == null) { - log.debug("Component type {} is invalid", componentTypeParamName); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); - handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - Either validateUserRole = validateUserRole(user, componentTypeEnum); - if (validateUserRole.isRight()) { - log.debug("Validation of user role failed, userId {}", userId); - ResponseFormat responseFormat = validateUserRole.right().value(); - handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - if (!ValidationUtils.validateCategoryDisplayNameFormat(categoryName)) { - log.debug("Category display name format is invalid, name {}, componentType {}", categoryName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue()); - handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - categoryName = ValidationUtils.normalizeCategoryName4Display(categoryName); - - if (!ValidationUtils.validateCategoryDisplayNameLength(categoryName)) { - log.debug("Category display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", categoryName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue()); - handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - category.setName(categoryName); - - String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(categoryName); - category.setNormalizedName(normalizedName); - - NodeTypeEnum nodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, categoryType); - - Either categoryUniqueEither = elementOperation.isCategoryUniqueForType(nodeType, normalizedName); - if (categoryUniqueEither.isRight()) { - log.debug("Failed to check category uniqueness, name {}, componentType {}", categoryName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(categoryUniqueEither.right().value()); - handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - Boolean isCategoryUnique = categoryUniqueEither.left().value(); - if (!isCategoryUnique) { - log.debug("Category is not unique, name {}, componentType {}", categoryName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, componentType, categoryName); - handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - Either createCategoryByType = elementOperation.createCategory(category, nodeType); - if (createCategoryByType.isRight()) { - log.debug("Failed to create category, name {}, componentType {}", categoryName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, componentType, categoryName); - handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); - return Either.right(componentsUtils.getResponseFormat(createCategoryByType.right().value())); - } - category = createCategoryByType.left().value(); - log.debug("Created category for component {}, name {}, uniqueId {}", componentType, categoryName, category.getUniqueId()); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); - handleCategoryAuditing(responseFormat, user, category.getName(), auditingAction, componentType); - return Either.left(category); - } - - public Either createSubCategory(SubCategoryDefinition subCategory, String componentTypeParamName, String parentCategoryId, String userId) { - - AuditingActionEnum auditingAction = AuditingActionEnum.ADD_SUB_CATEGORY; - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); - String componentType = (componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue()); - CategoryTypeEnum categoryType = CategoryTypeEnum.SUBCATEGORY; - // For auditing - String parentCategoryName = parentCategoryId; - - if (subCategory == null) { - log.debug("Sub-category json is invalid"); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); - handleCategoryAuditing(responseFormat, null, parentCategoryName, null, auditingAction, componentType); - return Either.right(responseFormat); - } - - String subCategoryName = subCategory.getName(); - // For auditing of failures we need the original non-normalized name - String origSubCategoryName = subCategoryName; - - User user = new User(); - /* - * if (userId == null) { user.setUserId("UNKNOWN"); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, - * auditingAction, componentType); return Either.right(responseFormat); } - */ - Either validateUser = validateUserExists(userId, "createSubCategory", false); - if (validateUser.isRight()) { - log.debug("Validation of user failed, userId {}", userId); - ResponseFormat responseFormat = validateUser.right().value(); - user = new User(); - user.setUserId(userId); - handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - user = validateUser.left().value(); - - if (componentTypeEnum == null) { - log.debug("Component type {} is invalid", componentTypeParamName); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); - handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - Either validateComponentType = validateComponentTypeForCategory(componentTypeEnum, categoryType); - if (validateComponentType.isRight()) { - log.debug("Validation of component type for sub-category failed"); - ResponseFormat responseFormat = validateComponentType.right().value(); - handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - Either validateUserRole = validateUserRole(user, componentTypeEnum); - if (validateUserRole.isRight()) { - log.debug("Validation of user role failed, userId {}", userId); - ResponseFormat responseFormat = validateUserRole.right().value(); - handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - NodeTypeEnum parentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY); - NodeTypeEnum childNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY); - - CategoryDefinition categoryDefinition; - Either validateCategoryExists = validateCategoryExists(parentNodeType, parentCategoryId, componentTypeEnum); - if (validateCategoryExists.isRight()) { - log.debug("Validation of parent category exists failed, parent categoryId {}", parentCategoryId); - ResponseFormat responseFormat = validateCategoryExists.right().value(); - handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - categoryDefinition = validateCategoryExists.left().value(); - parentCategoryName = categoryDefinition.getName(); - - if (!ValidationUtils.validateCategoryDisplayNameFormat(subCategoryName)) { - log.debug("Sub-category display name format is invalid, name {}, componentType {}", subCategoryName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue()); - handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - subCategoryName = ValidationUtils.normalizeCategoryName4Display(subCategoryName); - - if (!ValidationUtils.validateCategoryDisplayNameLength(subCategoryName)) { - log.debug("Sub-category display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", subCategoryName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue()); - handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(subCategoryName); - subCategory.setNormalizedName(normalizedName); - - // Uniqueness under this category - Either subCategoryUniqueForCategory = elementOperation.isSubCategoryUniqueForCategory(childNodeType, normalizedName, parentCategoryId); - if (subCategoryUniqueForCategory.isRight()) { - log.debug("Failed to check sub-category uniqueness, parent name {}, subcategory norm name {}, componentType {}", parentCategoryName, normalizedName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForCategory.right().value()); - handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - Boolean isSubUnique = subCategoryUniqueForCategory.left().value(); - if (!isSubUnique) { - log.debug("Sub-category is not unique for category, parent name {}, subcategory norm name {}, componentType {}", parentCategoryName, normalizedName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY, componentType, subCategoryName, parentCategoryName); - handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - // Setting name of subcategory to fit the similar subcategory name - // ignoring cases. - // For example if Network-->kUKU exists for service category Network, - // and user is trying to create Router-->Kuku for service category - // Router, - // his subcategory name will be Router-->kUKU. - Either subCategoryUniqueForType = elementOperation.getSubCategoryUniqueForType(childNodeType, normalizedName); - if (subCategoryUniqueForType.isRight()) { - log.debug("Failed validation of whether similar sub-category exists, normalizedName {} componentType {}", normalizedName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForType.right().value()); - handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - SubCategoryDefinition subCategoryDefinition = subCategoryUniqueForType.left().value(); - if (subCategoryDefinition != null) { - subCategoryName = subCategoryDefinition.getName(); - } - - subCategory.setName(subCategoryName); - ///////////////////////////////////////////// Validations end - - Either createSubCategory = elementOperation.createSubCategory(parentCategoryId, subCategory, childNodeType); - if (createSubCategory.isRight()) { - log.debug("Failed to create sub-category, name {}, componentType {}", subCategoryName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForType.right().value()); - handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); - return Either.right(responseFormat); - } - - SubCategoryDefinition subCategoryCreated = createSubCategory.left().value(); - log.debug("Created sub-category for component {}, name {}, uniqueId {}", componentType, subCategoryName, subCategoryCreated.getUniqueId()); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); - handleCategoryAuditing(responseFormat, user, parentCategoryName, subCategoryCreated.getName(), auditingAction, componentType); - return Either.left(subCategoryCreated); - } - - public Either createGrouping(GroupingDefinition grouping, String componentTypeParamName, String grandParentCategoryId, String parentSubCategoryId, String userId) { - - AuditingActionEnum auditingAction = AuditingActionEnum.ADD_GROUPING; - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); - String componentType = (componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue()); - CategoryTypeEnum categoryType = CategoryTypeEnum.GROUPING; - // For auditing - String parentCategoryName = grandParentCategoryId; - String parentSubCategoryName = parentSubCategoryId; - - User user; - Either validateUser = validateUserExists(userId, "create Grouping", false); - if (validateUser.isRight()) { - log.debug("Validation of user failed, userId {}", userId); - ResponseFormat responseFormat = validateUser.right().value(); - user = new User(); - user.setUserId(userId); - String groupingNameForAudit = (grouping == null ? null : grouping.getName()); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, groupingNameForAudit, auditingAction, componentType); - return Either.right(responseFormat); - } - - user = validateUser.left().value(); - - if (grouping == null) { - log.debug("Grouping json is invalid"); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, null, auditingAction, componentType); - return Either.right(responseFormat); - } - - String groupingName = grouping.getName(); - // For auditing of failures we need the original non-normalized name - String origGroupingName = groupingName; - - if (componentTypeEnum == null) { - log.debug("Component type {} is invalid", componentTypeParamName); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); - return Either.right(responseFormat); - } - - Either validateComponentType = validateComponentTypeForCategory(componentTypeEnum, categoryType); - if (validateComponentType.isRight()) { - log.debug("Validation of component type for grouping failed"); - ResponseFormat responseFormat = validateComponentType.right().value(); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); - return Either.right(responseFormat); - } - - Either validateUserRole = validateUserRole(user, componentTypeEnum); - if (validateUserRole.isRight()) { - log.debug("Validation of user role failed, userId {}", userId); - ResponseFormat responseFormat = validateUserRole.right().value(); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); - return Either.right(responseFormat); - } - - NodeTypeEnum grandParentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY); - NodeTypeEnum parentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY); - NodeTypeEnum childNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.GROUPING); - - // Validate category - CategoryDefinition categoryDefinition; - Either validateCategoryExists = validateCategoryExists(grandParentNodeType, grandParentCategoryId, componentTypeEnum); - if (validateCategoryExists.isRight()) { - log.debug("Validation of parent category exists failed, parent categoryId {}", grandParentCategoryId); - ResponseFormat responseFormat = validateCategoryExists.right().value(); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); - return Either.right(responseFormat); - } - - categoryDefinition = validateCategoryExists.left().value(); - parentCategoryName = categoryDefinition.getName(); - - // Validate subcategory - SubCategoryDefinition subCategoryDefinition; - Either validateSubCategoryExists = validateSubCategoryExists(parentNodeType, parentSubCategoryId, componentTypeEnum); - if (validateSubCategoryExists.isRight()) { - log.debug("Validation of parent sub-category exists failed, parent sub-category id {}", parentSubCategoryId); - ResponseFormat responseFormat = validateSubCategoryExists.right().value(); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); - return Either.right(responseFormat); - } - - subCategoryDefinition = validateSubCategoryExists.left().value(); - parentSubCategoryName = subCategoryDefinition.getName(); - - if (!ValidationUtils.validateCategoryDisplayNameFormat(groupingName)) { - log.debug("Sub-category display name format is invalid, name {}, componentType {}", groupingName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue()); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); - return Either.right(responseFormat); - } - - groupingName = ValidationUtils.normalizeCategoryName4Display(groupingName); - - if (!ValidationUtils.validateCategoryDisplayNameLength(groupingName)) { - log.debug("Grouping display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", groupingName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue()); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); - return Either.right(responseFormat); - } - - String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(groupingName); - grouping.setNormalizedName(normalizedName); - - // Uniqueness under this category - Either groupingUniqueForSubCategory = elementOperation.isGroupingUniqueForSubCategory(childNodeType, normalizedName, parentSubCategoryId); - if (groupingUniqueForSubCategory.isRight()) { - log.debug("Failed to check grouping uniqueness, parent name {}, grouping norm name {}, componentType {}", parentSubCategoryName, normalizedName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(groupingUniqueForSubCategory.right().value()); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); - return Either.right(responseFormat); - } - - Boolean isGroupingUnique = groupingUniqueForSubCategory.left().value(); - if (!isGroupingUnique) { - log.debug("Grouping is not unique for sub-category, parent name {}, grouping norm name {}, componentType {}", parentSubCategoryName, normalizedName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY, componentType, groupingName, parentSubCategoryName); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); - return Either.right(responseFormat); - } - - // Setting name of grouping to fit the similar grouping name ignoring - // cases. - // For example if Network-->kUKU exists for service sub-category - // Network, and user is trying to create grouping Router-->Kuku for - // service sub-category Router, - // his grouping name will be Router-->kUKU. - Either groupingUniqueForType = elementOperation.getGroupingUniqueForType(childNodeType, normalizedName); - if (groupingUniqueForType.isRight()) { - log.debug("Failed validation of whether similar grouping exists, normalizedName {} componentType {}", normalizedName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(groupingUniqueForType.right().value()); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); - return Either.right(responseFormat); - } - GroupingDefinition groupingDefinition = groupingUniqueForType.left().value(); - if (groupingDefinition != null) { - groupingName = groupingDefinition.getName(); - } - - grouping.setName(groupingName); - ///////////////////////////////////////////// Validations end - - Either createGrouping = elementOperation.createGrouping(parentSubCategoryId, grouping, childNodeType); - if (createGrouping.isRight()) { - log.debug("Failed to create grouping, name {}, componentType {}", groupingName, componentType); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(createGrouping.right().value()); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); - return Either.right(responseFormat); - } - - GroupingDefinition groupingCreated = createGrouping.left().value(); - log.debug("Created grouping for component {}, name {}, uniqueId {}", componentType, groupingName, groupingCreated.getUniqueId()); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); - handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, groupingCreated.getName(), auditingAction, componentType); - return Either.left(groupingCreated); - } - - public Either, ResponseFormat> getAllCategories(String componentType, String userId) { - AuditingActionEnum auditingAction = AuditingActionEnum.GET_CATEGORY_HIERARCHY; - ResponseFormat responseFormat; - User user = new User(); - if (userId == null) { - user.setUserId("UNKNOWN"); - responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); - componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat); - return Either.right(responseFormat); - } - - Either validateUser = validateUserExists(userId, "get All Categories", false); - if (validateUser.isRight()) { - user.setUserId(userId); - log.debug("Validation of user failed, userId {}", userId); - responseFormat = validateUser.right().value(); - componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat); - return Either.right(responseFormat); - } - user = validateUser.left().value(); - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - if (componentTypeEnum == null) { - log.debug("Cannot create category for component type {}", componentType); - responseFormat = componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, "component type"); - componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat); - return Either.right(responseFormat); - } - - NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY); - Either, ActionStatus> getAllCategoriesByType = elementOperation.getAllCategories(nodeTypeEnum, false); - if (getAllCategoriesByType.isRight()) { - responseFormat = componentsUtils.getResponseFormat(getAllCategoriesByType.right().value()); - componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat); - return Either.right(responseFormat); - } - List categories = getAllCategoriesByType.left().value(); - responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); - componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat); - return Either.left(categories); - } - - public Either deleteCategory(String categoryId, String componentTypeParamName, String userId) { - - Either resp = validateUserExists(userId, "delete Category", false); - if (resp.isRight()) { - return Either.right(resp.right().value()); - } - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); - if (componentTypeEnum == null) { - log.debug("Cannot create category for component type {}", componentTypeParamName); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY); - - Either deleteCategoryByType = elementOperation.deleteCategory(nodeTypeEnum, categoryId); - if (deleteCategoryByType.isRight()) { - // auditing, logging here... - return Either.right(componentsUtils.getResponseFormat(deleteCategoryByType.right().value())); - } - CategoryDefinition category = deleteCategoryByType.left().value(); - log.debug("Delete category for component {}, name {}, uniqueId {}", nodeTypeEnum, category.getName(), category.getUniqueId()); - return Either.left(category); - } - - public Either deleteSubCategory(String grandParentCategoryId, String parentSubCategoryId, String componentTypeParamName, String userId) { - - Either resp = validateUserExists(userId, "delete Sub Category", false); - if (resp.isRight()) { - return Either.right(resp.right().value()); - } - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); - if (componentTypeEnum == null) { - log.debug("Cannot delete sub-category for component type {}", componentTypeParamName); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY); - - Either deleteSubCategoryByType = elementOperation.deleteSubCategory(nodeTypeEnum, parentSubCategoryId); - if (deleteSubCategoryByType.isRight()) { - // auditing, logging here... - return Either.right(componentsUtils.getResponseFormat(deleteSubCategoryByType.right().value())); - } - SubCategoryDefinition subCategory = deleteSubCategoryByType.left().value(); - log.debug("Deleted sub-category for component {}, name {}, uniqueId {}", nodeTypeEnum, subCategory.getName(), subCategory.getUniqueId()); - return Either.left(subCategory); - } - - public Either deleteGrouping(String grandParentCategoryId, String parentSubCategoryId, String groupingId, String componentTypeParamName, String userId) { - - Either resp = validateUserExists(userId, "delete Grouping", false); - if (resp.isRight()) { - return Either.right(resp.right().value()); - } - - ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); - if (componentTypeEnum == null) { - log.debug("Cannot delete grouping for component type {}", componentTypeParamName); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.GROUPING); - - Either deleteGroupingByType = elementOperation.deleteGrouping(nodeTypeEnum, groupingId); - if (deleteGroupingByType.isRight()) { - // auditing, logging here... - return Either.right(componentsUtils.getResponseFormat(deleteGroupingByType.right().value())); - } - GroupingDefinition deletedGrouping = deleteGroupingByType.left().value(); - log.debug("Deleted grouping for component {}, name {}, uniqueId {}", nodeTypeEnum, deletedGrouping.getName(), deletedGrouping.getUniqueId()); - return Either.left(deletedGrouping); - } - - private Either validateUser(String userId) { - - // validate user exists - if (userId == null) { - log.debug("User id is null"); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION)); - } - - Either userResult = userAdminManager.getUser(userId, false); - if (userResult.isRight()) { - ResponseFormat responseFormat; - if (userResult.right().value().equals(ActionStatus.USER_NOT_FOUND)) { - log.debug("Not authorized user, userId = {}", userId); - responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); - } else { - log.debug("Failed to authorize user, userId = {}", userId); - responseFormat = componentsUtils.getResponseFormat(userResult.right().value()); - } - - return Either.right(responseFormat); - } - return Either.left(userResult.left().value()); - // ========================================- - } - - private Either validateUserRole(User user, ComponentTypeEnum componentTypeEnum) { - String role = user.getRole(); - boolean validAdminAction = (role.equals(Role.ADMIN.name()) && (componentTypeEnum == ComponentTypeEnum.SERVICE || componentTypeEnum == ComponentTypeEnum.RESOURCE)); - boolean validProductAction = (role.equals(Role.PRODUCT_STRATEGIST.name()) && (componentTypeEnum == ComponentTypeEnum.PRODUCT)); - - if (!(validAdminAction || validProductAction)) { - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); - log.debug("User not permitted to perform operation on category, userId = {}, role = {}, componentType = {}", user.getUserId(), role, componentTypeEnum); - return Either.right(responseFormat); - } - return Either.left(true); - } - - private Either validateComponentTypeForCategory(ComponentTypeEnum componentType, CategoryTypeEnum categoryType) { - boolean validResourceAction = (componentType == ComponentTypeEnum.RESOURCE && (categoryType == CategoryTypeEnum.CATEGORY || categoryType == CategoryTypeEnum.SUBCATEGORY)); - boolean validServiceAction = (componentType == ComponentTypeEnum.SERVICE && categoryType == CategoryTypeEnum.CATEGORY); - boolean validProductAction = (componentType == ComponentTypeEnum.PRODUCT); // can - // be - // any - // category - // type - - if (!(validResourceAction || validServiceAction || validProductAction)) { - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); - log.debug("It's not allowed to create category type {} for component type {}", categoryType, componentType); - return Either.right(responseFormat); - } - return Either.left(true); - } - - private Either validateCategoryExists(NodeTypeEnum nodeType, String categoryId, ComponentTypeEnum componentType) { - Either categoryByTypeAndId = elementOperation.getCategory(nodeType, categoryId); - if (categoryByTypeAndId.isRight()) { - log.debug("Failed to fetch parent category, parent categoryId {}", categoryId); - ActionStatus actionStatus = categoryByTypeAndId.right().value(); - ResponseFormat responseFormat; - if (actionStatus == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND) { - responseFormat = componentsUtils.getResponseFormat(actionStatus, componentType.getValue().toLowerCase(), CategoryTypeEnum.CATEGORY.getValue(), ""); - } else { - responseFormat = componentsUtils.getResponseFormat(actionStatus); - } - return Either.right(responseFormat); - } - return Either.left(categoryByTypeAndId.left().value()); - } - - private Either validateSubCategoryExists(NodeTypeEnum nodeType, String subCategoryId, ComponentTypeEnum componentType) { - Either subCategoryByTypeAndId = elementOperation.getSubCategory(nodeType, subCategoryId); - if (subCategoryByTypeAndId.isRight()) { - log.debug("Failed to fetch parent category, parent categoryId {}", subCategoryId); - ActionStatus actionStatus = subCategoryByTypeAndId.right().value(); - ResponseFormat responseFormat; - if (actionStatus == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND) { - responseFormat = componentsUtils.getResponseFormat(actionStatus, componentType.getValue().toLowerCase(), CategoryTypeEnum.SUBCATEGORY.getValue(), ""); - } else { - responseFormat = componentsUtils.getResponseFormat(actionStatus); - } - return Either.right(responseFormat); - } - return Either.left(subCategoryByTypeAndId.left().value()); - } - - private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, AuditingActionEnum auditingAction, String componentType) { - componentsUtils.auditCategory(responseFormat, user, category, null, null, auditingAction, componentType); - } - - private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, String subCategory, AuditingActionEnum auditingAction, String componentType) { - componentsUtils.auditCategory(responseFormat, user, category, subCategory, null, auditingAction, componentType); - } - - private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, String subCategory, String grouping, AuditingActionEnum auditingAction, String componentType) { - componentsUtils.auditCategory(responseFormat, user, category, subCategory, grouping, auditingAction, componentType); - } - - /* - * New categories flow - end - */ - - public Either, ActionStatus> getAllTags(String userId) { - Either resp = validateUserExistsActionStatus(userId, "get All Tags"); - if (resp.isRight()) { - return Either.right(resp.right().value()); - } - return elementOperation.getAllTags(); - } - - public Either, ActionStatus> getAllPropertyScopes(String userId) { - Either resp = validateUserExistsActionStatus(userId, "get All Property Scopes"); - if (resp.isRight()) { - return Either.right(resp.right().value()); - } - return elementOperation.getAllPropertyScopes(); - } - - public Either, ActionStatus> getAllArtifactTypes(String userId) { - Either resp = validateUserExistsActionStatus(userId, "get All Artifact Types"); - if (resp.isRight()) { - return Either.right(resp.right().value()); - } - return elementOperation.getAllArtifactTypes(); - } - - public Either, ActionStatus> getAllDeploymentArtifactTypes() { - return elementOperation.getAllDeploymentArtifactTypes(); - } - - public Either getDefaultHeatTimeout() { - return elementOperation.getDefaultHeatTimeout(); - } - - public Either>, ResponseFormat> getCatalogComponents(String userId) { - Either resp = validateUserExists(userId, "get Catalog Components", false); - if (resp.isRight()) { - return Either.right(resp.right().value()); - } - Map> resMap = new HashMap<>(); - - Either, StorageOperationStatus> resResources = resourceOperation.getResourceCatalogData(false); - if (resResources.isLeft()) { - Either, StorageOperationStatus> resServices = serviceOperation.getServiceCatalogData(false); - if (resServices.isLeft()) { - Either, StorageOperationStatus> resProducts = productOperation.getProductCatalogData(false); - if (resProducts.isLeft()) { - resMap.put("resources", resResources.left().value()); - resMap.put("services", resServices.left().value()); - resMap.put("products", resProducts.left().value()); - return Either.left(resMap); - } else { - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resProducts.right().value()))); - } - } else { - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resServices.right().value()))); - } - } else { - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resResources.right().value()))); - } - } - - public Either, ResponseFormat> getFilteredCatalogComponents(String assetType, Map filters, String query) { - ComponentTypeEnum assetTypeEnum = AssetTypeEnum.convertToComponentTypeEnum(assetType); - - if (query != null) { - Optional invalidFilter = findInvalidFilter(query, assetTypeEnum); - if (invalidFilter.isPresent()) { - log.debug("getFilteredAssetList: invalid filter key"); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_FILTER_KEY, invalidFilter.get().getName(), FilterKeyEnum.getValidFiltersByAssetType(assetTypeEnum).toString())); - } - } - - if (filters == null || filters.isEmpty()) { - return getCatalogComponentsByAssetType(assetTypeEnum); - } - - ComponentOperation componentOperation = getComponentOperation(assetTypeEnum); - Either, StorageOperationStatus> result = componentOperation.getFilteredComponents(filters, false); - - if (result.isRight()) {// category hierarchy mismatch or - // category/subCategory/distributionStatus not - // found - List params = getErrorResponseParams(filters, assetTypeEnum); - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value()), params.get(0), params.get(1), params.get(2))); - } - if (result.left().value().isEmpty()) {// no assets found for requested - // criteria - return Either.right(componentsUtils.getResponseFormat(ActionStatus.NO_ASSETS_FOUND, assetType, query)); - } - return Either.left(result.left().value()); - } - - public Either, ResponseFormat> getCatalogComponentsByAssetType(ComponentTypeEnum assetTypeEnum) { - - if (assetTypeEnum == null) { - log.debug("getCatalogComponentsByAssetType: Corresponding ComponentTypeEnum not found"); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - switch (assetTypeEnum) { - case RESOURCE: - - Either, StorageOperationStatus> resourceCatalogData = resourceOperation.getResourceCatalogDataVFLatestCertifiedAndNonCertified(false); - if (resourceCatalogData.isLeft()) { - log.debug("getCatalogComponentsByAssetType: Resource fetching successful"); - return Either.left(resourceCatalogData.left().value()); - } else { - log.debug("getCatalogComponentsByAssetType: Resource fetching failed"); - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourceCatalogData.right().value()))); - } - - case SERVICE: - Either, StorageOperationStatus> serviceCatalogData = serviceOperation.getServiceCatalogDataLatestCertifiedAndNotCertified(false); - if (serviceCatalogData.isLeft()) { - log.debug("getCatalogComponentsByAssetType: Service fetching successful"); - return Either.left(serviceCatalogData.left().value()); - } else { - log.debug("getCatalogComponentsByAssetType: Service fetching failed"); - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceCatalogData.right().value()))); - } - /* - * case PRODUCT: Either, StorageOperationStatus> resCatalogData = productOperation.getProductCatalogData(false); if(resCatalogData.isLeft()){ log. debug("getCatalogComponentsByAssetType: Product fetching successful" ); - * return Either.left(resCatalogData.left().value()); }else { log. debug("getCatalogComponentsByAssetType: Product fetching failed" ); return Either.right(componentsUtils .getResponseFormat(componentsUtils.convertFromStorageResponse( - * resCatalogData.right().value()))); } - */ - default: - log.debug("Invalid Asset Type"); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - } - - // TODO new story Tal - public Either, ResponseFormat> getCatalogComponentsByUuidAndAssetType(String assetType, String uuid) { - - if (assetType == null || assetType == null) { - log.debug("getCatalogComponentsByUuidAndAssetType: One of the function parameteres is null"); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - ComponentTypeEnum assetTypeEnum = AssetTypeEnum.convertToComponentTypeEnum(assetType); - - if (assetTypeEnum == null) { - log.debug("getCatalogComponentsByUuidAndAssetType: Corresponding ComponentTypeEnum not found"); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - - switch (assetTypeEnum) { - - case RESOURCE: - Either, StorageOperationStatus> resourceListByUuid = resourceOperation.getLatestResourceByUuid(uuid, false); - - if (resourceListByUuid.isLeft()) { - log.debug("getCatalogComponentsByUuidAndAssetType: Resource fetching successful"); - return Either.left(resourceListByUuid.left().value()); - } - - ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(resourceListByUuid.right().value()); - log.debug("getCatalogComponentsByUuidAndAssetType: Resource fetching failed"); - return Either.right(componentsUtils.getResponseFormat(actionStatus)); - - case SERVICE: - Either, StorageOperationStatus> serviceCatalogData = serviceOperation.getLatestServiceByUuid(uuid, false); - - if (serviceCatalogData.isLeft()) { - log.debug("getCatalogComponentsByUuidAndAssetType: Service fetching successful"); - return Either.left(serviceCatalogData.left().value()); - } - - log.debug("getCatalogComponentsByUuidAndAssetType: Service fetching failed"); - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceCatalogData.right().value()))); - // case Product is for future US - /* - * case PRODUCT: Either, StorageOperationStatus> resCatalogData = productOperation.getProductCatalogData(false); if(resCatalogData.isLeft()){ log. debug("getCatalogComponentsByAssetType: Product fetching successful" ); return - * Either.left(resCatalogData.left().value()); }else { log. debug("getCatalogComponentsByAssetType: Product fetching failed" ); return Either.right(componentsUtils .getResponseFormat(componentsUtils.convertFromStorageResponse( - * resCatalogData.right().value()))); } - */ - default: - log.debug("Invalid Asset Type"); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); - } - } - - public List getAllComponentTypesParamNames() { - List paramNames = new ArrayList<>(); - paramNames.add(ComponentTypeEnum.SERVICE_PARAM_NAME); - paramNames.add(ComponentTypeEnum.RESOURCE_PARAM_NAME); - paramNames.add(ComponentTypeEnum.PRODUCT_PARAM_NAME); - return paramNames; - } - - public List getAllSupportedRoles() { - Role[] values = Role.values(); - List roleNames = new ArrayList<>(); - for (Role role : values) { - roleNames.add(role.name()); - } - return roleNames; - } - - public Either, ActionStatus> getResourceTypesMap() { - return elementOperation.getResourceTypesMap(); - } - - private Optional findInvalidFilter(String query, ComponentTypeEnum assetType) { - List params = URLEncodedUtils.parse(query, StandardCharsets.UTF_8); - List validKeys = FilterKeyEnum.getValidFiltersByAssetType(assetType); - Predicate noMatch = p -> !validKeys.contains(p.getName()); - return params.stream().filter(noMatch).findAny(); - } - - private List getErrorResponseParams(Map filters, ComponentTypeEnum assetType) { - List params = new ArrayList(); - if (1 == filters.size()) { - params.add(assetType.getValue().toLowerCase()); - params.add(filters.keySet().iterator().next().getName()); - params.add(filters.values().iterator().next()); - } else { - params.add(assetType.getValue()); - params.add(filters.get(FilterKeyEnum.SUB_CATEGORY)); - params.add(filters.get(FilterKeyEnum.CATEGORY)); - } - return params; - } - + private static final Logger log = Logger.getLogger(ElementBusinessLogic.class); + private static final String SERVICES = "services"; + private static final String RESOURCES = "resources"; + private static final String VALIDATION_OF_USER_FAILED_USER_ID = "Validation of user failed, userId {}"; + private static final String COMPONENT_TYPE_IS_INVALID = "Component type {} is invalid"; + private static final String VALIDATION_OF_USER_ROLE_FAILED_USER_ID = "Validation of user role failed, userId {}"; + private final IElementOperation elementOperation; + + @Autowired + public ElementBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation, + IGroupTypeOperation groupTypeOperation, GroupBusinessLogic groupBusinessLogic, InterfaceOperation interfaceOperation, + InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsOperations artifactToscaOperation, + IElementOperation elementOperation, UserBusinessLogic userAdminManager) { + super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation, + artifactToscaOperation); + this.elementOperation = elementOperation; + } + + /** + * @param user + * @return + */ + public Either>, ResponseFormat> getFollowed(User user) { + // Used for not getting duplicated followed. Cheaper than checking ArrayList.contains + Either>, ResponseFormat> response = null; + // Getting the role + String role = user.getRole(); + String userId = user.getUserId(); + Role currentRole = Role.valueOf(role); + switch (currentRole) { + case DESIGNER: + response = handleDesigner(userId); + break; + case PRODUCT_STRATEGIST: + response = handleProductStrategist(); + break; + case PRODUCT_MANAGER: + response = handleProductManager(userId); + break; + case ADMIN: + response = handleAdmin(); + break; + default: + response = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + break; + } + // 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) + return convertedToListResponse(response); + } + + private Either>, ResponseFormat> convertedToListResponse( + Either>, ResponseFormat> setResponse) { + Map> arrayResponse = new HashMap<>(); + if (setResponse.isLeft()) { + for (Map.Entry> entry : setResponse.left().value().entrySet()) { + arrayResponse.put(entry.getKey(), new ArrayList(new HashSet(entry.getValue()))); + } + return Either.left(arrayResponse); + } + return Either.right(setResponse.right().value()); + } + + private Either>, ResponseFormat> handleAdmin() { + Either>, ResponseFormat> response; + // userId should stay null + Set lifecycleStates = new HashSet<>(); + lifecycleStates.add(LifecycleStateEnum.CERTIFIED); + response = getFollowedResourcesAndServices(null, lifecycleStates, new HashSet<>()); + return response; + } + + private Either>, ResponseFormat> handleDesigner(String userId) { + Set lifecycleStates = new HashSet<>(); + Set lastStateStates = new HashSet<>(); + Either>, ResponseFormat> response; + lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + lifecycleStates.add(LifecycleStateEnum.CERTIFIED); + // more states + lastStateStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + response = getFollowedResourcesAndServices(userId, lifecycleStates, lastStateStates); + return response; + } + + private Either>, ResponseFormat> handleProductStrategist() { + // Should be empty list according to Ella, 13/03/16 + Map> result = new HashMap<>(); + result.put("products", new HashSet<>()); + return Either.left(result); + } + + private Either>, ResponseFormat> handleProductManager(String userId) { + Set lifecycleStates = new HashSet<>(); + Set lastStateStates = new HashSet<>(); + Either>, ResponseFormat> response; + lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + lifecycleStates.add(LifecycleStateEnum.CERTIFIED); + // more states + lastStateStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + response = getFollowedProducts(userId, lifecycleStates, lastStateStates); + return response; + } + + private Either>, ResponseFormat> getFollowedResourcesAndServices(String userId, + Set lifecycleStates, + Set lastStateStates) { + try { + Either, StorageOperationStatus> resources = toscaOperationFacade + .getFollowed(userId, lifecycleStates, lastStateStates, ComponentTypeEnum.RESOURCE); + if (resources.isLeft()) { + Either, StorageOperationStatus> services = toscaOperationFacade + .getFollowed(userId, lifecycleStates, lastStateStates, ComponentTypeEnum.SERVICE); + if (services.isLeft()) { + Map> result = new HashMap<>(); + result.put(SERVICES, services.left().value()); + result.put(RESOURCES, resources.left().value()); + return Either.left(result); + } else { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(services.right().value()))); + } + } else { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resources.right().value()))); + } + } finally { + janusGraphDao.commit(); + } + } + + private Either>, ResponseFormat> getFollowedProducts(String userId, Set lifecycleStates, + Set lastStateStates) { + Either, StorageOperationStatus> products = toscaOperationFacade + .getFollowed(userId, lifecycleStates, lastStateStates, ComponentTypeEnum.PRODUCT); + if (products.isLeft()) { + Map> result = new HashMap<>(); + result.put("products", products.left().value()); + return Either.left(result); + } else { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(products.right().value()))); + } + } + + /* + * New categories flow - start + */ + public Either, ActionStatus> getAllResourceCategories() { + return elementOperation.getAllResourceCategories(); + } + + + public Either createCategory(CategoryDefinition category, String componentTypeParamName, String userId) { + AuditingActionEnum auditingAction = AuditingActionEnum.ADD_CATEGORY; + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); + String componentType = componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue(); + CategoryTypeEnum categoryType = CategoryTypeEnum.CATEGORY; + User user = validateUserExists(userId); + if (category == null) { + log.debug("Category json is invalid"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + handleCategoryAuditing(responseFormat, user, null, auditingAction, componentType); + return Either.right(responseFormat); + } + String categoryName = category.getName(); + // For auditing of failures we need the original non-normalized name + String origCategoryName = categoryName; + if (componentTypeEnum == null) { + log.debug(COMPONENT_TYPE_IS_INVALID, componentTypeParamName); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + Either validateUserRole = validateUserRole(user, componentTypeEnum); + if (validateUserRole.isRight()) { + log.debug(VALIDATION_OF_USER_ROLE_FAILED_USER_ID, userId); + ResponseFormat responseFormat = validateUserRole.right().value(); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + if (!ValidationUtils.validateCategoryDisplayNameFormat(categoryName)) { + log.debug("Category display name format is invalid, name {}, componentType {}", categoryName, componentType); + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue()); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + categoryName = ValidationUtils.normalizeCategoryName4Display(categoryName); + if (!ValidationUtils.validateCategoryDisplayNameLength(categoryName)) { + log.debug("Category display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", categoryName, + componentType); + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue()); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + category.setName(categoryName); + String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(categoryName); + category.setNormalizedName(normalizedName); + if (ValidationUtils.validateCategoryIconNotEmpty(category.getIcons())) { + log.debug("createCategory: setting category icon to default icon since service category was created without an icon "); + category.setIcons(Arrays.asList(DEFAULT_ICON)); + } + NodeTypeEnum nodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, categoryType); + Either categoryUniqueEither = elementOperation.isCategoryUniqueForType(nodeType, normalizedName); + if (categoryUniqueEither.isRight()) { + log.debug("Failed to check category uniqueness, name {}, componentType {}", categoryName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(categoryUniqueEither.right().value()); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + Boolean isCategoryUnique = categoryUniqueEither.left().value(); + if (Boolean.FALSE.equals(isCategoryUnique)) { + log.debug("Category is not unique, name {}, componentType {}", categoryName, componentType); + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, componentType, categoryName); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + Either createCategoryByType = elementOperation.createCategory(category, nodeType); + if (createCategoryByType.isRight()) { + log.debug("Failed to create category, name {}, componentType {}", categoryName, componentType); + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, componentType, categoryName); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(componentsUtils.getResponseFormat(createCategoryByType.right().value())); + } + category = createCategoryByType.left().value(); + log.debug("Created category for component {}, name {}, uniqueId {}", componentType, categoryName, category.getUniqueId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + handleCategoryAuditing(responseFormat, user, category.getName(), auditingAction, componentType); + return Either.left(category); + } + + public Either createSubCategory(SubCategoryDefinition subCategory, String componentTypeParamName, + String parentCategoryId, String userId) { + AuditingActionEnum auditingAction = AuditingActionEnum.ADD_SUB_CATEGORY; + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); + String componentType = componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue(); + CategoryTypeEnum categoryType = CategoryTypeEnum.SUBCATEGORY; + // For auditing + String parentCategoryName = parentCategoryId; + if (subCategory == null) { + log.debug("Sub-category json is invalid"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + handleCategoryAuditing(responseFormat, null, parentCategoryName, null, auditingAction, componentType); + return Either.right(responseFormat); + } + String subCategoryName = subCategory.getName(); + // For auditing of failures we need the original non-normalized name + String origSubCategoryName = subCategoryName; + User user; + try { + user = validateUserExists(userId); + } catch (ByActionStatusComponentException e) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()); + handleComponentException(userId, auditingAction, componentType, parentCategoryName, origSubCategoryName, responseFormat); + throw e; + } catch (ByResponseFormatComponentException e) { + ResponseFormat responseFormat = e.getResponseFormat(); + handleComponentException(userId, auditingAction, componentType, parentCategoryName, origSubCategoryName, responseFormat); + throw e; + } + if (componentTypeEnum == null) { + log.debug(COMPONENT_TYPE_IS_INVALID, componentTypeParamName); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + Either validateComponentType = validateComponentTypeForCategory(componentTypeEnum, categoryType); + if (validateComponentType.isRight()) { + log.debug("Validation of component type for sub-category failed"); + ResponseFormat responseFormat = validateComponentType.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + Either validateUserRole = validateUserRole(user, componentTypeEnum); + if (validateUserRole.isRight()) { + log.debug(VALIDATION_OF_USER_ROLE_FAILED_USER_ID, userId); + ResponseFormat responseFormat = validateUserRole.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + NodeTypeEnum parentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY); + NodeTypeEnum childNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY); + CategoryDefinition categoryDefinition; + Either validateCategoryExists = validateCategoryExists(parentNodeType, parentCategoryId, + componentTypeEnum); + if (validateCategoryExists.isRight()) { + log.debug("Validation of parent category exists failed, parent categoryId {}", parentCategoryId); + ResponseFormat responseFormat = validateCategoryExists.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + categoryDefinition = validateCategoryExists.left().value(); + parentCategoryName = categoryDefinition.getName(); + if (!ValidationUtils.validateCategoryDisplayNameFormat(subCategoryName)) { + log.debug("Sub-category display name format is invalid, name {}, componentType {}", subCategoryName, componentType); + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + subCategoryName = ValidationUtils.normalizeCategoryName4Display(subCategoryName); + if (!ValidationUtils.validateCategoryDisplayNameLength(subCategoryName)) { + log.debug("Sub-category display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", subCategoryName, + componentType); + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(subCategoryName); + subCategory.setNormalizedName(normalizedName); + // Uniqueness under this category + Either subCategoryUniqueForCategory = elementOperation + .isSubCategoryUniqueForCategory(childNodeType, normalizedName, parentCategoryId); + if (subCategoryUniqueForCategory.isRight()) { + log.debug("Failed to check sub-category uniqueness, parent name {}, subcategory norm name {}, componentType {}", parentCategoryName, + normalizedName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForCategory.right().value()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + Boolean isSubUnique = subCategoryUniqueForCategory.left().value(); + if (Boolean.FALSE.equals(isSubUnique)) { + log.debug("Sub-category is not unique for category, parent name {}, subcategory norm name {}, componentType {}", parentCategoryName, + normalizedName, componentType); + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY, componentType, subCategoryName, parentCategoryName); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + // Setting name of subcategory to fit the similar subcategory name + + // ignoring cases. + + // For example if Network-->kUKU exists for service category Network, + + // and user is trying to create Router-->Kuku for service category + + // Router, + + // his subcategory name will be Router-->kUKU. + Either subCategoryUniqueForType = elementOperation + .getSubCategoryUniqueForType(childNodeType, normalizedName); + if (subCategoryUniqueForType.isRight()) { + log.debug("Failed validation of whether similar sub-category exists, normalizedName {} componentType {}", normalizedName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForType.right().value()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + SubCategoryDefinition subCategoryDefinition = subCategoryUniqueForType.left().value(); + if (subCategoryDefinition != null) { + subCategoryName = subCategoryDefinition.getName(); + } + subCategory.setName(subCategoryName); + ///////////////////////////////////////////// Validations end + Either createSubCategory = elementOperation + .createSubCategory(parentCategoryId, subCategory, childNodeType); + if (createSubCategory.isRight()) { + log.debug("Failed to create sub-category, name {}, componentType {}", subCategoryName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForType.right().value()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + SubCategoryDefinition subCategoryCreated = createSubCategory.left().value(); + log.debug("Created sub-category for component {}, name {}, uniqueId {}", componentType, subCategoryName, subCategoryCreated.getUniqueId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + handleCategoryAuditing(responseFormat, user, parentCategoryName, subCategoryCreated.getName(), auditingAction, componentType); + return Either.left(subCategoryCreated); + } + + private void handleComponentException(String userId, AuditingActionEnum auditingAction, String componentType, String parentCategoryName, + String origSubCategoryName, ResponseFormat responseFormat) { + User user; + log.debug(VALIDATION_OF_USER_FAILED_USER_ID, userId); + user = new User(); + user.setUserId(userId); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + } + + private void handleComponentException(GroupingDefinition grouping, String userId, AuditingActionEnum auditingAction, String componentType, + String parentCategoryName, String parentSubCategoryName, ResponseFormat responseFormat) { + User user; + log.debug(VALIDATION_OF_USER_FAILED_USER_ID, userId); + user = new User(); + user.setUserId(userId); + String groupingNameForAudit = grouping == null ? null : grouping.getName(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, groupingNameForAudit, auditingAction, componentType); + } + + private void handleComponentException(String componentType, String userId, ResponseFormat responseFormat) { + User user; + user = new User(); + user.setUserId(userId); + log.debug(VALIDATION_OF_USER_FAILED_USER_ID, userId); + componentsUtils.auditGetCategoryHierarchy(user, componentType, responseFormat); + } + + public Either createGrouping(GroupingDefinition grouping, String componentTypeParamName, + String grandParentCategoryId, String parentSubCategoryId, String userId) { + AuditingActionEnum auditingAction = AuditingActionEnum.ADD_GROUPING; + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); + String componentType = componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue(); + CategoryTypeEnum categoryType = CategoryTypeEnum.GROUPING; + // For auditing + String parentCategoryName = grandParentCategoryId; + String parentSubCategoryName = parentSubCategoryId; + User user; + try { + user = validateUserExists(userId); + } catch (ByResponseFormatComponentException e) { + ResponseFormat responseFormat = e.getResponseFormat(); + handleComponentException(grouping, userId, auditingAction, componentType, parentCategoryName, parentSubCategoryName, responseFormat); + throw e; + } catch (ByActionStatusComponentException e) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()); + handleComponentException(grouping, userId, auditingAction, componentType, parentCategoryName, parentSubCategoryName, responseFormat); + throw e; + } + if (grouping == null) { + log.debug("Grouping json is invalid"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, null, auditingAction, componentType); + return Either.right(responseFormat); + } + String groupingName = grouping.getName(); + // For auditing of failures we need the original non-normalized name + String origGroupingName = groupingName; + if (componentTypeEnum == null) { + log.debug(COMPONENT_TYPE_IS_INVALID, componentTypeParamName); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + Either validateComponentType = validateComponentTypeForCategory(componentTypeEnum, categoryType); + if (validateComponentType.isRight()) { + log.debug("Validation of component type for grouping failed"); + ResponseFormat responseFormat = validateComponentType.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + Either validateUserRole = validateUserRole(user, componentTypeEnum); + if (validateUserRole.isRight()) { + log.debug(VALIDATION_OF_USER_ROLE_FAILED_USER_ID, userId); + ResponseFormat responseFormat = validateUserRole.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + NodeTypeEnum grandParentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY); + NodeTypeEnum parentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY); + NodeTypeEnum childNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.GROUPING); + // Validate category + CategoryDefinition categoryDefinition; + Either validateCategoryExists = validateCategoryExists(grandParentNodeType, grandParentCategoryId, + componentTypeEnum); + if (validateCategoryExists.isRight()) { + log.debug("Validation of parent category exists failed, parent categoryId {}", grandParentCategoryId); + ResponseFormat responseFormat = validateCategoryExists.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + categoryDefinition = validateCategoryExists.left().value(); + parentCategoryName = categoryDefinition.getName(); + // Validate subcategory + SubCategoryDefinition subCategoryDefinition; + Either validateSubCategoryExists = validateSubCategoryExists(parentNodeType, parentSubCategoryId, + componentTypeEnum); + if (validateSubCategoryExists.isRight()) { + log.debug("Validation of parent sub-category exists failed, parent sub-category id {}", parentSubCategoryId); + ResponseFormat responseFormat = validateSubCategoryExists.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + subCategoryDefinition = validateSubCategoryExists.left().value(); + parentSubCategoryName = subCategoryDefinition.getName(); + if (!ValidationUtils.validateCategoryDisplayNameFormat(groupingName)) { + log.debug("Sub-category display name format is invalid, name {}, componentType {}", groupingName, componentType); + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + groupingName = ValidationUtils.normalizeCategoryName4Display(groupingName); + if (!ValidationUtils.validateCategoryDisplayNameLength(groupingName)) { + log.debug("Grouping display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", groupingName, + componentType); + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(groupingName); + grouping.setNormalizedName(normalizedName); + // Uniqueness under this category + Either groupingUniqueForSubCategory = elementOperation + .isGroupingUniqueForSubCategory(childNodeType, normalizedName, parentSubCategoryId); + if (groupingUniqueForSubCategory.isRight()) { + log.debug("Failed to check grouping uniqueness, parent name {}, grouping norm name {}, componentType {}", parentSubCategoryName, + normalizedName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(groupingUniqueForSubCategory.right().value()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + Boolean isGroupingUnique = groupingUniqueForSubCategory.left().value(); + if (Boolean.FALSE.equals(isGroupingUnique)) { + log.debug("Grouping is not unique for sub-category, parent name {}, grouping norm name {}, componentType {}", parentSubCategoryName, + normalizedName, componentType); + ResponseFormat responseFormat = componentsUtils + .getResponseFormat(ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY, componentType, groupingName, parentSubCategoryName); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + // Setting name of grouping to fit the similar grouping name ignoring + + // cases. + + // For example if Network-->kUKU exists for service sub-category + + // Network, and user is trying to create grouping Router-->Kuku for + + // service sub-category Router, + + // his grouping name will be Router-->kUKU. + Either groupingUniqueForType = elementOperation.getGroupingUniqueForType(childNodeType, normalizedName); + if (groupingUniqueForType.isRight()) { + log.debug("Failed validation of whether similar grouping exists, normalizedName {} componentType {}", normalizedName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(groupingUniqueForType.right().value()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + GroupingDefinition groupingDefinition = groupingUniqueForType.left().value(); + if (groupingDefinition != null) { + groupingName = groupingDefinition.getName(); + } + grouping.setName(groupingName); + ///////////////////////////////////////////// Validations end + Either createGrouping = elementOperation.createGrouping(parentSubCategoryId, grouping, childNodeType); + if (createGrouping.isRight()) { + log.debug("Failed to create grouping, name {}, componentType {}", groupingName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(createGrouping.right().value()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + GroupingDefinition groupingCreated = createGrouping.left().value(); + log.debug("Created grouping for component {}, name {}, uniqueId {}", componentType, groupingName, groupingCreated.getUniqueId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, groupingCreated.getName(), auditingAction, + componentType); + return Either.left(groupingCreated); + } + + public Either, ResponseFormat> getAllCategories(String componentType, String userId) { + ResponseFormat responseFormat; + User user = new User(); + if (userId == null) { + user.setUserId("UNKNOWN"); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); + componentsUtils.auditGetCategoryHierarchy(user, componentType, responseFormat); + return Either.right(responseFormat); + } + try { + user = validateUserExists(userId); + } catch (ByActionStatusComponentException e) { + responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams()); + handleComponentException(componentType, userId, responseFormat); + throw e; + } catch (ByResponseFormatComponentException e) { + responseFormat = e.getResponseFormat(); + handleComponentException(componentType, userId, responseFormat); + throw e; + } + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + if (componentTypeEnum == null) { + log.debug("Cannot create category for component type {}", componentType); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, "component type"); + componentsUtils.auditGetCategoryHierarchy(user, componentType, responseFormat); + return Either.right(responseFormat); + } + NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY); + Either, ActionStatus> getAllCategoriesByType = elementOperation.getAllCategories(nodeTypeEnum, false); + if (getAllCategoriesByType.isRight()) { + responseFormat = componentsUtils.getResponseFormat(getAllCategoriesByType.right().value()); + componentsUtils.auditGetCategoryHierarchy(user, componentType, responseFormat); + return Either.right(responseFormat); + } + List categories = getAllCategoriesByType.left().value(); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + componentsUtils.auditGetCategoryHierarchy(user, componentType, responseFormat); + return Either.left(categories); + } + + public Either getAllCategories(String userId) { + ResponseFormat responseFormat; + UiCategories categories = new UiCategories(); + User user = validateUserExists(userId); + // GET resource categories + Either, ActionStatus> getResourceCategoriesByType = elementOperation + .getAllCategories(NodeTypeEnum.ResourceNewCategory, false); + if (getResourceCategoriesByType.isRight()) { + responseFormat = componentsUtils.getResponseFormat(getResourceCategoriesByType.right().value()); + componentsUtils.auditGetCategoryHierarchy(user, ComponentTypeEnum.RESOURCE.getValue(), responseFormat); + return Either.right(responseFormat); + } + categories.setResourceCategories(getResourceCategoriesByType.left().value()); + // GET service categories + Either, ActionStatus> getServiceCategoriesByType = elementOperation + .getAllCategories(NodeTypeEnum.ServiceNewCategory, false); + if (getServiceCategoriesByType.isRight()) { + responseFormat = componentsUtils.getResponseFormat(getServiceCategoriesByType.right().value()); + componentsUtils.auditGetCategoryHierarchy(user, ComponentTypeEnum.SERVICE.getValue(), responseFormat); + return Either.right(responseFormat); + } + categories.setServiceCategories(getServiceCategoriesByType.left().value()); + categories.setProductCategories(new ArrayList<>()); + return Either.left(categories); + } + + public Either deleteCategory(String categoryId, String componentTypeParamName, String userId) { + validateUserExists(userId); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); + if (componentTypeEnum == null) { + log.debug("Cannot create category for component type {}", componentTypeParamName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY); + Either deleteCategoryByType = elementOperation.deleteCategory(nodeTypeEnum, categoryId); + if (deleteCategoryByType.isRight()) { + // auditing, logging here... + return Either.right(componentsUtils.getResponseFormat(deleteCategoryByType.right().value())); + } + CategoryDefinition category = deleteCategoryByType.left().value(); + log.debug("Delete category for component {}, name {}, uniqueId {}", nodeTypeEnum, category.getName(), category.getUniqueId()); + return Either.left(category); + } + + public Either deleteSubCategory(String parentSubCategoryId, String componentTypeParamName, String userId) { + validateUserExists(userId); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); + if (componentTypeEnum == null) { + log.debug("Cannot delete sub-category for component type {}", componentTypeParamName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY); + Either deleteSubCategoryByType = elementOperation.deleteSubCategory(nodeTypeEnum, parentSubCategoryId); + if (deleteSubCategoryByType.isRight()) { + // auditing, logging here... + return Either.right(componentsUtils.getResponseFormat(deleteSubCategoryByType.right().value())); + } + SubCategoryDefinition subCategory = deleteSubCategoryByType.left().value(); + log.debug("Deleted sub-category for component {}, name {}, uniqueId {}", nodeTypeEnum, subCategory.getName(), subCategory.getUniqueId()); + return Either.left(subCategory); + } + + public Either deleteGrouping(String groupingId, String componentTypeParamName, String userId) { + validateUserExists(userId); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); + if (componentTypeEnum == null) { + log.debug("Cannot delete grouping for component type {}", componentTypeParamName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.GROUPING); + Either deleteGroupingByType = elementOperation.deleteGrouping(nodeTypeEnum, groupingId); + if (deleteGroupingByType.isRight()) { + // auditing, logging here... + return Either.right(componentsUtils.getResponseFormat(deleteGroupingByType.right().value())); + } + GroupingDefinition deletedGrouping = deleteGroupingByType.left().value(); + log.debug("Deleted grouping for component {}, name {}, uniqueId {}", nodeTypeEnum, deletedGrouping.getName(), deletedGrouping.getUniqueId()); + return Either.left(deletedGrouping); + } + + private Either validateUserRole(User user, ComponentTypeEnum componentTypeEnum) { + String role = user.getRole(); + boolean validAdminAction = + role.equals(Role.ADMIN.name()) && (componentTypeEnum == ComponentTypeEnum.SERVICE || componentTypeEnum == ComponentTypeEnum.RESOURCE); + boolean validProductAction = role.equals(Role.PRODUCT_STRATEGIST.name()) && (componentTypeEnum == ComponentTypeEnum.PRODUCT); + if (!(validAdminAction || validProductAction)) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + log.debug("User not permitted to perform operation on category, userId = {}, role = {}, componentType = {}", user.getUserId(), role, + componentTypeEnum); + return Either.right(responseFormat); + } + return Either.left(true); + } + + private Either validateComponentTypeForCategory(ComponentTypeEnum componentType, CategoryTypeEnum categoryType) { + boolean validResourceAction = componentType == ComponentTypeEnum.RESOURCE && (categoryType == CategoryTypeEnum.CATEGORY + || categoryType == CategoryTypeEnum.SUBCATEGORY); + boolean validServiceAction = componentType == ComponentTypeEnum.SERVICE && categoryType == CategoryTypeEnum.CATEGORY; + boolean validProductAction = componentType == ComponentTypeEnum.PRODUCT; // can + + // be + + // any + + // category + + // type + if (!(validResourceAction || validServiceAction || validProductAction)) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + log.debug("It's not allowed to create category type {} for component type {}", categoryType, componentType); + return Either.right(responseFormat); + } + return Either.left(true); + } + + private Either validateCategoryExists(NodeTypeEnum nodeType, String categoryId, + ComponentTypeEnum componentType) { + Either categoryByTypeAndId = elementOperation.getCategory(nodeType, categoryId); + if (categoryByTypeAndId.isRight()) { + log.debug("Failed to fetch parent category, parent categoryId {}", categoryId); + ActionStatus actionStatus = categoryByTypeAndId.right().value(); + ResponseFormat responseFormat; + if (actionStatus == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND) { + responseFormat = componentsUtils + .getResponseFormat(actionStatus, componentType.getValue().toLowerCase(), CategoryTypeEnum.CATEGORY.getValue(), ""); + } else { + responseFormat = componentsUtils.getResponseFormat(actionStatus); + } + return Either.right(responseFormat); + } + return Either.left(categoryByTypeAndId.left().value()); + } + + private Either validateSubCategoryExists(NodeTypeEnum nodeType, String subCategoryId, + ComponentTypeEnum componentType) { + Either subCategoryByTypeAndId = elementOperation.getSubCategory(nodeType, subCategoryId); + if (subCategoryByTypeAndId.isRight()) { + log.debug("Failed to fetch parent category, parent categoryId {}", subCategoryId); + ActionStatus actionStatus = subCategoryByTypeAndId.right().value(); + ResponseFormat responseFormat; + if (actionStatus == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND) { + responseFormat = componentsUtils + .getResponseFormat(actionStatus, componentType.getValue().toLowerCase(), CategoryTypeEnum.SUBCATEGORY.getValue(), ""); + } else { + responseFormat = componentsUtils.getResponseFormat(actionStatus); + } + return Either.right(responseFormat); + } + return Either.left(subCategoryByTypeAndId.left().value()); + } + + private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, AuditingActionEnum auditingAction, + String componentType) { + componentsUtils.auditCategory(responseFormat, user, category, null, null, auditingAction, componentType); + } + + private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, String subCategory, + AuditingActionEnum auditingAction, String componentType) { + componentsUtils.auditCategory(responseFormat, user, category, subCategory, null, auditingAction, componentType); + } + + private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, String subCategory, String grouping, + AuditingActionEnum auditingAction, String componentType) { + componentsUtils.auditCategory(responseFormat, user, category, subCategory, grouping, auditingAction, componentType); + } + + /* + * New categories flow - end + */ + public Either, ActionStatus> getAllTags(String userId) { + ActionStatus status = validateUserExistsActionStatus(userId); + if (ActionStatus.OK != status) { + return Either.right(status); + } + return elementOperation.getAllTags(); + } + + public Either, ActionStatus> getAllPropertyScopes(String userId) { + ActionStatus status = validateUserExistsActionStatus(userId); + if (ActionStatus.OK != status) { + return Either.right(status); + } + return elementOperation.getAllPropertyScopes(); + } + + public Either, ActionStatus> getAllArtifactTypes(final String userId) { + ActionStatus status = validateUserExistsActionStatus(userId); + if (ActionStatus.OK != status) { + return Either.right(status); + } + return Either.left(elementOperation.getAllArtifactTypes()); + } + + public Either getDefaultHeatTimeout() { + return elementOperation.getDefaultHeatTimeout(); + } + + public Either>, ResponseFormat> getCatalogComponents(List excludeTypes) { + try { + return toscaOperationFacade.getCatalogOrArchiveComponents(true, excludeTypes) + .bimap(this::groupByComponentType, err -> componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(err))); + } finally { + janusGraphDao.commit(); + } + } + + private Map> groupByComponentType(List components) { + Map> map = components.stream() + .collect(Collectors.groupingBy(cmpt -> cmptTypeToString(cmpt.getComponentType()))); + // fixed response for UI!!! UI need to receive always map! + if (map == null) { + map = new HashMap<>(); + } + map.computeIfAbsent(RESOURCES, k -> new ArrayList()); + map.computeIfAbsent(SERVICES, k -> new ArrayList()); + return map; + } + + private String cmptTypeToString(ComponentTypeEnum componentTypeEnum) { + switch (componentTypeEnum) { + case RESOURCE: + return RESOURCES; + case SERVICE: + return SERVICES; + default: + throw new IllegalStateException("resources or services only"); + } + } + + public Either, ResponseFormat> getFilteredCatalogComponents(String assetType, Map filters, + String query) { + ComponentTypeEnum assetTypeEnum = AssetTypeEnum.convertToComponentTypeEnum(assetType); + if (query != null) { + Optional invalidFilter = findInvalidFilter(query, assetTypeEnum); + if (invalidFilter.isPresent()) { + log.debug("getFilteredAssetList: invalid filter key"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_FILTER_KEY, invalidFilter.get().getName(), + FilterKeyEnum.getValidFiltersByAssetType(assetTypeEnum).toString())); + } + } + if (MapUtils.isEmpty(filters)) { + Either, StorageOperationStatus> componentsList = toscaOperationFacade.getCatalogComponents(assetTypeEnum, null, false); + if (componentsList.isRight()) { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(componentsList.right().value()))); + } + return Either.left(componentsList.left().value()); + } + Either, StorageOperationStatus> result = getFilteredComponents(filters, assetTypeEnum, false); + // category hierarchy mismatch or category/subCategory/distributionStatus not found + if (result.isRight()) { + List params = getErrorResponseParams(filters, assetTypeEnum); + return Either.right(componentsUtils + .getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value()), params.get(0), params.get(1), params.get(2))); + } + if (result.left().value().isEmpty()) { // no assets found for requested criteria + return Either.right(componentsUtils.getResponseFormat(ActionStatus.NO_ASSETS_FOUND, assetType, query)); + } + return Either.left(result.left().value()); + } + + private Either, StorageOperationStatus> getFilteredComponents(Map filters, ComponentTypeEnum assetType, + boolean inTransaction) { + Either, StorageOperationStatus> assetResult = Either.left(new LinkedList<>()); + if (assetType == ComponentTypeEnum.RESOURCE) { + assetResult = getFilteredResources(filters, inTransaction); + } else if (assetType == ComponentTypeEnum.SERVICE) { + assetResult = getFilteredServices(filters); + } + return assetResult; + } + + private Either, StorageOperationStatus> getFilteredServices(Map filters) { + final String distributionStatus = (String) filters.get(FilterKeyEnum.DISTRIBUTION_STATUS); + final DistributionStatusEnum distEnum; + if (StringUtils.isNotBlank(distributionStatus)) { + distEnum = DistributionStatusEnum.findState(distributionStatus); + if (distEnum == null) { + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } + } else { + distEnum = null; + } + Either, StorageOperationStatus> components = toscaOperationFacade.getCatalogComponents(ComponentTypeEnum.SERVICE, null, false); + if (components.isRight()) { // not found == empty list + return Either.left(new ArrayList<>()); + } + final String categoryName = (String) filters.get(FilterKeyEnum.CATEGORY); + Predicate servPredicate = Component::isService; + if (StringUtils.isNotBlank(categoryName)) { // primary filter + servPredicate = servPredicate.and( + p -> p.getCategories().parallelStream().map(CategoryDataDefinition::getName).collect(Collectors.toList()).contains(categoryName)); + } + if (distEnum != null) {// secondary filter + servPredicate = servPredicate.and(p -> p.getDistributionStatus() == distEnum); + } + List serviceList = components.left().value().parallelStream().filter(servPredicate).collect(Collectors.toList()); + + final String version = (String) filters.get(FilterKeyEnum.VERSION); + if (StringUtils.isNotBlank(version)) { + serviceList = filterServicesWithVersion(serviceList, version); + } + final List metadata = (List) filters.get(FilterKeyEnum.METADATA); + if (CollectionUtils.isNotEmpty(metadata)) { + serviceList = filterServicesWithMetadata(serviceList, metadata); + } + return Either.left((List) serviceList); + } + + private List filterServicesWithMetadata(final List serviceList, final List metadata) { + Predicate predicate = Component::isService; + final String regex = "[\\w\\.\\- ]"; + for (final String keyValuePair : metadata) { + final Matcher matcher = Pattern.compile("(" + regex + "+)[:=](" + regex + "+)").matcher(keyValuePair); + if (matcher.find()) { + predicate = predicate.and(service -> matcher.group(2).equals(service.getCategorySpecificMetadata().get(matcher.group(1)))); + } + } + return serviceList.stream().filter(predicate).collect(Collectors.toList()); + } + + private List filterServicesWithVersion(final List serviceList, final String version) { + String trim = version.trim(); + final Optional versionFilter = VersionFilterEnum.getFilter(trim); + if (versionFilter.isPresent()) { + return versionFilter.get().filter(serviceList, trim); + } + return serviceList; + } + + public Either, ResponseFormat> getCatalogComponentsByUuidAndAssetType(String assetType, String uuid) { + if (assetType == null || uuid == null) { + log.debug("getCatalogComponentsByUuidAndAssetType: One of the function parameteres is null"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + ComponentTypeEnum assetTypeEnum = AssetTypeEnum.convertToComponentTypeEnum(assetType); + if (assetTypeEnum == null) { + log.debug("getCatalogComponentsByUuidAndAssetType: Corresponding ComponentTypeEnum not found"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + Map additionalPropertiesToMatch = new EnumMap<>(GraphPropertyEnum.class); + switch (assetTypeEnum) { + case RESOURCE: + additionalPropertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name()); + break; + case SERVICE: + additionalPropertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name()); + break; + default: + log.debug("getCatalogComponentsByUuidAndAssetType: Corresponding ComponentTypeEnum not allowed for this API"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + Either, StorageOperationStatus> componentsListByUuid = toscaOperationFacade + .getComponentListByUuid(uuid, additionalPropertiesToMatch); + if (componentsListByUuid.isRight()) { + log.debug("getCatalogComponentsByUuidAndAssetType: " + assetTypeEnum.getValue() + " fetching failed"); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(componentsListByUuid.right().value(), assetTypeEnum); + return Either.right(componentsUtils.getResponseFormat(actionStatus, uuid)); + } + log.debug("getCatalogComponentsByUuidAndAssetType: " + assetTypeEnum.getValue() + assetTypeEnum.getValue() + "fetching successful"); + return Either.left(componentsListByUuid.left().value()); + } + + public List getAllComponentTypesParamNames() { + List paramNames = new ArrayList<>(); + paramNames.add(ComponentTypeEnum.SERVICE_PARAM_NAME); + paramNames.add(ComponentTypeEnum.RESOURCE_PARAM_NAME); + paramNames.add(ComponentTypeEnum.PRODUCT_PARAM_NAME); + return paramNames; + } + + public List getAllSupportedRoles() { + Role[] values = Role.values(); + List roleNames = new ArrayList<>(); + for (Role role : values) { + roleNames.add(role.name()); + } + return roleNames; + } + + public Either, ActionStatus> getResourceTypesMap() { + return elementOperation.getResourceTypesMap(); + } + + private Optional findInvalidFilter(String query, ComponentTypeEnum assetType) { + return URLEncodedUtils.parse(query, StandardCharsets.UTF_8) + .stream().filter(p -> !FilterKeyEnum.getValidFiltersByAssetType(assetType).contains(p.getName())).findAny(); + } + + private List getErrorResponseParams(Map filters, ComponentTypeEnum assetType) { + List params = new ArrayList<>(); + if (1 == filters.size()) { + params.add(assetType.getValue().toLowerCase()); + params.add(filters.keySet().iterator().next().getName()); + params.add((String) filters.values().iterator().next()); + } else { + params.add(assetType.getValue()); + params.add((String) filters.get(FilterKeyEnum.SUB_CATEGORY)); + params.add((String) filters.get(FilterKeyEnum.CATEGORY)); + } + return params; + } + + public Either, StorageOperationStatus> getFilteredResources(Map filters, boolean inTransaction) { + String subCategoryName = (String) filters.get(FilterKeyEnum.SUB_CATEGORY); + String categoryName = (String) filters.get(FilterKeyEnum.CATEGORY); + ResourceTypeEnum resourceType = ResourceTypeEnum.getType((String) filters.get(FilterKeyEnum.RESOURCE_TYPE)); + Either>, StorageOperationStatus> subcategories = null; + Optional> subCategoryData; + if (categoryName != null) { + subcategories = getAllSubCategories(categoryName); + if (subcategories.isRight()) { + filters.remove(FilterKeyEnum.SUB_CATEGORY); + return Either.right(subcategories.right().value()); + } + } + if (subCategoryName != null) { // primary filter + if (categoryName != null) { + subCategoryData = validateCategoryHierarcy(subcategories.left().value(), subCategoryName); + if (subCategoryData.isEmpty()) { + return Either.right(StorageOperationStatus.MATCH_NOT_FOUND); + } + return fetchByCategoryOrSubCategoryUid(subCategoryData.get().getLeft().getUniqueId(), NodeTypeEnum.Resource, inTransaction, + resourceType); + } + return fetchByCategoryOrSubCategoryName(subCategoryName, NodeTypeEnum.ResourceSubcategory, NodeTypeEnum.Resource, inTransaction, + resourceType); + } + if (subcategories != null) { + return fetchByMainCategory(subcategories.left().value(), inTransaction, resourceType); + } + return fetchComponentMetaDataByResourceType((String) filters.get(FilterKeyEnum.RESOURCE_TYPE), inTransaction); + } + + private Either>, StorageOperationStatus> getAllSubCategories(String categoryName) { + Either categoryResult = elementOperation + .getNewCategoryData(categoryName, NodeTypeEnum.ResourceNewCategory, CategoryData.class); + if (categoryResult.isRight()) { + return Either.right(categoryResult.right().value()); + } + CategoryData categoryData = categoryResult.left().value(); + Either>, JanusGraphOperationStatus> childrenNodes = janusGraphGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceNewCategory), categoryData.getUniqueId(), + GraphEdgeLabels.SUB_CATEGORY, NodeTypeEnum.ResourceSubcategory, SubCategoryData.class); + if (childrenNodes.isRight()) { + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(childrenNodes.right().value())); + } + return Either.left(childrenNodes.left().value()); + } + + private Optional> validateCategoryHierarcy(List> childNodes, + String subCategoryName) { + Predicate> matchName = p -> p.getLeft().getSubCategoryDataDefinition().getName() + .equals(subCategoryName); + return childNodes.stream().filter(matchName).findAny(); + } + + protected Either, StorageOperationStatus> fetchByCategoryOrSubCategoryUid(String categoryUid, + NodeTypeEnum categoryType, + boolean inTransaction, + ResourceTypeEnum resourceType) { + try { + return collectComponents(categoryType, categoryUid, resourceType); + } finally { + if (!inTransaction) { + janusGraphDao.commit(); + } + } + } + + protected Either, StorageOperationStatus> fetchByCategoryOrSubCategoryName(String categoryName, + NodeTypeEnum categoryType, + NodeTypeEnum neededType, + boolean inTransaction, + ResourceTypeEnum resourceType) { + List components = new ArrayList<>(); + try { + Class categoryClazz = categoryType == NodeTypeEnum.ServiceNewCategory ? CategoryData.class : SubCategoryData.class; + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), ValidationUtils.normalizeCategoryName4Uniqueness(categoryName)); + Either, JanusGraphOperationStatus> getCategory = janusGraphGenericDao.getByCriteria(categoryType, props, + (Class) categoryClazz); + if (getCategory.isRight()) { + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } + for (GraphNode category : getCategory.left().value()) { + Either, StorageOperationStatus> result = collectComponents(neededType, category.getUniqueId(), resourceType); + if (result.isRight() && result.right().value() != StorageOperationStatus.NOT_FOUND) { + return result; + } else if (result.isLeft()) { + components.addAll(result.left().value()); + } + } + if (components.isEmpty()) { + return Either.right(StorageOperationStatus.NOT_FOUND); + } + return Either.left(components); + } finally { + if (!inTransaction) { + janusGraphDao.commit(); + } + } + } + + private Either, StorageOperationStatus> collectComponents(NodeTypeEnum neededType, String categoryUid, + ResourceTypeEnum resourceType) { + List components = new ArrayList<>(); + Either categoryVertexById = janusGraphDao.getVertexById(categoryUid, JsonParseFlagEnum.NoParse); + if (categoryVertexById.isRight()) { + JanusGraphOperationStatus status = categoryVertexById.right().value(); + log.debug("#collectComponents Failed to get category vertex with uid {}, status is {}.", categoryUid, status); + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)); + } + GraphVertex categoryVertex = categoryVertexById.left().value(); + Either, JanusGraphOperationStatus> componentsVertices = janusGraphDao + .getParentVertices(categoryVertex, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.ParseMetadata); + if (componentsVertices.isRight()) { + JanusGraphOperationStatus status = componentsVertices.right().value(); + log.debug("#collectComponents Failed to get components vertices of category {}, status is {}.", categoryVertex, status); + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)); + } + List componentsMetadataDataDefinition = componentsVertices.left().value().stream().filter(Objects::nonNull) + .filter(componentsVertex -> Objects.nonNull(componentsVertex.getType())).map(ModelConverter::convertToComponentMetadataDataDefinition) + .collect(Collectors.toList()); + for (ComponentMetadataDataDefinition component : componentsMetadataDataDefinition) { + boolean isHighest = isTrue(component.isHighestVersion()); + boolean isMatchingResourceType = isMatchingByResourceType(neededType, resourceType, component); + boolean isDeleted = isTrue(component.isDeleted()); + boolean isArchived = isTrue(component.isArchived()); + if (isHighest && isMatchingResourceType && !isDeleted && !isArchived) { + Either result = toscaOperationFacade + .getToscaElement(component.getUniqueId(), JsonParseFlagEnum.ParseMetadata); + if (result.isRight()) { + return Either.right(result.right().value()); + } + components.add(result.left().value()); + } + } + return Either.left(components); + } + + private boolean isMatchingByResourceType(NodeTypeEnum componentType, ResourceTypeEnum resourceType, + ComponentMetadataDataDefinition componentData) { + boolean isMatching; + if (componentType == NodeTypeEnum.Resource) { + if (resourceType == null) { + isMatching = true; + } else { + isMatching = resourceType == ((ResourceMetadataDataDefinition) componentData).getResourceType(); + } + } else { + isMatching = true; + } + return isMatching; + } + + private Either, StorageOperationStatus> fetchByMainCategory( + List> subcategories, boolean inTransaction, ResourceTypeEnum resourceType) { + List components = new ArrayList<>(); + for (ImmutablePair subCategory : subcategories) { + Either, StorageOperationStatus> fetched = fetchByCategoryOrSubCategoryUid(subCategory.getLeft().getUniqueId(), + NodeTypeEnum.Resource, inTransaction, resourceType); + if (fetched.isRight()) { + continue; + } + components.addAll(fetched.left().value()); + } + return Either.left(components); + } + + private Either, StorageOperationStatus> fetchComponentMetaDataByResourceType(String resourceType, boolean inTransaction) { + List components = null; + StorageOperationStatus status; + Wrapper statusWrapper = new Wrapper<>(); + try { + ComponentParametersView fetchUsersAndCategoriesFilter = new ComponentParametersView( + Arrays.asList(ComponentFieldsEnum.USERS.getValue(), ComponentFieldsEnum.CATEGORIES.getValue())); + Either, StorageOperationStatus> getResources = toscaOperationFacade + .fetchMetaDataByResourceType(resourceType, fetchUsersAndCategoriesFilter); + if (getResources.isRight()) { + status = getResources.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + statusWrapper.setInnerElement(getResources.right().value()); + } else { + components = new ArrayList<>(); + } + } else { + components = getResources.left().value(); + } + if (statusWrapper.isEmpty()) { + return Either.left(components); + } else { + return Either.right(statusWrapper.getInnerElement()); + } + } finally { + if (!inTransaction) { + janusGraphDao.commit(); + } + } + } + + public CatalogUpdateTimestamp getCatalogUpdateTime() { + try { + return toscaOperationFacade.getCatalogTimes(); + } finally { + janusGraphDao.commit(); + } + } + + public Either, ActionStatus> getBaseTypes(final String categoryName, final String userId, final String modelName) { + final ActionStatus status = validateUserExistsActionStatus(userId); + if (ActionStatus.OK != status) { + return Either.right(status); + } + return Either.left(elementOperation.getServiceBaseTypes(categoryName, modelName)); + } + + /** + * Checks if a category requires a base type. + * + * @param categoryName the category name + * @return {@code true} if a base type is required, {@code false} otherwise. + */ + public boolean isBaseTypeRequired(final String categoryName) { + return elementOperation.isBaseTypeRequired(categoryName); + } + + /** + * Fetches default baseType from the template. + * + * @param categoryName the category name + * @return defaultBaseType mapped to the corresponding category name. + */ + public String getDefaultBaseType(final String categoryName) { + return elementOperation.getDefaultBaseType(categoryName); + } + + public boolean isDoNotExtendBaseType(final String categoryName) { + return elementOperation.isDoNotExtendBaseType(categoryName); + } }