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