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