1 package org.openecomp.sdc.asdctool.migration.tasks.mig1802;
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.jsongraph.GraphVertex;
10 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
11 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
12 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
13 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
14 import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
15 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
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.jsontitan.operations.TopologyTemplateOperation;
19 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaElementOperation;
20 import org.openecomp.sdc.common.log.wrappers.Logger;
21 import org.springframework.stereotype.Component;
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;
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);
34 private ToscaElementOperation toscaElementOperation;
35 private TitanDao titanDao;
37 public SdcCatalogMigration(TopologyTemplateOperation toscaElementOperation, TitanDao titanDao) {
38 this.toscaElementOperation = toscaElementOperation;
39 this.titanDao = titanDao;
43 public String description() {
44 return "optimize sdc catalog vertices";
48 public DBVersion getVersion() {
49 return DBVersion.from(BigInteger.valueOf(1802), BigInteger.valueOf(0));
53 public MigrationResult migrate() {
54 TitanOperationStatus status = null;
56 status = getOrCreateCatalogRoot()
57 .either(this::associateCatalogRootToCatalogElements,
58 err -> {LOGGER.error("failed to create catalog root. err: {}", err); return err;});
59 return status == TitanOperationStatus.OK ? MigrationResult.success() : MigrationResult.error("failed to create and associate catalog root. error: " + status);
61 commitOrRollBack(status);
65 private void commitOrRollBack(TitanOperationStatus status) {
66 if (status == TitanOperationStatus.OK) {
73 private Either<GraphVertex, TitanOperationStatus> getOrCreateCatalogRoot() {
74 LOGGER.info("creating or getting catalog root vertex");
75 return titanDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT)
77 .bind(this::createRootCatalogVertexOrError);
81 private Either<GraphVertex, TitanOperationStatus> createRootCatalogVertexOrError(TitanOperationStatus titanOperationStatus) {
82 return titanOperationStatus == TitanOperationStatus.NOT_FOUND ? createRootCatalogVertex() : Either.right(titanOperationStatus);
85 private Either<GraphVertex, TitanOperationStatus> createRootCatalogVertex() {
86 LOGGER.info("Creating root catalog vertex");
87 GraphVertex catalogRootVertex = new GraphVertex(VertexTypeEnum.CATALOG_ROOT);
88 catalogRootVertex.setUniqueId(IdBuilderUtils.generateUniqueId());
89 return titanDao.createVertex(catalogRootVertex);
92 private Either<List<GraphVertex>, TitanOperationStatus> getAllCatalogVertices() {
93 LOGGER.info("fetching all catalog resources");
94 return toscaElementOperation.getListOfHighestComponents(ComponentTypeEnum.RESOURCE, EXCLUDE_TYPES, JsonParseFlagEnum.ParseMetadata)
96 .bind(this::errOrEmptyListIfNotFound)
98 .bind(this::getAllCatalogVertices);
101 private Either<List<GraphVertex>, TitanOperationStatus> errOrEmptyListIfNotFound(TitanOperationStatus err) {
102 return TitanOperationStatus.NOT_FOUND.equals(err) ? Either.left(new ArrayList<>()) : Either.right(err);
105 @SuppressWarnings("unchecked")
106 private Either<List<GraphVertex>, TitanOperationStatus> getAllCatalogVertices(List<GraphVertex> allResourceCatalogVertices) {
107 LOGGER.info("number of resources: {}", allResourceCatalogVertices.size());
108 LOGGER.info("fetching all catalog services");
109 return toscaElementOperation.getListOfHighestComponents(ComponentTypeEnum.SERVICE, EXCLUDE_TYPES, JsonParseFlagEnum.ParseMetadata)
111 .bind(this::errOrEmptyListIfNotFound)
113 .map(allServiceVertices -> ListUtils.union(allServiceVertices, allResourceCatalogVertices));
116 private TitanOperationStatus associateCatalogRootToCatalogElements(GraphVertex root) {
117 return getAllCatalogVertices()
118 .either(catalogVertices -> associateCatalogRootToCatalogElements(root, catalogVertices),
122 private TitanOperationStatus associateCatalogRootToCatalogElements(GraphVertex root, List<GraphVertex> catalogElements) {
123 LOGGER.info("number of catalog elements: {}", catalogElements.size());
124 LOGGER.info("connect all catalog elements to root edge");
125 List<GraphVertex> nonConnectedElements = catalogElements.stream().filter(this::edgeNotAlreadyExists).collect(Collectors.toList());
126 int numOfCreatedEdges = 0;
127 for (GraphVertex catalogElement : nonConnectedElements) {
128 TitanOperationStatus edgeCreationStatus = titanDao.createEdge(root, catalogElement, EdgeLabelEnum.CATALOG_ELEMENT, null);
129 if (edgeCreationStatus != TitanOperationStatus.OK) {
130 LOGGER.error("failed to create edge from catalog element to vertex {}", catalogElement.getUniqueId());
131 return edgeCreationStatus;
133 LOGGER.debug("created edge from catalog root to element {}", catalogElement.getUniqueId());
136 LOGGER.info("number edges created: {}", numOfCreatedEdges);
137 return TitanOperationStatus.OK;
140 private boolean edgeNotAlreadyExists(GraphVertex catalogElement) {
141 return !catalogElement.getVertex().edges(Direction.IN, EdgeLabelEnum.CATALOG_ELEMENT.name()).hasNext();