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