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