1 package org.openecomp.sdc.asdctool.impl.migration.v1707.jsonmodel;
4 import org.openecomp.sdc.asdctool.impl.migration.MigrationMsg;
5 import org.openecomp.sdc.asdctool.impl.migration.Migration1707Task;
6 import org.openecomp.sdc.asdctool.impl.migration.v1707.MigrationUtils;
7 import org.openecomp.sdc.be.dao.api.ActionStatus;
8 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
9 import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition;
10 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
11 import org.openecomp.sdc.be.model.category.CategoryDefinition;
12 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
13 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
14 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
16 import javax.annotation.Resource;
17 import java.util.ArrayList;
18 import java.util.List;
20 import java.util.stream.Collectors;
22 import static org.openecomp.sdc.asdctool.impl.migration.v1707.jsonmodel.CategoriesUtils.filterOldCategories;
23 import static org.openecomp.sdc.asdctool.impl.migration.v1707.jsonmodel.CategoriesUtils.filterOldSubCategories;
26 public class ResourcesCategoriesMigration implements Migration1707Task {
28 @Resource(name = "element-operation")
29 private IElementOperation elementOperation;
31 @Resource(name = "element-operation-migration")
32 private IElementOperation elementOperationMigration;
34 @Resource(name = "titan-dao")
38 public String description() {
39 return "migrate resource categories";
43 public boolean migrate() {
44 return getCategoriesToMigrate().either(this::migrateCategories,
45 errorStatus -> MigrationUtils.handleError(MigrationMsg.FAILED_TO_RETRIEVE_CATEGORIES.getMessage(errorStatus.name())));
48 private Either<List<CategoryDefinition>, ActionStatus> getCategoriesToMigrate() {
49 return elementOperation.getAllCategories(NodeTypeEnum.ResourceNewCategory, false);
52 private boolean migrateCategories(List<CategoryDefinition> categoryDefinitions) {
53 List<CategoryDefinition> categoriesToMigrate = filterOldCategoriesAndSubCategories(categoryDefinitions);
54 for (CategoryDefinition categoryDefinition : categoriesToMigrate) {
55 boolean isMigrated = migrateCategoryIfNotExists(categoryDefinition);
66 //since production was malformed we need to fixed it by removing wrong categories and sub categories
67 private List<CategoryDefinition> filterOldCategoriesAndSubCategories(List<CategoryDefinition> categoryDefinitions) {
68 Map<String, List<CategoryDefinition>> categoriesByNormalName = categoryDefinitions.stream().collect(Collectors.groupingBy(CategoryDataDefinition::getNormalizedName));
69 List<CategoryDefinition> categoriesToMigrate = filterOldCategories(categoryDefinitions);
70 for (CategoryDefinition categoryDefinition : categoriesToMigrate) {
71 List<SubCategoryDefinition> newSubCategories = getAllDistinctSubCategories(categoriesByNormalName.get(categoryDefinition.getNormalizedName()));
72 categoryDefinition.setSubcategories(newSubCategories);
74 return categoriesToMigrate;
77 private List<SubCategoryDefinition> getAllDistinctSubCategories (List<CategoryDefinition> categoriesDefinitions) {
78 Map<String, List<SubCategoryDefinition>> subCategoriesByNormalName = categoriesDefinitions.stream()
79 .filter(ct -> ct.getSubcategories()!=null)
80 .flatMap(ct -> ct.getSubcategories().stream())
81 .collect(Collectors.groupingBy(SubCategoryDefinition::getNormalizedName));
82 return getDistinctSubCategories(subCategoriesByNormalName);
85 private List<SubCategoryDefinition> getDistinctSubCategories(Map<String, List<SubCategoryDefinition>> subCategoriesByNormalName) {
86 List<SubCategoryDefinition> allSubCategories = new ArrayList<>();
87 for (List<SubCategoryDefinition> subCategoryDefinitions : subCategoriesByNormalName.values()) {
88 if (subCategoryDefinitions.size() == 1) {
89 allSubCategories.addAll(subCategoryDefinitions);
91 allSubCategories.addAll(filterOldSubCategories(subCategoryDefinitions));
94 return allSubCategories;
97 private boolean migrateCategoryIfNotExists(CategoryDefinition categoryDefinition) {
98 return isExists(categoryDefinition).either(isExist -> isExist ? migrateSubCategories(categoryDefinition) : migrateCategoryAndSubCategories(categoryDefinition),
99 error -> MigrationUtils.handleError(MigrationMsg.FAILED_TO_RETRIEVE_CATEGORY.getMessage(categoryDefinition.getName(), error.name())));
102 private boolean migrateCategoryAndSubCategories(CategoryDefinition resourceCategory) {
103 return elementOperationMigration.createCategory(resourceCategory, NodeTypeEnum.ResourceNewCategory)
104 .either(createdCategory -> this.migrateSubCategories(resourceCategory),
105 status -> MigrationUtils.handleError(MigrationMsg.FAILED_TO_CREATE_CATEGORY.getMessage(resourceCategory.getName(), status.name())));
108 private boolean migrateSubCategories(CategoryDefinition categoryDefinition) {
109 for (SubCategoryDefinition subCategory : categoryDefinition.getSubcategories()) {
110 boolean isMigrated = migrateSubcategoryIfNotExists(categoryDefinition, subCategory);
118 private boolean migrateSubcategoryIfNotExists(CategoryDefinition parentCategory, SubCategoryDefinition subCategory) {
119 return isExists(parentCategory, subCategory).either(isExists -> isExists || migrateSubCategory(parentCategory, subCategory),
120 status -> MigrationUtils.handleError(MigrationMsg.FAILED_TO_RETRIEVE_CATEGORY.getMessage(subCategory.getName(), status.name())));
123 private boolean migrateSubCategory(CategoryDefinition categoryDefinition, SubCategoryDefinition subCategory) {
124 return elementOperationMigration.createSubCategory(categoryDefinition.getUniqueId(), subCategory, NodeTypeEnum.ResourceSubcategory)
125 .either(createdSubCategory -> true,
126 errorStatus -> MigrationUtils.handleError(MigrationMsg.FAILED_TO_CREATE_SUB_CATEGORY.getMessage(subCategory.getName(), categoryDefinition.getName(), errorStatus.name())));
130 private Either<Boolean, ActionStatus> isExists(CategoryDefinition category) {
131 Either<CategoryDefinition, ActionStatus> byId = getCategoryById(category);
132 return byId.either(existingVal -> Either.left(true),
133 this::getEitherNotExistOrErrorStatus);
136 private Either<Boolean, ActionStatus> isExists(CategoryDefinition parentCategory, SubCategoryDefinition subCategory) {
137 return getSubCategoryById(parentCategory, subCategory).either(existingVal -> Either.left(true),
138 this::getEitherNotExistOrErrorStatus);
141 private Either<Boolean, ActionStatus> getEitherNotExistOrErrorStatus(ActionStatus status) {
142 return status == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND ? Either.left(false) : Either.right(status);
145 private Either<CategoryDefinition, ActionStatus> getCategoryById(CategoryDefinition category) {
146 return elementOperationMigration.getCategory(NodeTypeEnum.ResourceNewCategory, category.getUniqueId());
149 private Either<SubCategoryDefinition, ActionStatus> getSubCategoryById(CategoryDefinition parentCategory, SubCategoryDefinition subCategory) {
150 String subCategoryUid = getExpectedSubCategoryId(parentCategory, subCategory);
151 return elementOperationMigration.getSubCategory(NodeTypeEnum.ResourceSubcategory, subCategoryUid);
154 //since a sub category might belong to a different category in old graph its new graph id is different than its old graph id
155 private String getExpectedSubCategoryId(CategoryDefinition parentCategory, SubCategoryDefinition subCategory) {
156 String parentId = UniqueIdBuilder.buildCategoryUid(parentCategory.getNormalizedName(), NodeTypeEnum.ResourceNewCategory);
157 return UniqueIdBuilder.buildSubCategoryUid(parentId, subCategory.getNormalizedName());