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