514760fba23eb8b53b5338d109b60e25db48e942
[sdc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.asdctool.impl.migration.v1707.jsonmodel;
22
23 import fj.data.Either;
24 import org.apache.tinkerpop.gremlin.structure.Edge;
25 import org.openecomp.sdc.asdctool.impl.migration.MigrationMsg;
26 import org.openecomp.sdc.asdctool.impl.migration.v1707.MigrationUtils;
27 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
28 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
29 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
30 import org.openecomp.sdc.be.dao.titan.TitanGenericDao;
31 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
32 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
33 import org.openecomp.sdc.be.model.Component;
34 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import javax.annotation.Resource;
39 import java.util.Collections;
40 import java.util.HashMap;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.stream.Collectors;
44
45 public abstract class VersionMigration<T extends Component>  {
46
47     private static Logger LOGGER = LoggerFactory.getLogger(VersionMigration.class);
48
49     @Resource(name = "titan-generic-dao-migration")
50     private TitanGenericDao titanGenericDaoMigration;
51
52     @Resource(name = "titan-dao")
53     private TitanDao titanDao;
54
55     public boolean buildComponentsVersionChain(List<T> components) {
56         Map<String, List<T>> componentsByInvariant = components.stream().filter(c -> c.getInvariantUUID() != null).collect(Collectors.groupingBy(Component::getInvariantUUID));
57         for (List<T> componentsList : componentsByInvariant.values()) {
58             boolean versionChainBuilt = buildVersionChainForInvariant(componentsList);
59             if (!versionChainBuilt) {
60                 titanDao.rollback();
61                 return false;
62             }
63             titanDao.commit();
64         }
65         return true;
66     }
67
68     private boolean buildVersionChainForInvariant(List<T> components) {
69         sortComponentsByVersion(components);
70         for (int i = 0; i < components.size() -1; i++) {
71             String lowerVersionUid = components.get(i).getUniqueId();
72             String higherVersionUid = components.get(i + 1).getUniqueId();
73             boolean versionCreated = createVersionRelationIfNotExist(lowerVersionUid, higherVersionUid);
74             if (!versionCreated) {
75                 return false;
76             }
77         }
78         return true;
79     }
80
81     private void sortComponentsByVersion(List<T> components) {
82         Collections.sort(components, (o1, o2) -> Double.valueOf(o1.getVersion()).compareTo(Double.valueOf(o2.getVersion())));
83     }
84
85     private boolean createVersionRelationIfNotExist(String fromUid, String toUid) {
86         Either<Boolean, TitanOperationStatus> isVersionExists = isVersionExists(fromUid, toUid);
87         return isVersionExists.either(versionExists -> versionExists || createVersionRelation(fromUid, toUid),
88                                errorStatus -> MigrationUtils.handleError(MigrationMsg.FAILED_TO_RETRIEVE_VERSION_RELATION.getMessage(fromUid, toUid, isVersionExists.right().value().name())));
89     }
90
91     private boolean createVersionRelation(String fromUid, String toUid) {
92         LOGGER.debug(String.format("creating version edge between vertex %s and vertex %s", fromUid, toUid));
93         Either<GraphVertex, TitanOperationStatus> fromVertex = titanDao.getVertexById(fromUid);
94         Either<GraphVertex, TitanOperationStatus> toVertex = titanDao.getVertexById(toUid);
95         if (toVertex.isLeft() && fromVertex.isLeft()) {
96             TitanOperationStatus versionCreated = titanDao.createEdge(fromVertex.left().value(), toVertex.left().value(), EdgeLabelEnum.VERSION, new HashMap<>());
97             return versionCreated == TitanOperationStatus.OK;
98         }
99         return MigrationUtils.handleError(String.format("could not create version edge between vertex %s and vertex %s.", fromUid, toUid));
100     }
101
102     private Either<Boolean, TitanOperationStatus> isVersionExists(String fromUid, String toUid) {
103         LOGGER.debug(String.format("checking if version edge between vertex %s and vertex %s already exist", fromUid, toUid));
104         String uidKey = UniqueIdBuilder.getKeyByNodeType(getNodeTypeEnum());
105         Either<Edge, TitanOperationStatus> edgeByVertices = titanGenericDaoMigration.getEdgeByVerticies(uidKey, fromUid, uidKey, toUid, EdgeLabelEnum.VERSION.name());
106         if (isNotFoundStatus(edgeByVertices)) {
107             return Either.left(false);
108         }
109         return edgeByVertices.bimap(foundEdge -> true,
110                                     error -> error);
111     }
112
113     private boolean isNotFoundStatus(Either<Edge, TitanOperationStatus> edgeByVertices) {
114         return edgeByVertices.isRight() && edgeByVertices.right().value() == TitanOperationStatus.NOT_FOUND;
115     }
116
117     abstract NodeTypeEnum getNodeTypeEnum();
118 }