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