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