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