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