Sync Integ to Master
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsontitan / operations / ToscaElementOperation.java
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.be.model.jsontitan.operations;
22
23 import java.lang.reflect.Type;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Map.Entry;
31 import java.util.Set;
32
33 import org.apache.tinkerpop.gremlin.structure.Direction;
34 import org.apache.tinkerpop.gremlin.structure.Edge;
35 import org.apache.tinkerpop.gremlin.structure.Vertex;
36 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
37 import org.openecomp.sdc.be.config.ConfigurationManager;
38 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
39 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
40 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
41 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
42 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
43 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
44 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
45 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
46 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
47 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
48 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
49 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
50 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
51 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
52 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
53 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
54 import org.openecomp.sdc.be.model.ComponentParametersView;
55 import org.openecomp.sdc.be.model.LifecycleStateEnum;
56 import org.openecomp.sdc.be.model.catalog.CatalogComponent;
57 import org.openecomp.sdc.be.model.category.CategoryDefinition;
58 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
59 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
60 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
61 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
62 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
63 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
64 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
65 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
66 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
67 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
68 import org.openecomp.sdc.common.util.ValidationUtils;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
71 import org.springframework.beans.factory.annotation.Autowired;
72 import org.springframework.util.StopWatch;
73
74 import com.google.gson.Gson;
75 import com.google.gson.reflect.TypeToken;
76
77 import fj.data.Either;
78
79 public abstract class ToscaElementOperation extends BaseOperation {
80     private static Logger log = LoggerFactory.getLogger(ToscaElementOperation.class.getName());
81
82     private static final Gson gson = new Gson();
83
84     protected Gson getGson() {
85         return gson;
86     }
87
88     @Autowired
89     protected CategoryOperation categoryOperation;
90
91     protected Either<GraphVertex, StorageOperationStatus> getComponentByLabelAndId(String uniqueId, ToscaElementTypeEnum nodeType, JsonParseFlagEnum parseFlag) {
92
93         Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
94         propertiesToMatch.put(GraphPropertyEnum.UNIQUE_ID, uniqueId);
95
96         VertexTypeEnum vertexType = ToscaElementTypeEnum.getVertexTypeByToscaType(nodeType);
97         Either<List<GraphVertex>, TitanOperationStatus> getResponse = titanDao.getByCriteria(vertexType, propertiesToMatch, parseFlag);
98         if (getResponse.isRight()) {
99             log.debug("Couldn't fetch component with type {} and unique id {}, error: {}", vertexType, uniqueId, getResponse.right().value());
100             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getResponse.right().value()));
101
102         }
103         List<GraphVertex> componentList = getResponse.left().value();
104         if (componentList.isEmpty()) {
105             log.debug("Component with type {} and unique id {} was not found", vertexType, uniqueId);
106             return Either.right(StorageOperationStatus.NOT_FOUND);
107         }
108         GraphVertex vertexG = componentList.get(0);
109         return Either.left(vertexG);
110     }
111
112     public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId) {
113         return getToscaElement(uniqueId, new ComponentParametersView());
114     }
115
116     public Either<GraphVertex, StorageOperationStatus> markComponentToDelete(GraphVertex componentToDelete) {
117         Either<GraphVertex, StorageOperationStatus> result = null;
118
119         Boolean isDeleted = (Boolean) componentToDelete.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
120         if (isDeleted != null && isDeleted && !(Boolean) componentToDelete.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION)) {
121             // component already marked for delete
122             result = Either.left(componentToDelete);
123             return result;
124         } else {
125
126             componentToDelete.addMetadataProperty(GraphPropertyEnum.IS_DELETED, Boolean.TRUE);
127             componentToDelete.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
128
129             Either<GraphVertex, TitanOperationStatus> updateNode = titanDao.updateVertex(componentToDelete);
130
131             StorageOperationStatus updateComponent;
132             if (updateNode.isRight()) {
133                 log.debug("Failed to update component {}. status is {}", componentToDelete.getUniqueId(), updateNode.right().value());
134                 updateComponent = DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value());
135                 result = Either.right(updateComponent);
136                 return result;
137             }
138
139             result = Either.left(componentToDelete);
140             return result;
141         }
142     }
143
144     /**
145      * Performs a shadow clone of previousToscaElement
146      * 
147      * @param previousToscaElement
148      * @param nextToscaElement
149      * @param user
150      * @return
151      */
152     public Either<GraphVertex, StorageOperationStatus> cloneToscaElement(GraphVertex previousToscaElement, GraphVertex nextToscaElement, GraphVertex user) {
153
154         Either<GraphVertex, StorageOperationStatus> result = null;
155         GraphVertex createdToscaElementVertex = null;
156         TitanOperationStatus status;
157
158         Either<GraphVertex, TitanOperationStatus> createNextVersionRes = titanDao.createVertex(nextToscaElement);
159         if (createNextVersionRes.isRight()) {
160             status = createNextVersionRes.right().value();
161             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create tosca element vertex {} with version {} on graph. Status is {}. ", previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME),
162                     previousToscaElement.getMetadataProperty(GraphPropertyEnum.VERSION), status);
163             result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
164         }
165         if (result == null) {
166             createdToscaElementVertex = createNextVersionRes.left().value();
167             Map<EdgePropertyEnum, Object> properties = new HashMap<EdgePropertyEnum, Object>();
168             properties.put(EdgePropertyEnum.STATE, createdToscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE));
169             status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.STATE, properties);
170             if (status != TitanOperationStatus.OK) {
171                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.STATE, user.getUniqueId(),
172                         previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
173                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
174             }
175         }
176         if (result == null) {
177             status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
178             if (status != TitanOperationStatus.OK) {
179                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.LAST_MODIFIER, user.getUniqueId(),
180                         nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
181                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
182             }
183         }
184         if (result == null) {
185             status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.CREATOR, new HashMap<>());
186             if (status != TitanOperationStatus.OK) {
187                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.CREATOR, user.getUniqueId(),
188                         nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
189                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
190             }
191         }
192         if (result == null) {
193             Iterator<Edge> edgesToCopyIter = previousToscaElement.getVertex().edges(Direction.OUT);
194             while (edgesToCopyIter.hasNext()) {
195                 Edge currEdge = edgesToCopyIter.next();
196                 Vertex currVertex = currEdge.inVertex();
197                 // if(EdgeLabelEnum.getEdgeLabelEnum(currEdge.label()).equals(EdgeLabelEnum.VERSION)){
198                 // continue;
199                 // }
200                 status = titanDao.createEdge(createdToscaElementVertex.getVertex(), currVertex, EdgeLabelEnum.getEdgeLabelEnum(currEdge.label()), currEdge);
201                 if (status != TitanOperationStatus.OK) {
202                     CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from tosca element vertex {} to vertex with label {} on graph. Status is {}. ", currEdge.label(), createdToscaElementVertex.getUniqueId(),
203                             currVertex.property(GraphPropertyEnum.LABEL.getProperty()), status);
204                     result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
205                     break;
206                 }
207             }
208         }
209
210         if (result == null) {
211             result = Either.left(createdToscaElementVertex);
212         } else {
213             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element {} with the name {}. ", previousToscaElement.getUniqueId(), previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME));
214         }
215         return result;
216     }
217
218     protected TitanOperationStatus setLastModifierFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
219         Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(componentV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
220         if (parentVertex.isRight()) {
221             log.debug("Failed to fetch last modifier for tosca element with id {} error {}", componentV.getUniqueId(), parentVertex.right().value());
222             return parentVertex.right().value();
223         }
224         GraphVertex userV = parentVertex.left().value();
225         String userId = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
226         toscaElement.setLastUpdaterUserId(userId);
227         toscaElement.setLastUpdaterFullName(buildFullName(userV));
228         return TitanOperationStatus.OK;
229     }
230
231     public String buildFullName(GraphVertex userV) {
232
233         String fullName = (String) userV.getMetadataProperty(GraphPropertyEnum.FIRST_NAME);
234         if (fullName == null) {
235             fullName = "";
236         } else {
237             fullName = fullName + " ";
238         }
239         String lastName = (String) userV.getMetadataProperty(GraphPropertyEnum.LAST_NAME);
240         if (lastName != null) {
241             fullName += lastName;
242         }
243         return fullName;
244     }
245
246     protected TitanOperationStatus setCreatorFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
247         Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(componentV, EdgeLabelEnum.CREATOR, JsonParseFlagEnum.NoParse);
248         if (parentVertex.isRight()) {
249             log.debug("Failed to fetch creator for tosca element with id {} error {}", componentV.getUniqueId(), parentVertex.right().value());
250             return parentVertex.right().value();
251         }
252         GraphVertex userV = parentVertex.left().value();
253         String creatorUserId = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
254         toscaElement.setCreatorUserId(creatorUserId);
255         toscaElement.setCreatorFullName(buildFullName(userV));
256
257         return TitanOperationStatus.OK;
258     }
259
260     protected <T extends ToscaElement> T getResourceMetaDataFromResource(T toscaElement) {
261         if (toscaElement.getNormalizedName() == null || toscaElement.getNormalizedName().isEmpty()) {
262             toscaElement.setNormalizedName(ValidationUtils.normaliseComponentName(toscaElement.getName()));
263         }
264         if (toscaElement.getSystemName() == null || toscaElement.getSystemName().isEmpty()) {
265             toscaElement.setSystemName(ValidationUtils.convertToSystemName(toscaElement.getName()));
266         }
267
268         LifecycleStateEnum lifecycleStateEnum = toscaElement.getLifecycleState();
269         if (lifecycleStateEnum == null) {
270             toscaElement.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
271         }
272         long currentDate = System.currentTimeMillis();
273         if (toscaElement.getCreationDate() == null) {
274             toscaElement.setCreationDate(currentDate);
275         }
276         toscaElement.setLastUpdateDate(currentDate);
277
278         return toscaElement;
279     }
280
281     protected void fillCommonMetadata(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
282         if (toscaElement.isHighestVersion() == null) {
283             toscaElement.setHighestVersion(true);
284         }
285         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_DELETED, toscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED));
286         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, toscaElement.getMetadataValueOrDefault(JsonPresentationFields.HIGHEST_VERSION, Boolean.TRUE));
287         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.STATE, toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
288         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.RESOURCE_TYPE, toscaElement.getMetadataValue(JsonPresentationFields.RESOURCE_TYPE));
289         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.VERSION, toscaElement.getMetadataValue(JsonPresentationFields.VERSION));
290         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME, toscaElement.getMetadataValue(JsonPresentationFields.NORMALIZED_NAME));
291         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, toscaElement.getMetadataValue(JsonPresentationFields.UNIQUE_ID));
292         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
293         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.UUID, toscaElement.getMetadataValue(JsonPresentationFields.UUID));
294         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_ABSTRACT, toscaElement.getMetadataValue(JsonPresentationFields.IS_ABSTRACT));
295         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.INVARIANT_UUID, toscaElement.getMetadataValue(JsonPresentationFields.INVARIANT_UUID));
296         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NAME, toscaElement.getMetadataValue(JsonPresentationFields.NAME));
297         nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.SYSTEM_NAME, toscaElement.getMetadataValue(JsonPresentationFields.SYSTEM_NAME));
298         toscaElement.getMetadata().entrySet().stream().filter(e -> e.getValue() != null).forEach(e -> nodeTypeVertex.setJsonMetadataField(JsonPresentationFields.getByPresentation(e.getKey()), e.getValue()));
299
300         nodeTypeVertex.setUniqueId(toscaElement.getUniqueId());
301         nodeTypeVertex.setType(toscaElement.getComponentType());
302
303     }
304
305     protected StorageOperationStatus assosiateToUsers(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
306         // handle user
307         String userId = toscaElement.getCreatorUserId();
308
309         Either<GraphVertex, TitanOperationStatus> findUser = findUserVertex(userId);
310
311         if (findUser.isRight()) {
312             TitanOperationStatus status = findUser.right().value();
313             log.error("Cannot find user {} in the graph. status is {}", userId, status);
314             return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
315
316         }
317         GraphVertex creatorVertex = findUser.left().value();
318         GraphVertex updaterVertex = creatorVertex;
319         String updaterId = toscaElement.getLastUpdaterUserId();
320         if (updaterId != null && !updaterId.equals(userId)) {
321             findUser = findUserVertex(updaterId);
322             if (findUser.isRight()) {
323                 TitanOperationStatus status = findUser.right().value();
324                 log.error("Cannot find user {} in the graph. status is {}", userId, status);
325                 return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
326             } else {
327                 updaterVertex = findUser.left().value();
328             }
329         }
330         Map<EdgePropertyEnum, Object> props = new HashMap<EdgePropertyEnum, Object>();
331         props.put(EdgePropertyEnum.STATE, (String) toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
332
333         TitanOperationStatus result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.STATE, props);
334         log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.STATE);
335         if (TitanOperationStatus.OK != result) {
336             return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
337         }
338         result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.LAST_MODIFIER, null);
339         log.debug("After associating user {}  to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
340         if (!result.equals(TitanOperationStatus.OK)) {
341             log.error("Failed to associate user {}  to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
342             return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
343         }
344
345         toscaElement.setLastUpdaterUserId(toscaElement.getCreatorUserId());
346         toscaElement.setLastUpdaterFullName(toscaElement.getCreatorFullName());
347
348         result = titanDao.createEdge(creatorVertex, nodeTypeVertex, EdgeLabelEnum.CREATOR, null);
349         log.debug("After associating user {} to resource {}. Edge type is {} ", creatorVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.CREATOR);
350         if (!result.equals(TitanOperationStatus.OK)) {
351             log.error("Failed to associate user {} to resource {}. Edge type is {} ", creatorVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.CREATOR);
352             return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
353         }
354         return StorageOperationStatus.OK;
355     }
356
357     protected StorageOperationStatus assosiateResourceMetadataToCategory(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
358         String subcategoryName = nodeType.getCategories().get(0).getSubcategories().get(0).getName();
359         String categoryName = nodeType.getCategories().get(0).getName();
360         Either<GraphVertex, StorageOperationStatus> getCategoryVertex = getResourceCategoryVertex(nodeType.getUniqueId(), subcategoryName, categoryName);
361
362         if (getCategoryVertex.isRight()) {
363             return getCategoryVertex.right().value();
364         }
365
366         GraphVertex subCategoryV = getCategoryVertex.left().value();
367
368         TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, subCategoryV, EdgeLabelEnum.CATEGORY, new HashMap<>());
369         if (createEdge != TitanOperationStatus.OK) {
370             log.trace("Failed to associate resource {} to category {} with id {}", nodeType.getUniqueId(), subcategoryName, subCategoryV.getUniqueId());
371             return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
372         }
373         return StorageOperationStatus.OK;
374     }
375
376     protected Either<GraphVertex, StorageOperationStatus> getResourceCategoryVertex(String elementId, String subcategoryName, String categoryName) {
377         Either<GraphVertex, StorageOperationStatus> category = categoryOperation.getCategory(categoryName, VertexTypeEnum.RESOURCE_CATEGORY);
378         if (category.isRight()) {
379             log.trace("Failed to fetch category {} for resource {} error {}", categoryName, elementId, category.right().value());
380             return Either.right(category.right().value());
381         }
382         GraphVertex categoryV = category.left().value();
383
384         if (subcategoryName != null) {
385             Either<GraphVertex, StorageOperationStatus> subCategory = categoryOperation.getSubCategoryForCategory(categoryV, subcategoryName);
386             if (subCategory.isRight()) {
387                 log.trace("Failed to fetch subcategory {} of category for resource {} error {}", subcategoryName, categoryName, elementId, subCategory.right().value());
388                 return Either.right(subCategory.right().value());
389             }
390
391             GraphVertex subCategoryV = subCategory.left().value();
392             return Either.left(subCategoryV);
393         }
394         return Either.left(categoryV);
395     }
396
397     private StorageOperationStatus associateArtifactsToResource(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
398         Map<String, ArtifactDataDefinition> artifacts = toscaElement.getArtifacts();
399         Either<GraphVertex, StorageOperationStatus> status;
400         if (artifacts != null) {
401             artifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
402                 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
403                 a.setUniqueId(uniqueId);
404             });
405             status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ARTIFACTS, EdgeLabelEnum.ARTIFACTS, artifacts);
406             if (status.isRight()) {
407                 return status.right().value();
408             }
409         }
410         Map<String, ArtifactDataDefinition> toscaArtifacts = toscaElement.getToscaArtifacts();
411         if (toscaArtifacts != null) {
412             toscaArtifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
413                 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
414                 a.setUniqueId(uniqueId);
415             });
416             status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.TOSCA_ARTIFACTS, EdgeLabelEnum.TOSCA_ARTIFACTS, toscaArtifacts);
417             if (status.isRight()) {
418                 return status.right().value();
419             }
420         }
421         Map<String, ArtifactDataDefinition> deploymentArtifacts = toscaElement.getDeploymentArtifacts();
422         if (deploymentArtifacts != null) {
423             deploymentArtifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
424                 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
425                 a.setUniqueId(uniqueId);
426             });
427             status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.DEPLOYMENT_ARTIFACTS, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS, deploymentArtifacts);
428             if (status.isRight()) {
429                 return status.right().value();
430             }
431         }
432         return StorageOperationStatus.OK;
433     }
434
435     protected TitanOperationStatus disassociateAndDeleteCommonElements(GraphVertex toscaElementVertex) {
436         TitanOperationStatus status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ARTIFACTS);
437         if (status != TitanOperationStatus.OK) {
438             log.debug("Failed to disaccociate artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
439             return status;
440         }
441         status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.TOSCA_ARTIFACTS);
442         if (status != TitanOperationStatus.OK) {
443             log.debug("Failed to disaccociate tosca artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
444             return status;
445         }
446         status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
447         if (status != TitanOperationStatus.OK) {
448             log.debug("Failed to deployment artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
449             return status;
450         }
451         status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.PROPERTIES);
452         if (status != TitanOperationStatus.OK) {
453             log.debug("Failed to disaccociate properties for {} error {}", toscaElementVertex.getUniqueId(), status);
454             return status;
455         }
456         status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
457         if (status != TitanOperationStatus.OK) {
458             log.debug("Failed to disaccociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
459             return status;
460         }
461         status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ADDITIONAL_INFORMATION);
462         if (status != TitanOperationStatus.OK) {
463             log.debug("Failed to disaccociate additional information for {} error {}", toscaElementVertex.getUniqueId(), status);
464             return status;
465         }
466         status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
467         if (status != TitanOperationStatus.OK) {
468             log.debug("Failed to disaccociate capabilities for {} error {}", toscaElementVertex.getUniqueId(), status);
469             return status;
470         }
471         status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
472         if (status != TitanOperationStatus.OK) {
473             log.debug("Failed to disaccociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
474             return status;
475         }
476         status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.FORWARDING_PATH);
477         if (status != TitanOperationStatus.OK) {
478             log.debug("Failed to disaccociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
479             return status;
480         }
481         return TitanOperationStatus.OK;
482     }
483
484     protected StorageOperationStatus assosiateCommonForToscaElement(GraphVertex nodeTypeVertex, ToscaElement toscaElement, List<GraphVertex> derivedResources) {
485
486         StorageOperationStatus associateUsers = assosiateToUsers(nodeTypeVertex, toscaElement);
487         if (associateUsers != StorageOperationStatus.OK) {
488             return associateUsers;
489         }
490         StorageOperationStatus associateArtifacts = associateArtifactsToResource(nodeTypeVertex, toscaElement);
491         if (associateArtifacts != StorageOperationStatus.OK) {
492             return associateArtifacts;
493         }
494         StorageOperationStatus associateProperties = associatePropertiesToResource(nodeTypeVertex, toscaElement, derivedResources);
495         if (associateProperties != StorageOperationStatus.OK) {
496             return associateProperties;
497         }
498         StorageOperationStatus associateAdditionaInfo = associateAdditionalInfoToResource(nodeTypeVertex, toscaElement);
499         if (associateAdditionaInfo != StorageOperationStatus.OK) {
500             return associateAdditionaInfo;
501         }
502         if (needConnectToCatalog(toscaElement)) {
503             StorageOperationStatus associateToCatalog = associateToCatalogRoot(nodeTypeVertex);
504             if (associateToCatalog != StorageOperationStatus.OK) {
505                 return associateToCatalog;
506             }
507         }
508         return StorageOperationStatus.OK;
509     }
510
511     private boolean needConnectToCatalog(ToscaElement toscaElement) {
512         Boolean isAbstract = (Boolean) toscaElement.getMetadataValue(JsonPresentationFields.IS_ABSTRACT);
513         if (isAbstract != null && isAbstract) {
514             return false;
515         }
516         return toscaElement.isHighestVersion();
517     }
518
519     private StorageOperationStatus associateToCatalogRoot(GraphVertex nodeTypeVertex) {
520         Either<GraphVertex, TitanOperationStatus> catalog = titanDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT);
521         if (catalog.isRight()) {
522             log.debug("Failed to fetch catalog vertex. error {}", catalog.right().value());
523             return DaoStatusConverter.convertTitanStatusToStorageStatus(catalog.right().value());
524         }
525         TitanOperationStatus createEdge = titanDao.createEdge(catalog.left().value(), nodeTypeVertex, EdgeLabelEnum.CATALOG_ELEMENT, null);
526
527         return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
528     }
529
530     protected StorageOperationStatus associatePropertiesToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType, List<GraphVertex> derivedResources) {
531         // Note : currently only one derived supported!!!!
532         Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.PROPERTIES);
533         if (dataFromDerived.isRight()) {
534             return dataFromDerived.right().value();
535         }
536         Map<String, PropertyDataDefinition> propertiesAll = dataFromDerived.left().value();
537
538         Map<String, PropertyDataDefinition> properties = nodeType.getProperties();
539
540         if (properties != null) {
541             properties.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
542                 String uid = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId(), p.getName());
543                 p.setUniqueId(uid);
544             });
545
546             Either<Map<String, PropertyDataDefinition>, String> eitherMerged = ToscaDataDefinition.mergeDataMaps(propertiesAll, properties);
547             if (eitherMerged.isRight()) {
548                 // TODO re-factor error handling - moving BL to operation resulted in loss of info about the invalid property
549                 log.debug("property {} cannot be overriden", eitherMerged.right().value());
550                 return StorageOperationStatus.INVALID_PROPERTY;
551             }
552         }
553         if (!propertiesAll.isEmpty()) {
554             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.PROPERTIES, EdgeLabelEnum.PROPERTIES, propertiesAll);
555             if (assosiateElementToData.isRight()) {
556                 return assosiateElementToData.right().value();
557             }
558         }
559         return StorageOperationStatus.OK;
560     }
561
562     private StorageOperationStatus associateAdditionalInfoToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
563         Map<String, AdditionalInfoParameterDataDefinition> additionalInformation = nodeType.getAdditionalInformation();
564         if (additionalInformation != null) {
565             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, additionalInformation);
566             if (assosiateElementToData.isRight()) {
567                 return assosiateElementToData.right().value();
568             }
569         }
570         return StorageOperationStatus.OK;
571     }
572
573     protected <T extends ToscaDataDefinition> Either<Map<String, T>, StorageOperationStatus> getDataFromDerived(List<GraphVertex> derivedResources, EdgeLabelEnum edge) {
574         Map<String, T> propertiesAll = new HashMap<>();
575
576         if (derivedResources != null && !derivedResources.isEmpty()) {
577             for (GraphVertex derived : derivedResources) {
578                 Either<List<GraphVertex>, TitanOperationStatus> derivedProperties = titanDao.getChildrenVertecies(derived, edge, JsonParseFlagEnum.ParseJson);
579                 if (derivedProperties.isRight()) {
580                     if (derivedProperties.right().value() != TitanOperationStatus.NOT_FOUND) {
581                         log.debug("Failed to get properties for derived from {} error {}", derived.getUniqueId(), derivedProperties.right().value());
582                         return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(derivedProperties.right().value()));
583                     } else {
584                         continue;
585                     }
586                 }
587                 List<GraphVertex> propList = derivedProperties.left().value();
588                 for (GraphVertex propV : propList) {
589                     Map<String, T> propertiesFromDerived = (Map<String, T>) propV.getJson();
590                     if (propertiesFromDerived != null) {
591                         propertiesFromDerived.entrySet().forEach(x -> x.getValue().setOwnerIdIfEmpty(derived.getUniqueId()));
592                         propertiesAll.putAll(propertiesFromDerived);
593                     }
594                 }
595             }
596         }
597         return Either.left(propertiesAll);
598     }
599
600     protected TitanOperationStatus setArtifactsFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
601         Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ARTIFACTS);
602         if (result.isLeft()) {
603             toscaElement.setArtifacts(result.left().value());
604         } else {
605             if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
606                 return result.right().value();
607             }
608         }
609         result = getDataFromGraph(componentV, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
610         if (result.isLeft()) {
611             toscaElement.setDeploymentArtifacts(result.left().value());
612         } else {
613             if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
614                 return result.right().value();
615             }
616         }
617         result = getDataFromGraph(componentV, EdgeLabelEnum.TOSCA_ARTIFACTS);
618         if (result.isLeft()) {
619             toscaElement.setToscaArtifacts(result.left().value());
620         } else {
621             if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
622                 return result.right().value();
623             }
624         }
625         return TitanOperationStatus.OK;
626     }
627
628     protected TitanOperationStatus setAllVersions(GraphVertex componentV, ToscaElement toscaElement) {
629         Map<String, String> allVersion = new HashMap<>();
630
631         allVersion.put((String) componentV.getMetadataProperty(GraphPropertyEnum.VERSION), componentV.getUniqueId());
632         ArrayList<GraphVertex> allChildrenAndParants = new ArrayList<GraphVertex>();
633         Either<GraphVertex, TitanOperationStatus> childResourceRes = titanDao.getChildVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
634         while (childResourceRes.isLeft()) {
635             GraphVertex child = childResourceRes.left().value();
636             allChildrenAndParants.add(child);
637             childResourceRes = titanDao.getChildVertex(child, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
638         }
639         TitanOperationStatus operationStatus = childResourceRes.right().value();
640
641         if (operationStatus != TitanOperationStatus.NOT_FOUND) {
642             return operationStatus;
643         } else {
644             Either<GraphVertex, TitanOperationStatus> parentResourceRes = titanDao.getParentVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
645             while (parentResourceRes.isLeft()) {
646                 GraphVertex parent = parentResourceRes.left().value();
647                 allChildrenAndParants.add(parent);
648                 parentResourceRes = titanDao.getParentVertex(parent, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
649             }
650             operationStatus = parentResourceRes.right().value();
651             if (operationStatus != TitanOperationStatus.NOT_FOUND) {
652                 return operationStatus;
653             } else {
654                 allChildrenAndParants.stream().filter(vertex -> {
655                     Boolean isDeleted = (Boolean) vertex.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
656                     return (isDeleted == null || isDeleted == false);
657                 }).forEach(vertex -> allVersion.put((String) vertex.getMetadataProperty(GraphPropertyEnum.VERSION), vertex.getUniqueId()));
658
659                 toscaElement.setAllVersions(allVersion);
660                 return TitanOperationStatus.OK;
661             }
662         }
663     }
664
665     protected <T extends ToscaElement> Either<List<T>, StorageOperationStatus> getFollowedComponent(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, ComponentTypeEnum neededType) {
666
667         Either<List<T>, StorageOperationStatus> result = null;
668
669         Map<GraphPropertyEnum, Object> props = null;
670
671         if (userId != null) {
672             props = new HashMap<>();
673             // for Designer retrieve specific user
674             props.put(GraphPropertyEnum.USERID, userId);
675         }
676         // in case of user id == null -> get all users by label
677         // for Tester and Admin retrieve all users
678         Either<List<GraphVertex>, TitanOperationStatus> usersByCriteria = titanDao.getByCriteria(VertexTypeEnum.USER, props, JsonParseFlagEnum.NoParse);
679         if (usersByCriteria.isRight()) {
680             log.debug("Failed to fetch users by criteria {} error {}", props, usersByCriteria.right().value());
681             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(usersByCriteria.right().value()));
682         }
683         List<GraphVertex> users = usersByCriteria.left().value();
684
685         List<T> components = new ArrayList<>();
686         List<T> componentsPerUser;
687         for (GraphVertex userV : users) {
688
689             HashSet<String> ids = new HashSet<String>();
690             Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.STATE, JsonParseFlagEnum.NoParse);
691             if (childrenVertecies.isRight() && childrenVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
692                 log.debug("Failed to fetch children vertices for user {} by edge {} error {}", userV.getMetadataProperty(GraphPropertyEnum.USERID), EdgeLabelEnum.STATE, childrenVertecies.right().value());
693                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
694             }
695
696             // get all resource with current state
697             if (childrenVertecies.isLeft()) {
698                 componentsPerUser = fetchComponents(lifecycleStates, childrenVertecies.left().value(), neededType, EdgeLabelEnum.STATE);
699
700                 if (componentsPerUser != null) {
701                     for (T comp : componentsPerUser) {
702                         ids.add(comp.getUniqueId());
703                         components.add(comp);
704                     }
705                 }
706             }
707             if (lastStateStates != null && !lastStateStates.isEmpty()) {
708                 // get all resource with last state
709                 childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.LAST_STATE, JsonParseFlagEnum.NoParse);
710                 if (childrenVertecies.isRight() && childrenVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
711                     log.debug("Failed to fetch children vertices for user {} by edge {} error {}", userV.getMetadataProperty(GraphPropertyEnum.USERID), EdgeLabelEnum.LAST_STATE, childrenVertecies.right().value());
712                     return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
713                 }
714                 if (childrenVertecies.isLeft()) {
715                     boolean isFirst;
716                     componentsPerUser = fetchComponents(lastStateStates, childrenVertecies.left().value(), neededType, EdgeLabelEnum.LAST_STATE);
717                     if (componentsPerUser != null) {
718                         for (T comp : componentsPerUser) {
719                             isFirst = true;
720
721                             if (ids.contains(comp.getUniqueId())) {
722                                 isFirst = false;
723                             }
724                             if (isFirst == true) {
725                                 components.add(comp);
726                             }
727
728                         }
729                     }
730                 }
731             }
732
733         } // whlile users
734         ;
735         result = Either.left(components);
736         return result;
737
738     }
739
740     private <T extends ToscaElement> List<T> fetchComponents(Set<LifecycleStateEnum> lifecycleStates, List<GraphVertex> vertices, ComponentTypeEnum neededType, EdgeLabelEnum edgelabel) {
741         List<T> components = new ArrayList<>();
742         for (GraphVertex node : vertices) {
743
744             Iterator<Edge> edges = node.getVertex().edges(Direction.IN, edgelabel.name());
745             while (edges.hasNext()) {
746                 Edge edge = edges.next();
747                 String stateStr = (String) titanDao.getProperty(edge, EdgePropertyEnum.STATE);
748
749                 LifecycleStateEnum nodeState = LifecycleStateEnum.findState(stateStr);
750                 if (nodeState == null) {
751                     log.debug("no supported STATE {} for element  {}", stateStr, node.getUniqueId());
752                     continue;
753                 }
754                 if (lifecycleStates != null && lifecycleStates.contains(nodeState)) {
755
756                     Boolean isDeleted = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
757                     if (isDeleted != null && isDeleted) {
758                         log.trace("Deleted element  {}, discard", node.getUniqueId());
759                         continue;
760                     }
761
762                     Boolean isHighest = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
763                     if (isHighest) {
764
765                         ComponentTypeEnum componentType = node.getType();
766                         // get only latest versions
767
768                         if (componentType == null) {
769                             log.debug("No supported type {} for vertex {}", componentType, node.getUniqueId());
770                             continue;
771                         }
772                         if (neededType == componentType) {
773                             switch (componentType) {
774                             case SERVICE:
775                             case PRODUCT:
776                                 handleNode(components, node, componentType);
777                                 break;
778                             case RESOURCE:
779                                 Boolean isAbtract = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
780                                 if (isAbtract == null || false == isAbtract) {
781                                     handleNode(components, node, componentType);
782                                 } // if not abstract
783                                 break;
784                             default:
785                                 log.debug("not supported node type {}", componentType);
786                                 break;
787                             }// case
788                         } // needed type
789                     }
790                 } // if
791             } // while edges
792         } // while resources
793         return components;
794     }
795
796     protected <T extends ToscaElement> void handleNode(List<T> components, GraphVertex vertexComponent, ComponentTypeEnum nodeType) {
797
798         Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, nodeType, new ComponentParametersView(true));
799         if (component.isRight()) {
800             log.debug("Failed to get component for id =  {}  error : {} skip resource", vertexComponent.getUniqueId(), component.right().value());
801         } else {
802             components.add(component.left().value());
803         }
804     }
805
806     protected <T extends ToscaElement> Either<T, StorageOperationStatus> getLightComponent(String componentUid, ComponentTypeEnum nodeType, ComponentParametersView parametersFilter) {
807         Either<GraphVertex, TitanOperationStatus> getVertexRes = titanDao.getVertexById(componentUid);
808         if (getVertexRes.isRight()) {
809             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexRes.right().value()));
810         }
811         return getLightComponent(getVertexRes.left().value(), nodeType, parametersFilter);
812     }
813
814     protected <T extends ToscaElement> Either<T, StorageOperationStatus> getLightComponent(GraphVertex vertexComponent, ComponentTypeEnum nodeType, ComponentParametersView parametersFilter) {
815
816         log.trace("Starting to build light component of type {}, id {}", nodeType, vertexComponent.getUniqueId());
817
818         titanDao.parseVertexProperties(vertexComponent, JsonParseFlagEnum.ParseMetadata);
819
820         T toscaElement = convertToComponent(vertexComponent);
821
822         TitanOperationStatus status = setCreatorFromGraph(vertexComponent, toscaElement);
823         if (status != TitanOperationStatus.OK) {
824             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
825         }
826
827         status = setLastModifierFromGraph(vertexComponent, toscaElement);
828         if (status != TitanOperationStatus.OK) {
829             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
830         }
831         status = setCategoriesFromGraph(vertexComponent, toscaElement);
832         if (status != TitanOperationStatus.OK) {
833             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
834         }
835         if (!parametersFilter.isIgnoreAllVersions()) {
836             status = setAllVersions(vertexComponent, toscaElement);
837             if (status != TitanOperationStatus.OK) {
838                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
839             }
840         }
841         if (!parametersFilter.isIgnoreCapabilities()) {
842             status = setCapabilitiesFromGraph(vertexComponent, toscaElement);
843             if (status != TitanOperationStatus.OK) {
844                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
845             }
846         }
847         if (!parametersFilter.isIgnoreRequirements()) {
848             status = setRequirementsFromGraph(vertexComponent, toscaElement);
849             if (status != TitanOperationStatus.OK) {
850                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
851             }
852         }
853         log.debug("Ended to build light component of type {}, id {}", nodeType, vertexComponent.getUniqueId());
854         return Either.left(toscaElement);
855     }
856
857     @SuppressWarnings("unchecked")
858     protected <T extends ToscaElement> T convertToComponent(GraphVertex componentV) {
859         ToscaElement toscaElement = null;
860         VertexTypeEnum label = componentV.getLabel();
861         switch (label) {
862         case NODE_TYPE:
863             toscaElement = new NodeType();
864             break;
865         case TOPOLOGY_TEMPLATE:
866             toscaElement = new TopologyTemplate();
867             break;
868         default:
869             log.debug("Not supported tosca type {}", label);
870             break;
871         }
872
873         Map<String, Object> jsonMetada = componentV.getMetadataJson();
874         if (toscaElement != null) {
875             toscaElement.setMetadata(jsonMetada);
876         }
877         return (T) toscaElement;
878     }
879
880     protected TitanOperationStatus setServiceCategoryFromGraphV(Vertex vertex, CatalogComponent catalogComponent) {
881         Either<Vertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(vertex, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
882         if (childVertex.isRight()) {
883             log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, catalogComponent.getUniqueId(), childVertex.right().value());
884             return childVertex.right().value();
885         }
886         Vertex categoryV = childVertex.left().value();
887         catalogComponent.setCategoryNormalizedName((String) categoryV.property(JsonPresentationFields.NORMALIZED_NAME.getPresentation()).value());
888
889         return TitanOperationStatus.OK;
890     }
891
892     protected TitanOperationStatus setResourceCategoryFromGraphV(Vertex vertex, CatalogComponent catalogComponent) {
893
894         Either<Vertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(vertex, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
895         if (childVertex.isRight()) {
896             log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, catalogComponent.getUniqueId(), childVertex.right().value());
897             return childVertex.right().value();
898         }
899         Vertex subCategoryV = childVertex.left().value();
900         catalogComponent.setSubCategoryNormalizedName((String) subCategoryV.property(JsonPresentationFields.NORMALIZED_NAME.getPresentation()).value());
901         Either<Vertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
902         Vertex categoryV = parentVertex.left().value();
903         catalogComponent.setCategoryNormalizedName((String) categoryV.property(JsonPresentationFields.NORMALIZED_NAME.getPresentation()).value());
904
905         return TitanOperationStatus.OK;
906     }
907
908     protected TitanOperationStatus setResourceCategoryFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
909         List<CategoryDefinition> categories = new ArrayList<>();
910         SubCategoryDefinition subcategory;
911
912         Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(componentV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
913         if (childVertex.isRight()) {
914             log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, componentV.getUniqueId(), childVertex.right().value());
915             return childVertex.right().value();
916         }
917         GraphVertex subCategoryV = childVertex.left().value();
918         Map<GraphPropertyEnum, Object> metadataProperties = subCategoryV.getMetadataProperties();
919         subcategory = new SubCategoryDefinition();
920         subcategory.setUniqueId(subCategoryV.getUniqueId());
921         subcategory.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
922         subcategory.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
923
924         Type listTypeSubcat = new TypeToken<List<String>>() {
925         }.getType();
926         List<String> iconsfromJsonSubcat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeSubcat);
927         subcategory.setIcons(iconsfromJsonSubcat);
928
929         Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
930         if (parentVertex.isRight()) {
931             log.debug("failed to fetch {} for category with id {}, error {}", EdgeLabelEnum.SUB_CATEGORY, subCategoryV.getUniqueId(), parentVertex.right().value());
932             return childVertex.right().value();
933         }
934         GraphVertex categoryV = parentVertex.left().value();
935         metadataProperties = categoryV.getMetadataProperties();
936
937         CategoryDefinition category = new CategoryDefinition();
938         category.setUniqueId(categoryV.getUniqueId());
939         category.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
940         category.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
941
942         Type listTypeCat = new TypeToken<List<String>>() {
943         }.getType();
944         List<String> iconsfromJsonCat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeCat);
945         category.setIcons(iconsfromJsonCat);
946
947         category.addSubCategory(subcategory);
948         categories.add(category);
949         toscaElement.setCategories(categories);
950
951         return TitanOperationStatus.OK;
952     }
953
954     public <T extends ToscaElement> Either<T, StorageOperationStatus> updateToscaElement(T toscaElementToUpdate, GraphVertex elementV, ComponentParametersView filterResult) {
955         Either<T, StorageOperationStatus> result = null;
956
957         log.debug("In updateToscaElement. received component uid = {}", (toscaElementToUpdate == null ? null : toscaElementToUpdate.getUniqueId()));
958         if (toscaElementToUpdate == null) {
959             log.error("Service object is null");
960             result = Either.right(StorageOperationStatus.BAD_REQUEST);
961             return result;
962         }
963
964         String modifierUserId = toscaElementToUpdate.getLastUpdaterUserId();
965         if (modifierUserId == null || modifierUserId.isEmpty()) {
966             log.error("UserId is missing in the request.");
967             result = Either.right(StorageOperationStatus.BAD_REQUEST);
968             return result;
969         }
970         Either<GraphVertex, TitanOperationStatus> findUser = findUserVertex(modifierUserId);
971
972         if (findUser.isRight()) {
973             TitanOperationStatus status = findUser.right().value();
974             log.error("Cannot find user {} in the graph. status is {}", modifierUserId, status);
975             return result;
976         }
977
978         GraphVertex modifierV = findUser.left().value();
979         // UserData modifierUserData = findUser.left().value();
980         String toscaElementId = toscaElementToUpdate.getUniqueId();
981
982         Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(elementV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
983         if (parentVertex.isRight()) {
984             log.debug("Failed to fetch last modifier for tosca element with id {} error {}", toscaElementId, parentVertex.right().value());
985             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentVertex.right().value()));
986         }
987         GraphVertex userV = parentVertex.left().value();
988         String currentModifier = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
989
990         String prevSystemName = (String) elementV.getMetadataProperty(GraphPropertyEnum.SYSTEM_NAME);
991
992         if (currentModifier.equals(modifierUserId)) {
993             log.debug("Graph LAST MODIFIER edge should not be changed since the modifier is the same as the last modifier.");
994         } else {
995             log.debug("Going to update the last modifier user of the resource from {} to {}", currentModifier, modifierUserId);
996             StorageOperationStatus status = moveLastModifierEdge(elementV, modifierV);
997             log.debug("Finish to update the last modifier user of the resource from {} to {}. status is {}", currentModifier, modifierUserId, status);
998             if (status != StorageOperationStatus.OK) {
999                 result = Either.right(status);
1000                 return result;
1001             }
1002         }
1003
1004         final long currentTimeMillis = System.currentTimeMillis();
1005         log.debug("Going to update the last Update Date of the resource from {} to {}", elementV.getJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE), currentTimeMillis);
1006         elementV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currentTimeMillis);
1007
1008         StorageOperationStatus checkCategories = validateCategories(toscaElementToUpdate, elementV);
1009         if (checkCategories != StorageOperationStatus.OK) {
1010             result = Either.right(checkCategories);
1011             return result;
1012         }
1013
1014         // update all data on vertex
1015         fillToscaElementVertexData(elementV, toscaElementToUpdate, JsonParseFlagEnum.ParseMetadata);
1016
1017         Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(elementV);
1018
1019         if (updateElement.isRight()) {
1020             log.error("Failed to update resource {}. status is {}", toscaElementId, updateElement.right().value());
1021             result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
1022             return result;
1023         }
1024         GraphVertex updateElementV = updateElement.left().value();
1025
1026         // DE230195 in case resource name changed update TOSCA artifacts
1027         // file names accordingly
1028         String newSystemName = (String) updateElementV.getMetadataProperty(GraphPropertyEnum.SYSTEM_NAME);
1029         if (newSystemName != null && !newSystemName.equals(prevSystemName)) {
1030             Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> resultToscaArt = getDataFromGraph(updateElementV, EdgeLabelEnum.TOSCA_ARTIFACTS);
1031             if (resultToscaArt.isRight()) {
1032                 log.debug("Failed to get  tosca artifact from graph for tosca element {} error {}", toscaElementId, resultToscaArt.right().value());
1033                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resultToscaArt.right().value()));
1034             }
1035
1036             Map<String, ArtifactDataDefinition> toscaArtifacts = resultToscaArt.left().value();
1037             if (toscaArtifacts != null) {
1038                 for (Entry<String, ArtifactDataDefinition> artifact : toscaArtifacts.entrySet()) {
1039                     generateNewToscaFileName(toscaElementToUpdate.getComponentType().getValue().toLowerCase(), newSystemName, artifact.getValue());
1040                 }
1041                 // TODO call to new Artifact operation in order to update list of artifacts
1042
1043             }
1044             // US833308 VLI in service - specific network_role property value logic
1045             if (ComponentTypeEnum.SERVICE == toscaElementToUpdate.getComponentType()) {
1046                 // update method logs success/error and returns boolean (true if nothing fails)
1047                 // TODO!!!!
1048                 // updateServiceNameInVLIsNetworkRolePropertyValues(component, prevSystemName, newSystemName);
1049             }
1050         }
1051
1052         if (toscaElementToUpdate.getComponentType() == ComponentTypeEnum.RESOURCE) {
1053             StorageOperationStatus resultDerived = updateDerived(toscaElementToUpdate, updateElementV);
1054             if (resultDerived != StorageOperationStatus.OK) {
1055                 log.debug("Failed to update from derived data for element {} error {}", toscaElementId, resultDerived);
1056                 return Either.right(resultDerived);
1057             }
1058         }
1059
1060         Either<T, StorageOperationStatus> updatedResource = getToscaElement(updateElementV, filterResult);
1061         if (updatedResource.isRight()) {
1062             log.error("Failed to fetch tosca element {} after update , error {}", toscaElementId, updatedResource.right().value());
1063             result = Either.right(StorageOperationStatus.BAD_REQUEST);
1064             return result;
1065         }
1066
1067         T updatedResourceValue = updatedResource.left().value();
1068         result = Either.left(updatedResourceValue);
1069
1070         return result;
1071     }
1072
1073     protected StorageOperationStatus moveLastModifierEdge(GraphVertex elementV, GraphVertex modifierV) {
1074         return DaoStatusConverter.convertTitanStatusToStorageStatus(titanDao.moveEdge(elementV, modifierV, EdgeLabelEnum.LAST_MODIFIER, Direction.IN));
1075     }
1076
1077     protected StorageOperationStatus moveCategoryEdge(GraphVertex elementV, GraphVertex categoryV) {
1078         return DaoStatusConverter.convertTitanStatusToStorageStatus(titanDao.moveEdge(elementV, categoryV, EdgeLabelEnum.CATEGORY, Direction.OUT));
1079     }
1080
1081     private void generateNewToscaFileName(String componentType, String componentName, ArtifactDataDefinition artifactInfo) {
1082         Map<String, Object> getConfig = (Map<String, Object>) ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts().entrySet().stream().filter(p -> p.getKey().equalsIgnoreCase(artifactInfo.getArtifactLabel()))
1083                 .findAny().get().getValue();
1084         artifactInfo.setArtifactName(componentType + "-" + componentName + getConfig.get("artifactName"));
1085     }
1086
1087     protected <T extends ToscaElement> StorageOperationStatus validateResourceCategory(T toscaElementToUpdate, GraphVertex elementV) {
1088         StorageOperationStatus status = StorageOperationStatus.OK;
1089         List<CategoryDefinition> newCategoryList = toscaElementToUpdate.getCategories();
1090         CategoryDefinition newCategory = newCategoryList.get(0);
1091
1092         Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(elementV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
1093         if (childVertex.isRight()) {
1094             log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, elementV.getUniqueId(), childVertex.right().value());
1095             return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
1096         }
1097         GraphVertex subCategoryV = childVertex.left().value();
1098         Map<GraphPropertyEnum, Object> metadataProperties = subCategoryV.getMetadataProperties();
1099         String subCategoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
1100
1101         Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
1102         if (parentVertex.isRight()) {
1103             log.debug("failed to fetch {} for category with id {}, error {}", EdgeLabelEnum.SUB_CATEGORY, subCategoryV.getUniqueId(), parentVertex.right().value());
1104             return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
1105         }
1106         GraphVertex categoryV = parentVertex.left().value();
1107         metadataProperties = categoryV.getMetadataProperties();
1108         String categoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
1109
1110         boolean categoryWasChanged = false;
1111
1112         String newCategoryName = newCategory.getName();
1113         SubCategoryDefinition newSubcategory = newCategory.getSubcategories().get(0);
1114         String newSubCategoryName = newSubcategory.getName();
1115         if (newCategoryName != null && false == newCategoryName.equals(categoryNameCurrent)) {
1116             // the category was changed
1117             categoryWasChanged = true;
1118         } else {
1119             // the sub-category was changed
1120             if (newSubCategoryName != null && false == newSubCategoryName.equals(subCategoryNameCurrent)) {
1121                 log.debug("Going to update the category of the resource from {} to {}", categoryNameCurrent, newCategory);
1122                 categoryWasChanged = true;
1123             }
1124         }
1125         if (categoryWasChanged) {
1126             Either<GraphVertex, StorageOperationStatus> getCategoryVertex = getResourceCategoryVertex(elementV.getUniqueId(), newSubCategoryName, newCategoryName);
1127
1128             if (getCategoryVertex.isRight()) {
1129                 return getCategoryVertex.right().value();
1130             }
1131             GraphVertex newCategoryV = getCategoryVertex.left().value();
1132             status = moveCategoryEdge(elementV, newCategoryV);
1133             log.debug("Going to update the category of the resource from {} to {}. status is {}", categoryNameCurrent, newCategory, status);
1134         }
1135         return status;
1136     }
1137
1138     public <T extends ToscaElement> Either<List<T>, StorageOperationStatus> getElementCatalogData(ComponentTypeEnum componentType, List<ResourceTypeEnum> excludeTypes, boolean isHighestVersions) {
1139         Either<List<GraphVertex>, TitanOperationStatus> listOfComponents;
1140         if (isHighestVersions) {
1141             listOfComponents = getListOfHighestComponents(componentType, excludeTypes, JsonParseFlagEnum.NoParse);
1142         } else {
1143             listOfComponents = getListOfHighestAndAllCertifiedComponents(componentType, excludeTypes);
1144         }
1145
1146         if (listOfComponents.isRight() && listOfComponents.right().value() != TitanOperationStatus.NOT_FOUND) {
1147             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(listOfComponents.right().value()));
1148         }
1149         List<T> result = new ArrayList<>();
1150         if (listOfComponents.isLeft()) {
1151             List<GraphVertex> highestAndAllCertified = listOfComponents.left().value();
1152             if (highestAndAllCertified != null && false == highestAndAllCertified.isEmpty()) {
1153                 for (GraphVertex vertexComponent : highestAndAllCertified) {
1154                     Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, componentType, new ComponentParametersView(true));
1155                     if (component.isRight()) {
1156                         log.debug("Failed to fetch light element for {} error {}", vertexComponent.getUniqueId(), component.right().value());
1157                         return Either.right(component.right().value());
1158                     } else {
1159                         result.add(component.left().value());
1160                     }
1161                 }
1162             }
1163         }
1164         return Either.left(result);
1165     }
1166
1167     public Either<List<CatalogComponent>, StorageOperationStatus> getElementCatalogData() {
1168         List<CatalogComponent> results = new ArrayList<>();
1169         StopWatch stopWatch = new StopWatch();
1170         stopWatch.start();
1171
1172         Either<Iterator<Vertex>, TitanOperationStatus> verticesEither = titanDao.getCatalogVerticies();
1173         if (verticesEither.isRight()) {
1174             return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(verticesEither.right().value()));
1175         }
1176         Iterator<Vertex> vertices = verticesEither.left().value();
1177         while (vertices.hasNext()) {
1178             Vertex vertex = vertices.next();
1179             VertexProperty<Object> property = vertex.property(GraphPropertiesDictionary.METADATA.getProperty());
1180             String json = (String) property.value();
1181
1182             CatalogComponent catalogComponent = new CatalogComponent();
1183             Map<String, Object> metadatObj = JsonParserUtils.toMap(json);
1184
1185             catalogComponent.setComponentType(ComponentTypeEnum.valueOf((String) metadatObj.get(JsonPresentationFields.COMPONENT_TYPE.getPresentation())));
1186             catalogComponent.setVersion((String) metadatObj.get(JsonPresentationFields.VERSION.getPresentation()));
1187             catalogComponent.setName((String) metadatObj.get(JsonPresentationFields.NAME.getPresentation()));
1188             catalogComponent.setIcon((String) metadatObj.get(JsonPresentationFields.ICON.getPresentation()));
1189             catalogComponent.setUniqueId((String) metadatObj.get(JsonPresentationFields.UNIQUE_ID.getPresentation()));
1190             catalogComponent.setLifecycleState((String) metadatObj.get(JsonPresentationFields.LIFECYCLE_STATE.getPresentation()));
1191             catalogComponent.setLastUpdateDate((Long) metadatObj.get(JsonPresentationFields.LAST_UPDATE_DATE.getPresentation()));
1192             catalogComponent.setDistributionStatus((String) metadatObj.get(JsonPresentationFields.DISTRIBUTION_STATUS.getPresentation()));
1193             Object resourceType = metadatObj.get(JsonPresentationFields.RESOURCE_TYPE.getPresentation());
1194             if (resourceType != null) {
1195                 catalogComponent.setResourceType((String) resourceType);
1196             }
1197
1198             if (catalogComponent.getComponentType() == ComponentTypeEnum.SERVICE) {
1199                 setServiceCategoryFromGraphV(vertex, catalogComponent);
1200
1201             } else {
1202                 setResourceCategoryFromGraphV(vertex, catalogComponent);
1203             }
1204             results.add(catalogComponent);
1205
1206         }
1207         stopWatch.stop();
1208         String timeToFetchElements = stopWatch.prettyPrint();
1209         log.info("time to fetch all catalog elements: {}", timeToFetchElements);
1210         return Either.left(results);
1211     }
1212
1213     public Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestComponents(ComponentTypeEnum componentType, List<ResourceTypeEnum> excludeTypes, JsonParseFlagEnum parseFlag) {
1214         Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
1215         Map<GraphPropertyEnum, Object> propertiesHasNotToMatch = new HashMap<>();
1216         propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1217         propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1218
1219         if (componentType == ComponentTypeEnum.RESOURCE) {
1220             propertiesToMatch.put(GraphPropertyEnum.IS_ABSTRACT, false);
1221             propertiesHasNotToMatch.put(GraphPropertyEnum.RESOURCE_TYPE, excludeTypes);
1222         }
1223         propertiesHasNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
1224
1225         return titanDao.getByCriteria(null, propertiesToMatch, propertiesHasNotToMatch, parseFlag);
1226     }
1227
1228     // highest + (certified && !highest)
1229     public Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestAndAllCertifiedComponents(ComponentTypeEnum componentType, List<ResourceTypeEnum> excludeTypes) {
1230         long startFetchAllStates = System.currentTimeMillis();
1231         Either<List<GraphVertex>, TitanOperationStatus> highestNodes = getListOfHighestComponents(componentType, excludeTypes, JsonParseFlagEnum.ParseMetadata);
1232
1233         Map<GraphPropertyEnum, Object> propertiesToMatchCertified = new HashMap<>();
1234         Map<GraphPropertyEnum, Object> propertiesHasNotToMatchCertified = new HashMap<>();
1235         propertiesToMatchCertified.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1236         propertiesToMatchCertified.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1237         if (componentType == ComponentTypeEnum.RESOURCE) {
1238             propertiesToMatchCertified.put(GraphPropertyEnum.IS_ABSTRACT, false);
1239             propertiesHasNotToMatchCertified.put(GraphPropertyEnum.RESOURCE_TYPE, excludeTypes);
1240         }
1241
1242         propertiesHasNotToMatchCertified.put(GraphPropertyEnum.IS_DELETED, true);
1243         propertiesHasNotToMatchCertified.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1244
1245         Either<List<GraphVertex>, TitanOperationStatus> certifiedNotHighestNodes = titanDao.getByCriteria(null, propertiesToMatchCertified, propertiesHasNotToMatchCertified, JsonParseFlagEnum.ParseMetadata);
1246         if (certifiedNotHighestNodes.isRight() && certifiedNotHighestNodes.right().value() != TitanOperationStatus.NOT_FOUND) {
1247             return Either.right(certifiedNotHighestNodes.right().value());
1248         }
1249
1250         long endFetchAllStates = System.currentTimeMillis();
1251
1252         List<GraphVertex> allNodes = new ArrayList<>();
1253
1254         if (certifiedNotHighestNodes.isLeft()) {
1255             allNodes.addAll(certifiedNotHighestNodes.left().value());
1256         }
1257         if (highestNodes.isLeft()) {
1258             allNodes.addAll(highestNodes.left().value());
1259         }
1260
1261         log.debug("Fetch catalog {}s all states from graph took {} ms", componentType, endFetchAllStates - startFetchAllStates);
1262         return Either.left(allNodes);
1263     }
1264
1265     protected Either<List<GraphVertex>, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum componentType) {
1266
1267         // get all components marked for delete
1268         Map<GraphPropertyEnum, Object> props = new HashMap<GraphPropertyEnum, Object>();
1269         props.put(GraphPropertyEnum.IS_DELETED, true);
1270         props.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1271
1272         Either<List<GraphVertex>, TitanOperationStatus> componentsToDelete = titanDao.getByCriteria(null, props, JsonParseFlagEnum.NoParse);
1273
1274         if (componentsToDelete.isRight()) {
1275             TitanOperationStatus error = componentsToDelete.right().value();
1276             if (error.equals(TitanOperationStatus.NOT_FOUND)) {
1277                 log.trace("no components to delete");
1278                 return Either.left(new ArrayList<>());
1279             } else {
1280                 log.info("failed to find components to delete. error : {}", error.name());
1281                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1282             }
1283         }
1284         return Either.left(componentsToDelete.left().value());
1285     }
1286
1287     protected TitanOperationStatus setAdditionalInformationFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
1288         Either<Map<String, AdditionalInfoParameterDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ADDITIONAL_INFORMATION);
1289         if (result.isLeft()) {
1290             toscaElement.setAdditionalInformation(result.left().value());
1291         } else {
1292             if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
1293                 return result.right().value();
1294             }
1295         }
1296         return TitanOperationStatus.OK;
1297     }
1298
1299     // --------------------------------------------
1300     public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView);
1301
1302     public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(GraphVertex toscaElementVertex, ComponentParametersView componentParametersView);
1303
1304     public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex);
1305
1306     public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> createToscaElement(ToscaElement toscaElement);
1307
1308     protected abstract <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement);
1309
1310     protected abstract <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement);
1311
1312     protected abstract <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement);
1313
1314     protected abstract <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV);
1315
1316     protected abstract <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex updateElementV);
1317
1318     public abstract <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag);
1319
1320 }