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