Upgrade SDC from Titan to Janus Graph
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsonjanusgraph / operations / UpgradeOperation.java
1 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
2
3 import org.janusgraph.core.JanusGraphVertex;
4 import fj.data.Either;
5 import org.apache.tinkerpop.gremlin.structure.Direction;
6 import org.apache.tinkerpop.gremlin.structure.Edge;
7 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
8 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
9 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
10 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
11 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
12 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
13 import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
14 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
15 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
16 import org.openecomp.sdc.be.model.ComponentDependency;
17 import org.openecomp.sdc.be.model.jsonjanusgraph.enums.JsonConstantKeysEnum;
18 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
19 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
20 import org.openecomp.sdc.common.log.wrappers.Logger;
21 import org.springframework.stereotype.Component;
22
23 import java.util.*;
24 import java.util.function.Function;
25 import java.util.stream.Collectors;
26
27 @Component
28 public class UpgradeOperation extends BaseOperation {
29     private static final Logger log = Logger.getLogger(UpgradeOperation.class.getName());
30
31     public Either<List<ComponentDependency>, StorageOperationStatus> getComponentDependencies(String componentId) {
32         Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(componentId);
33         if (vertexById.isRight()) {
34             log.debug("Failed to fetch vertex with id {} error {}", componentId, vertexById.right().value());
35             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexById.right().value()));
36         }
37         List<ComponentDependency> dependencies = new ArrayList<>();
38
39         GraphVertex vertex = vertexById.left().value();
40
41         StorageOperationStatus status = fillDependenciesByVertex(componentId, dependencies, vertex);
42         if (status != StorageOperationStatus.OK) {
43             return Either.right(status);
44         }
45
46         GraphVertex vertexToStart = vertex;
47         Function<GraphVertex, Either<GraphVertex, JanusGraphOperationStatus>> getNextElement = vertexP -> janusGraphDao
48             .getParentVertex(vertexP, EdgeLabelEnum.VERSION, JsonParseFlagEnum.ParseAll);
49         status = handleVersionChain(componentId, dependencies, vertex, getNextElement);
50         if (status != StorageOperationStatus.OK) {
51             return Either.right(status);
52         }
53         vertex = vertexToStart;
54         getNextElement = vertexP -> janusGraphDao
55             .getChildVertex(vertexP, EdgeLabelEnum.VERSION, JsonParseFlagEnum.ParseAll);
56         status = handleVersionChain(componentId, dependencies, vertex, getNextElement);
57
58         return status == StorageOperationStatus.OK ? Either.left(dependencies) : Either.right(status);
59     }
60
61     private StorageOperationStatus handleVersionChain(String componentId, List<ComponentDependency> dependencies, GraphVertex vertexToStart, Function<GraphVertex, Either<GraphVertex, JanusGraphOperationStatus>> getNextElement) {
62
63         StorageOperationStatus status;
64         boolean nextInChain = true;
65         GraphVertex vertex = vertexToStart;
66         Either<GraphVertex, JanusGraphOperationStatus> nextInChainV;
67         while (nextInChain) {
68             nextInChainV = getNextElement.apply(vertex);
69             if (nextInChainV.isRight()) {
70                 nextInChain = false;
71             } else {
72                 vertex = nextInChainV.left().value();
73                 status = fillDependenciesByVertex(componentId, dependencies, vertex);
74                 if (status != StorageOperationStatus.OK) {
75                     return status;
76                 }
77             }
78         }
79         return StorageOperationStatus.OK;
80     }
81
82     private StorageOperationStatus fillDependenciesByVertex(String componentId, List<ComponentDependency> dependencies, GraphVertex vertex) {
83         StorageOperationStatus status = StorageOperationStatus.OK;
84         if ( needToAddToDepenedency(vertex) ) {
85             ComponentDependency dependency = fillDataFromVertex(vertex, null, null);
86
87             List<EdgeLabelEnum> dependList = Arrays.asList(EdgeLabelEnum.INSTANCE_OF, EdgeLabelEnum.PROXY_OF, EdgeLabelEnum.ALLOTTED_OF);
88             for (EdgeLabelEnum label : dependList) {
89                 status = fillDependenciesByLabel(componentId, vertex, dependency, label);
90                 if (status != StorageOperationStatus.OK) {
91                     log.debug("Failed to create dependencies for component {} and label {} status {}", componentId, label, status);
92                     break;
93                 }
94             }
95             if (status == StorageOperationStatus.OK) {
96                 dependencies.add(dependency);
97             }
98         }
99         return status;
100     }
101     private boolean needToAddToDepenedency(GraphVertex vertex){
102         Boolean isDeleted = (Boolean) vertex.getMetadataProperty(GraphPropertyEnum.IS_DELETED);     
103         Boolean isArchived = (Boolean) vertex.getMetadataProperty(GraphPropertyEnum.IS_ARCHIVED);
104         return ( isDeleted == Boolean.TRUE || isArchived == Boolean.TRUE) ? false : true;
105     }
106
107     private StorageOperationStatus fillDependenciesByLabel(String componentId, GraphVertex vertex, ComponentDependency dependency, EdgeLabelEnum label) {
108         Either<List<GraphVertex>, JanusGraphOperationStatus> parentVertecies = janusGraphDao
109             .getParentVertecies(vertex, label, JsonParseFlagEnum.ParseAll);
110         if (parentVertecies.isRight() && parentVertecies.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
111             log.debug("Failed to fetch parent verticies by label INSTANCE_OF for vertex with id {} error {}", componentId, parentVertecies.right().value());
112             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(parentVertecies.right().value());
113         }
114         if (parentVertecies.isLeft()) {
115             List<ComponentDependency> existIn = new ArrayList<>( );
116             parentVertecies.left().value().forEach(v -> handleHighestVersion(vertex, label, existIn, v) );
117             dependency.addDependencies(existIn);
118         }
119         return StorageOperationStatus.OK;
120     }
121
122     private void handleHighestVersion(GraphVertex vertexOrigin, EdgeLabelEnum label, List<ComponentDependency> exisIn, GraphVertex containerVertex) {
123         Boolean isHighest = (Boolean) containerVertex.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
124         if ( isHighest && needToAddToDepenedency(containerVertex) ) {  
125             JanusGraphVertex janusGraphVertex = containerVertex.getVertex();
126             Iterator<Edge> edges = janusGraphVertex.edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
127             //verify that it is a last version - highest by version number
128             if ( edges == null || !edges.hasNext() ){
129                 ComponentDependency container = fillDataFromVertex(containerVertex, vertexOrigin.getUniqueId(), label);
130                 boolean addToDependency = true;
131                 if (label == EdgeLabelEnum.ALLOTTED_OF) {
132                     //in case of not full allotted chain not add to dependency list
133                     addToDependency = findAllottedChain(containerVertex, container);
134                 }
135                 if ( addToDependency ){
136                     exisIn.add(container);
137                  }
138             }
139         }
140     }
141
142     private boolean findAllottedChain(GraphVertex vertex, ComponentDependency container) {
143         Either<List<GraphVertex>, JanusGraphOperationStatus> parentVertecies = janusGraphDao
144             .getParentVertecies(vertex, EdgeLabelEnum.INSTANCE_OF, JsonParseFlagEnum.ParseAll);
145         if (parentVertecies.isLeft()) {
146             List<ComponentDependency> existIn = new ArrayList<>();
147             parentVertecies.left().value().forEach(v -> {
148                 Boolean isHighest = (Boolean) v.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
149                 if ( isHighest && needToAddToDepenedency(v) ) {
150                    JanusGraphVertex janusGraphVertex = v.getVertex();
151                    Iterator<Edge> edges = janusGraphVertex.edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
152                    //verify that it is a last version - highest by version number
153                    if ( edges == null || !edges.hasNext() ){
154                        ComponentDependency parentContainer = fillDataFromVertex(v, vertex.getUniqueId(), EdgeLabelEnum.INSTANCE_OF);
155                        existIn.add(parentContainer);
156                    }
157                 }
158             });
159             if ( !existIn.isEmpty() ){
160                 container.setDependencies(existIn);
161                 return true;
162             }
163         }
164         return false;
165     }
166
167     private ComponentDependency fillDataFromVertex(GraphVertex v, String originId, EdgeLabelEnum edgeLabel) {
168         ComponentDependency container = new ComponentDependency();
169         container.setName((String) v.getMetadataProperty(GraphPropertyEnum.NAME));
170         container.setVersion((String) v.getMetadataProperty(GraphPropertyEnum.VERSION));
171         container.setUniqueId(v.getUniqueId());
172         container.setType((String) v.getMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE));
173         container.setIcon((String) v.getJsonMetadataField(JsonPresentationFields.ICON));
174         container.setState((String) v.getMetadataProperty(GraphPropertyEnum.STATE));
175
176         if (edgeLabel == EdgeLabelEnum.PROXY_OF || edgeLabel == EdgeLabelEnum.ALLOTTED_OF) {
177             findInstanceNames(v, originId, edgeLabel, container);
178         }
179         return container;
180     }
181
182     private void findInstanceNames(GraphVertex v, String originId, EdgeLabelEnum edgeLabel, ComponentDependency container) {
183         Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) v.getJson();
184         CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
185         JanusGraphVertex vertex = v.getVertex();
186         Iterator<Edge> edges = vertex.edges(Direction.OUT, edgeLabel.name());
187         while (edges != null && edges.hasNext()) {
188             Edge edge = edges.next();
189             JanusGraphVertex inVertex = (JanusGraphVertex) edge.inVertex();
190             String id = (String) janusGraphDao.getProperty(inVertex, GraphPropertyEnum.UNIQUE_ID.getProperty());
191             if (id.equals(originId)) {
192                 List<String> instanceOnEdge = (List<String>) janusGraphDao
193                     .getProperty(edge, EdgePropertyEnum.INSTANCES);
194                 Map<String, ComponentInstanceDataDefinition> componentInstances = compositionDataDefinition.getComponentInstances();
195
196                 if (componentInstances != null) {
197                     List<String> ciNames = componentInstances
198                             .values()
199                             .stream()
200                             .filter(ci -> instanceOnEdge.contains(ci.getUniqueId()))
201                             .map(ComponentInstanceDataDefinition::getName)
202                             .collect(Collectors.toList());
203                     if (ciNames != null && !ciNames.isEmpty()) {
204                         container.setInstanceNames(ciNames);
205                         break;
206                     }
207                 }
208             }
209         }
210     }
211
212     public List<String> getInstanceIdFromAllottedEdge(String resourceId, String serviceInvariantUUID) {
213       Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(resourceId);
214       if ( vertexById.isLeft() ){
215           GraphVertex vertexG = vertexById.left().value();
216           JanusGraphVertex vertex = vertexG.getVertex();
217           Iterator<Edge> edges = vertex.edges(Direction.OUT, EdgeLabelEnum.ALLOTTED_OF.name());
218           while ( edges != null && edges.hasNext() ){
219               Edge edge = edges.next();
220               JanusGraphVertex inVertex = (JanusGraphVertex)edge.inVertex();
221               String vertexInInvUUID = (String) janusGraphDao
222                   .getProperty(inVertex, GraphPropertyEnum.INVARIANT_UUID.getProperty());
223               if ( vertexInInvUUID.equals(serviceInvariantUUID) ){
224                   return (List<String>) janusGraphDao.getProperty(edge, EdgePropertyEnum.INSTANCES) ;
225               }
226           }
227       }
228       return new ArrayList<>();
229     }
230
231 }