Raise JUnit coverage asdctool
[sdc.git] / asdctool / src / main / java / org / openecomp / sdc / asdctool / migration / tasks / mig1802 / SdcCatalogMigration.java
1 package org.openecomp.sdc.asdctool.migration.tasks.mig1802;
2
3 import java.math.BigInteger;
4 import java.util.Arrays;
5 import java.util.List;
6 import java.util.stream.Collectors;
7
8 import org.apache.commons.collections.ListUtils;
9 import org.apache.tinkerpop.gremlin.structure.Direction;
10 import org.openecomp.sdc.asdctool.migration.core.DBVersion;
11 import org.openecomp.sdc.asdctool.migration.core.task.Migration;
12 import org.openecomp.sdc.asdctool.migration.core.task.MigrationResult;
13 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
14 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
15 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
16 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
17 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
18 import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
19 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
20 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
21 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
22 import org.openecomp.sdc.be.model.jsontitan.operations.TopologyTemplateOperation;
23 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaElementOperation;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26 import org.springframework.stereotype.Component;
27
28 import fj.data.Either;
29
30 @Component
31 public class SdcCatalogMigration implements Migration {
32     private static final Logger LOGGER = LoggerFactory.getLogger(SdcCatalogMigration.class);
33     private static final List<ResourceTypeEnum> EXCLUDE_TYPES = Arrays.asList(ResourceTypeEnum.VFCMT, ResourceTypeEnum.Configuration);
34
35     private ToscaElementOperation toscaElementOperation;
36     private TitanDao titanDao;
37
38     public SdcCatalogMigration(TopologyTemplateOperation toscaElementOperation, TitanDao titanDao) {
39         this.toscaElementOperation = toscaElementOperation;
40         this.titanDao = titanDao;
41     }
42
43     @Override
44     public String description() {
45         return "optimize sdc catalog vertices";
46     }
47
48     @Override
49     public DBVersion getVersion() {
50         return DBVersion.from(BigInteger.valueOf(1802), BigInteger.valueOf(0));
51     }
52
53     @Override
54     public MigrationResult migrate() {
55         TitanOperationStatus status = null;
56         try {
57             status = getOrCreateCatalogRoot()
58                     .either(this::associateCatalogRootToCatalogElements,
59                             err -> {LOGGER.error("failed to create catalog root. err: {}", err); return err;});
60             return status == TitanOperationStatus.OK ? MigrationResult.success() : MigrationResult.error("failed to create and associate catalog root. error: " + status);
61         } finally {
62             commitOrRollBack(status);
63         }
64     }
65
66     private void commitOrRollBack(TitanOperationStatus status) {
67         if (status == TitanOperationStatus.OK) {
68             titanDao.commit();
69         } else {
70             titanDao.rollback();
71         }
72     }
73
74     private Either<GraphVertex, TitanOperationStatus> getOrCreateCatalogRoot() {
75         LOGGER.info("creating or getting catalog root vertex");
76         return titanDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT)
77                 .right()
78                 .bind(this::createRootCatalogVertexOrError);
79     }
80
81
82     private Either<GraphVertex, TitanOperationStatus> createRootCatalogVertexOrError(TitanOperationStatus titanOperationStatus) {
83         return titanOperationStatus == TitanOperationStatus.NOT_FOUND ? createRootCatalogVertex() : Either.right(titanOperationStatus);
84     }
85
86     private Either<GraphVertex, TitanOperationStatus> createRootCatalogVertex() {
87         LOGGER.info("Creating root catalog vertex");
88         GraphVertex catalogRootVertex = new GraphVertex(VertexTypeEnum.CATALOG_ROOT);
89         catalogRootVertex.setUniqueId(IdBuilderUtils.generateUniqueId());
90         return titanDao.createVertex(catalogRootVertex);
91     }
92
93     private Either<List<GraphVertex>, TitanOperationStatus> getAllCatalogVertices() {
94         LOGGER.info("fetching all catalog resources");
95         return toscaElementOperation.getListOfHighestComponents(ComponentTypeEnum.RESOURCE, EXCLUDE_TYPES, JsonParseFlagEnum.ParseMetadata)
96                 .left()
97                 .bind(this::getAllCatalogVertices);
98     }
99
100     @SuppressWarnings("unchecked")
101     private Either<List<GraphVertex>, TitanOperationStatus> getAllCatalogVertices(List<GraphVertex> allResourceCatalogVertices) {
102         LOGGER.info("number of resources: {}", allResourceCatalogVertices.size());
103         LOGGER.info("fetching all catalog services");
104         return toscaElementOperation.getListOfHighestComponents(ComponentTypeEnum.SERVICE, EXCLUDE_TYPES, JsonParseFlagEnum.ParseMetadata)
105                 .left()
106                 .map(allServiceVertices -> ListUtils.union(allServiceVertices, allResourceCatalogVertices));
107     }
108
109     private TitanOperationStatus associateCatalogRootToCatalogElements(GraphVertex root) {
110         return getAllCatalogVertices()
111                 .either(catalogVertices -> associateCatalogRootToCatalogElements(root, catalogVertices),
112                         err -> err);
113     }
114
115     private TitanOperationStatus associateCatalogRootToCatalogElements(GraphVertex root, List<GraphVertex> catalogElements) {
116         LOGGER.info("number of catalog elements: {}", catalogElements.size());
117         LOGGER.info("connect all catalog elements to root edge");
118         List<GraphVertex> nonConnectedElements = catalogElements.stream().filter(this::edgeNotAlreadyExists).collect(Collectors.toList());
119         int numOfCreatedEdges = 0;
120         for (GraphVertex catalogElement : nonConnectedElements) {
121                 TitanOperationStatus edgeCreationStatus = titanDao.createEdge(root, catalogElement, EdgeLabelEnum.CATALOG_ELEMENT, null);
122                 if (edgeCreationStatus != TitanOperationStatus.OK) {
123                     LOGGER.error("failed to create edge from catalog element to vertex {}", catalogElement.getUniqueId());
124                     return edgeCreationStatus;
125                 }
126                 LOGGER.debug("created edge from catalog root to element {}", catalogElement.getUniqueId());
127                 numOfCreatedEdges++;
128         }
129         LOGGER.info("number edges created: {}", numOfCreatedEdges);
130         return TitanOperationStatus.OK;
131     }
132
133     private boolean edgeNotAlreadyExists(GraphVertex catalogElement) {
134         return !catalogElement.getVertex().edges(Direction.IN, EdgeLabelEnum.CATALOG_ELEMENT.name()).hasNext();
135     }
136
137
138 }