7dadd79a1b32a48fbb09ddfa504c3e6e5e3f06d3
[sdc.git] /
1 package org.openecomp.sdc.asdctool.impl.migration.v1707.jsonmodel;
2
3 import fj.data.Either;
4 import org.apache.commons.lang3.StringUtils;
5 import org.apache.tinkerpop.gremlin.structure.Edge;
6 import org.openecomp.sdc.asdctool.impl.migration.MigrationException;
7 import org.openecomp.sdc.asdctool.impl.migration.MigrationMsg;
8 import org.openecomp.sdc.asdctool.impl.migration.v1707.MigrationUtils;
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.titan.TitanGenericDao;
13 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
14 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
15 import org.openecomp.sdc.be.model.Component;
16 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
17 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 import javax.annotation.Resource;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.stream.Collectors;
27
28 public abstract class VersionMigration<T extends Component>  {
29
30     private static Logger LOGGER = LoggerFactory.getLogger(VersionMigration.class);
31
32     @Resource(name = "titan-generic-dao-migration")
33     private TitanGenericDao titanGenericDaoMigration;
34
35     @Resource(name = "titan-dao")
36     private TitanDao titanDao;
37
38     public boolean buildComponentsVersionChain(List<T> components) {
39         setMissingInvariantUid(components);
40         Map<String, List<T>> componentsByInvariant = components.stream().collect(Collectors.groupingBy(Component::getInvariantUUID));
41         for (List<T> componentsList : componentsByInvariant.values()) {
42             boolean versionChainBuilt = buildVersionChainForInvariant(componentsList);
43             if (!versionChainBuilt) {
44                 titanDao.rollback();
45                 return false;
46             }
47             titanDao.commit();
48         }
49         return true;
50     }
51
52     private boolean buildVersionChainForInvariant(List<T> components) {
53         sortComponentsByVersion(components);
54         for (int i = 0; i < components.size() -1; i++) {
55             String lowerVersionUid = components.get(i).getUniqueId();
56             String higherVersionUid = components.get(i + 1).getUniqueId();
57             boolean versionCreated = createVersionRelationIfNotExist(lowerVersionUid, higherVersionUid);
58             if (!versionCreated) {
59                 return false;
60             }
61         }
62         return true;
63     }
64
65     private void sortComponentsByVersion(List<T> components) {
66         Collections.sort(components, (o1, o2) -> o1.getVersion().compareTo(o2.getVersion()));
67     }
68
69     private boolean createVersionRelationIfNotExist(String fromUid, String toUid) {
70         Either<Boolean, TitanOperationStatus> isVersionExists = isVersionExists(fromUid, toUid);
71         return isVersionExists.either(versionExists -> versionExists || createVersionRelation(fromUid, toUid),
72                                errorStatus -> MigrationUtils.handleError(MigrationMsg.FAILED_TO_RETRIEVE_VERSION_RELATION.getMessage(fromUid, toUid, isVersionExists.right().value().name())));
73     }
74
75     private boolean createVersionRelation(String fromUid, String toUid) {
76         LOGGER.debug(String.format("creating version edge between vertex %s and vertex %s", fromUid, toUid));
77         Either<GraphVertex, TitanOperationStatus> vertexById = titanDao.getVertexById(fromUid);
78         Either<GraphVertex, TitanOperationStatus> vertexById1 = titanDao.getVertexById(toUid);
79         if (vertexById1.isLeft() && vertexById.isLeft()) {
80             TitanOperationStatus versionCreated = titanDao.createEdge(vertexById.left().value(), vertexById1.left().value(), EdgeLabelEnum.VERSION, new HashMap<>());
81             return versionCreated == TitanOperationStatus.OK;
82         }
83         return MigrationUtils.handleError(String.format("could not create version edge between vertex %s and vertex %s.", fromUid, toUid));
84     }
85
86     private Either<Boolean, TitanOperationStatus> isVersionExists(String fromUid, String toUid) {
87         LOGGER.debug(String.format("checking if version edge between vertex %s and vertex %s already exist", fromUid, toUid));
88         String uidKey = UniqueIdBuilder.getKeyByNodeType(getNodeTypeEnum());
89         Either<Edge, TitanOperationStatus> edgeByVertices = titanGenericDaoMigration.getEdgeByVerticies(uidKey, fromUid, uidKey, toUid, EdgeLabelEnum.VERSION.name());
90         if (isNotFoundStatus(edgeByVertices)) {
91             return Either.left(false);
92         }
93         return edgeByVertices.bimap(foundEdge -> true,
94                                     error -> error);
95     }
96
97     private boolean isNotFoundStatus(Either<Edge, TitanOperationStatus> edgeByVertices) {
98         return edgeByVertices.isRight() && edgeByVertices.right().value() == TitanOperationStatus.NOT_FOUND;
99     }
100
101     abstract NodeTypeEnum getNodeTypeEnum();
102
103     //some invariatn uids are missing in production
104     private void setMissingInvariantUid(List<T> components) {
105         List<T> missingInvariantCmpts = getComponentsWithNoInvariantUids(components);
106         for (T missingInvariantCmpt : missingInvariantCmpts) {
107             String uuid = missingInvariantCmpt.getUUID();
108             missingInvariantCmpt.setInvariantUUID(findInvariantUidOrElseFail(components, uuid));
109         }
110     }
111
112     private List<T> getComponentsWithNoInvariantUids(List<T> components) {
113         List<T> cmptsWithoutInvariant = components.stream().filter(c -> c.getInvariantUUID() == null).collect(Collectors.toList());
114         LOGGER.info(String.format("the following components are missing invariant uids: %s", StringUtils.join(cmptsWithoutInvariant.stream().map(Component::getUniqueId).collect(Collectors.toList()), ",")));
115         return cmptsWithoutInvariant;
116     }
117
118     private String findInvariantUidOrElseFail(List<T> components, String uuid) {
119         return components.stream()
120                 .filter(c -> c.getUUID().equals(uuid))
121                 .map(Component::getInvariantUUID)
122                 .filter(c -> c != null)
123                 .findAny().orElseThrow(() -> new MigrationException(String.format("cannot find invariantuid for component with uuid %s", uuid)));
124     }
125
126 }