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