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