Catalog alignment
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsonjanusgraph / operations / NodeTypeOperation.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 fj.data.Either;
24 import org.apache.tinkerpop.gremlin.structure.Direction;
25 import org.apache.tinkerpop.gremlin.structure.Edge;
26 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
27 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
28 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
29 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
30 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
31 import org.openecomp.sdc.be.datatypes.elements.*;
32 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
33 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
34 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
35 import org.openecomp.sdc.be.model.ComponentParametersView;
36 import org.openecomp.sdc.be.model.DerivedNodeTypeResolver;
37 import org.openecomp.sdc.be.model.LifecycleStateEnum;
38 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.NodeType;
39 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement;
40 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElementTypeEnum;
41 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
42 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
43 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
44 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
45 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
46 import org.openecomp.sdc.common.log.wrappers.Logger;
47 import org.springframework.beans.factory.annotation.Qualifier;
48
49 import java.util.*;
50 import java.util.regex.Pattern;
51 import java.util.stream.Collectors;
52
53 @org.springframework.stereotype.Component("node-type-operation")
54 public class NodeTypeOperation extends ToscaElementOperation {
55     public static final Pattern uuidNewVersion = Pattern.compile("^\\d+.1");
56     public static final Pattern uuidNormativeNewVersion = Pattern.compile("^\\d+.0");
57     private static final Logger log = Logger.getLogger(NodeTypeOperation.class);
58     private DerivedNodeTypeResolver derivedResourceResolver;
59
60     
61     public NodeTypeOperation(@Qualifier("derived-resource-resolver") DerivedNodeTypeResolver derivedNodeTypeResolver) {
62         this.derivedResourceResolver = derivedNodeTypeResolver;
63     }
64
65     public Either<NodeType, StorageOperationStatus> createNodeType(NodeType nodeType) {
66
67         Either<NodeType, StorageOperationStatus> result = null;
68
69         nodeType.generateUUID();
70
71         nodeType = getResourceMetaDataFromResource(nodeType);
72         String resourceUniqueId = nodeType.getUniqueId();
73         if (resourceUniqueId == null) {
74             resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId();
75             nodeType.setUniqueId(resourceUniqueId);
76         }
77
78         // get derived from resources
79         List<GraphVertex> derivedResources = null;
80         Either<List<GraphVertex>, StorageOperationStatus> derivedResourcesResult = findDerivedResources(nodeType);
81         if (derivedResourcesResult.isRight()) {
82             result = Either.right(derivedResourcesResult.right().value());
83             return result;
84         } else {
85             derivedResources = derivedResourcesResult.left().value();
86         }
87
88         GraphVertex nodeTypeVertex = new GraphVertex(VertexTypeEnum.NODE_TYPE);
89         fillToscaElementVertexData(nodeTypeVertex, nodeType, JsonParseFlagEnum.ParseAll);
90
91         Either<GraphVertex, JanusGraphOperationStatus> createdVertex = janusGraphDao.createVertex(nodeTypeVertex);
92         if (createdVertex.isRight()) {
93             JanusGraphOperationStatus status = createdVertex.right().value();
94             log.error("Error returned after creating resource data node {}. status returned is ", nodeTypeVertex, status);
95             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
96             return result;
97         }
98         nodeTypeVertex = createdVertex.left().value();
99
100         StorageOperationStatus assosiateCommon = assosiateCommonForToscaElement(nodeTypeVertex, nodeType, derivedResources);
101         if (assosiateCommon != StorageOperationStatus.OK) {
102             result = Either.right(assosiateCommon);
103             return result;
104         }
105
106         StorageOperationStatus associateDerived = assosiateToDerived(nodeTypeVertex, derivedResources);
107         if (associateDerived != StorageOperationStatus.OK) {
108             result = Either.right(associateDerived);
109             return result;
110         }
111         StorageOperationStatus associateCategory = assosiateResourceMetadataToCategory(nodeTypeVertex, nodeType);
112         if (associateCategory != StorageOperationStatus.OK) {
113             result = Either.right(associateCategory);
114             return result;
115         }
116
117         StorageOperationStatus associateAttributes = associateAttributesToResource(nodeTypeVertex, nodeType, derivedResources);
118         if (associateAttributes != StorageOperationStatus.OK) {
119             result = Either.right(associateAttributes);
120             return result;
121         }
122
123         StorageOperationStatus associateRequirements = associateRequirementsToResource(nodeTypeVertex, nodeType, derivedResources);
124         if (associateRequirements != StorageOperationStatus.OK) {
125             result = Either.right(associateRequirements);
126             return result;
127         }
128
129         StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(nodeTypeVertex, nodeType, derivedResources);
130         if (associateCapabilities != StorageOperationStatus.OK) {
131             result = Either.right(associateCapabilities);
132             return result;
133         }
134         StorageOperationStatus associateCapabilitiesProps = associateCapabilitiesPropertiesToResource(nodeTypeVertex, nodeType, derivedResources);
135         if (associateCapabilitiesProps != StorageOperationStatus.OK) {
136             result = Either.right(associateCapabilitiesProps);
137             return result;
138         }
139
140         StorageOperationStatus associateInterfaces = associateInterfacesToResource(nodeTypeVertex, nodeType, derivedResources);
141         if (associateInterfaces != StorageOperationStatus.OK) {
142             result = Either.right(associateInterfaces);
143             return result;
144         }
145
146         StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(nodeTypeVertex, nodeType, derivedResources);
147         if (addAdditionalInformation != StorageOperationStatus.OK) {
148             result = Either.right(addAdditionalInformation);
149             return result;
150         }
151         result = Either.left(nodeType);
152         return result;
153
154     }
155
156     private StorageOperationStatus associateInterfacesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
157         // Note : currently only one derived supported!!!!
158         Either<Map<String, InterfaceDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.INTERFACE_ARTIFACTS);
159         if (dataFromDerived.isRight()) {
160             return dataFromDerived.right().value();
161         }
162         Map<String, InterfaceDataDefinition> interfacArtsAll = dataFromDerived.left().value();
163
164         Map<String, InterfaceDataDefinition> interfacArts = nodeType.getInterfaceArtifacts();
165         if (interfacArts != null) {
166             interfacArtsAll.putAll(interfacArts);
167         }
168         if (!interfacArtsAll.isEmpty()) {
169             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.INTERFACE_ARTIFACTS, EdgeLabelEnum.INTERFACE_ARTIFACTS, interfacArtsAll);
170             if (assosiateElementToData.isRight()) {
171                 return assosiateElementToData.right().value();
172             }
173         }
174         return StorageOperationStatus.OK;
175     }
176
177     @Override
178     public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView) {
179
180         Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(uniqueId, ToscaElementTypeEnum.NODE_TYPE, JsonParseFlagEnum.ParseMetadata);
181         if (componentByLabelAndId.isRight()) {
182             return Either.right(componentByLabelAndId.right().value());
183         }
184         GraphVertex componentV = componentByLabelAndId.left().value();
185
186         return getToscaElement(componentV, componentParametersView);
187
188     }
189
190     // -------------------------------------------------------------
191     @Override
192     public Either<ToscaElement, StorageOperationStatus> getToscaElement(GraphVertex componentV, ComponentParametersView componentParametersView) {
193         NodeType toscaElement;
194         toscaElement = convertToComponent(componentV);
195         JanusGraphOperationStatus status = null;
196         if (!componentParametersView.isIgnoreUsers()) {
197             status = setCreatorFromGraph(componentV, toscaElement);
198             if (status != JanusGraphOperationStatus.OK) {
199                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
200             }
201
202             status = setLastModifierFromGraph(componentV, toscaElement);
203             if (status != JanusGraphOperationStatus.OK) {
204                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
205             }
206         }
207
208         if (!componentParametersView.isIgnoreProperties()) {
209             status = setResourcePropertiesFromGraph(componentV, toscaElement);
210             if (status != JanusGraphOperationStatus.OK && status != JanusGraphOperationStatus.NOT_FOUND) {
211                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
212             }
213         }
214
215         if (!componentParametersView.isIgnoreAttributesFrom()) {
216             status = setResourceAttributesFromGraph(componentV, toscaElement);
217             if (status != JanusGraphOperationStatus.OK) {
218                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
219             }
220         }
221
222         if (!componentParametersView.isIgnoreDerivedFrom()) {
223             status = setResourceDerivedFromGraph(componentV, toscaElement);
224             if (status != JanusGraphOperationStatus.OK) {
225                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
226             }
227         }
228
229         if (!componentParametersView.isIgnoreCategories()) {
230             status = setResourceCategoryFromGraph(componentV, toscaElement);
231             if (status != JanusGraphOperationStatus.OK) {
232                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
233             }
234         }
235         if (!componentParametersView.isIgnoreRequirements()) {
236             status = setResourceRequirementsFromGraph(componentV, toscaElement);
237             if (status != JanusGraphOperationStatus.OK) {
238                 log.error("Failed to set requirement of resource {}. status is {}", componentV.getUniqueId(), status);
239                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
240             }
241         }
242         if (!componentParametersView.isIgnoreCapabilities()) {
243             status = setResourceCapabilitiesFromGraph(componentV, toscaElement);
244             if (status != JanusGraphOperationStatus.OK) {
245                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
246             }
247         }
248
249         if (!componentParametersView.isIgnoreArtifacts()) {
250             status = setArtifactsFromGraph(componentV, toscaElement);
251             if (status != JanusGraphOperationStatus.OK) {
252                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
253             }
254         }
255         if (!componentParametersView.isIgnoreAdditionalInformation()) {
256             status = setAdditionalInformationFromGraph(componentV, toscaElement);
257             if (status != JanusGraphOperationStatus.OK) {
258                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
259             }
260         }
261         if (!componentParametersView.isIgnoreInterfaces()) {
262             status = setInterfacesFromGraph(componentV, toscaElement);
263             if (status != JanusGraphOperationStatus.OK) {
264                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
265             }
266         }
267         if (!componentParametersView.isIgnoreAllVersions()) {
268             status = setAllVersions(componentV, toscaElement);
269             if (status != JanusGraphOperationStatus.OK && status != JanusGraphOperationStatus.NOT_FOUND) {
270                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
271             }
272         }
273
274         if (!componentParametersView.isIgnoreCapabiltyProperties()) {
275             status = setComponentCapPropertiesFromGraph(componentV, toscaElement);
276             if (status != JanusGraphOperationStatus.OK) {
277                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
278
279             }
280         }
281         return Either.left(toscaElement);
282     }
283
284     private JanusGraphOperationStatus setComponentCapPropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
285         Either<Map<String, MapPropertiesDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
286         if (result.isLeft()) {
287             toscaElement.setCapabilitiesProperties(result.left().value());
288         } else {
289             if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
290                 return result.right().value();
291             }
292         }
293         return JanusGraphOperationStatus.OK;
294     }
295
296     private JanusGraphOperationStatus setInterfacesFromGraph(GraphVertex componentV, NodeType toscaElement) {
297         Either<Map<String, InterfaceDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INTERFACE_ARTIFACTS);
298         if (result.isLeft()) {
299             toscaElement.setInterfaceArtifacts(result.left().value());
300         } else {
301             if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
302                 return result.right().value();
303             }
304         }
305         return JanusGraphOperationStatus.OK;
306     }
307
308     protected <T extends ToscaElement> JanusGraphOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement) {
309         return setResourceCapabilitiesFromGraph(componentV, (NodeType) toscaElement);
310     }
311
312     private JanusGraphOperationStatus setResourceCapabilitiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
313         Either<Map<String, ListCapabilityDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES);
314         if (result.isLeft()) {
315             toscaElement.setCapabilities(result.left().value());
316         } else {
317             if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
318                 return result.right().value();
319             }
320         }
321         return JanusGraphOperationStatus.OK;
322     }
323
324     private JanusGraphOperationStatus setResourceDerivedFromGraph(GraphVertex componentV, NodeType toscaElement) {
325         List<String> derivedFromList = new ArrayList<>();
326
327         JanusGraphOperationStatus
328             listFromGraphStatus = findResourcesPathRecursively(componentV, derivedFromList);
329         if (JanusGraphOperationStatus.OK != listFromGraphStatus) {
330             return listFromGraphStatus;
331         }
332
333         if (!derivedFromList.isEmpty()) {
334             if (derivedFromList.size() > 1) {
335                 List<String> lastDerivedFrom = new ArrayList<>();
336                 lastDerivedFrom.add(derivedFromList.get(1));
337                 toscaElement.setDerivedFrom(lastDerivedFrom);
338                 toscaElement.setDerivedList(derivedFromList);
339             } else {
340                 toscaElement.setDerivedFrom(null);
341                 toscaElement.setDerivedList(derivedFromList);
342             }
343
344         }
345         return JanusGraphOperationStatus.OK;
346     }
347
348     protected JanusGraphOperationStatus findResourcesPathRecursively(GraphVertex nodeTypeV, List<String> resourcesPathList) {
349         Either<GraphVertex, JanusGraphOperationStatus> parentResourceRes = janusGraphDao
350             .getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
351         resourcesPathList.add((String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
352         while (parentResourceRes.isLeft()) {
353
354             GraphVertex parent = parentResourceRes.left().value();
355             resourcesPathList.add((String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
356             parentResourceRes = janusGraphDao
357                 .getChildVertex(parent, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
358         }
359         JanusGraphOperationStatus operationStatus = parentResourceRes.right().value();
360
361         if (operationStatus != JanusGraphOperationStatus.NOT_FOUND) {
362             return operationStatus;
363         } else {
364             return JanusGraphOperationStatus.OK;
365         }
366
367     }
368
369     protected <T extends ToscaElement> JanusGraphOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement) {
370         return setResourceRequirementsFromGraph(componentV, (NodeType) toscaElement);
371     }
372
373     private JanusGraphOperationStatus setResourceRequirementsFromGraph(GraphVertex componentV, NodeType toscaElement) {
374         Either<Map<String, ListRequirementDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.REQUIREMENTS);
375         if (result.isLeft()) {
376             toscaElement.setRequirements(result.left().value());
377         } else {
378             if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
379                 return result.right().value();
380             }
381         }
382         return JanusGraphOperationStatus.OK;
383     }
384
385     private JanusGraphOperationStatus setResourceAttributesFromGraph(GraphVertex componentV, NodeType toscaElement) {
386         Either<Map<String, PropertyDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ATTRIBUTES);
387         if (result.isLeft()) {
388             toscaElement.setAttributes(result.left().value());
389         } else {
390             if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
391                 return result.right().value();
392             }
393         }
394         return JanusGraphOperationStatus.OK;
395     }
396
397     private JanusGraphOperationStatus setResourcePropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
398         Either<Map<String, PropertyDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.PROPERTIES);
399         if (result.isLeft()) {
400             toscaElement.setProperties(result.left().value());
401         } else {
402             if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
403                 return result.right().value();
404             }
405         }
406         return JanusGraphOperationStatus.OK;
407     }
408
409     private StorageOperationStatus assosiateToDerived(GraphVertex nodeTypeVertex, List<GraphVertex> derivedResources) {
410         for (GraphVertex derivedV : derivedResources) {
411             JanusGraphOperationStatus
412                 createEdge = janusGraphDao
413                 .createEdge(nodeTypeVertex, derivedV, EdgeLabelEnum.DERIVED_FROM, null);
414             if (createEdge != JanusGraphOperationStatus.OK) {
415                 log.trace("Failed to associate resource {} to derived with id {}", nodeTypeVertex.getUniqueId(), derivedV.getUniqueId());
416                 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdge);
417             }
418         }
419         return StorageOperationStatus.OK;
420     }
421
422     private StorageOperationStatus addAdditionalInformationToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
423         // Note : currently only one derived supported!!!!
424         Either<Map<String, AdditionalInfoParameterDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ADDITIONAL_INFORMATION);
425         if (dataFromDerived.isRight()) {
426             return dataFromDerived.right().value();
427         }
428         Map<String, AdditionalInfoParameterDataDefinition> addInformationAll = dataFromDerived.left().value();
429
430         Map<String, AdditionalInfoParameterDataDefinition> addInformation = nodeType.getAdditionalInformation();
431         if (addInformation != null) {
432             ToscaDataDefinition.mergeDataMaps(addInformationAll, addInformation);
433         }
434         if (!addInformationAll.isEmpty()) {
435             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, addInformationAll);
436             if (assosiateElementToData.isRight()) {
437                 return assosiateElementToData.right().value();
438             }
439         }
440         return StorageOperationStatus.OK;
441     }
442
443     private StorageOperationStatus associateCapabilitiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
444         // Note : currently only one derived supported!!!!
445         Either<Map<String, ListCapabilityDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES);
446         if (dataFromDerived.isRight()) {
447             return dataFromDerived.right().value();
448         }
449         Map<String, ListCapabilityDataDefinition> capabiltiesAll = dataFromDerived.left().value();
450
451         Map<String, ListCapabilityDataDefinition> capabilties = nodeType.getCapabilities();
452         if (capabilties != null) {
453             if (capabiltiesAll == null) {
454                 capabiltiesAll = new HashMap<>();
455             }
456             capabilties.values().forEach(l -> {
457                 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
458                     String uid = UniqueIdBuilder.buildCapabilityUid(nodeTypeVertex.getUniqueId(), p.getName());
459                     p.setUniqueId(uid);
460                 });
461             });
462
463             ToscaDataDefinition.mergeDataMaps(capabiltiesAll, capabilties);
464             capabiltiesAll.values().forEach(l -> {
465                 l.getListToscaDataDefinition().forEach(c -> {
466                     List<String> capabilitySources = c.getCapabilitySources();
467                     if (capabilitySources == null) {
468                         capabilitySources = new ArrayList<>();
469                     }
470                     capabilitySources.add((String) nodeType.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
471                     c.setCapabilitySources(capabilitySources);
472                 });
473             });
474         }
475         capabiltiesAll.values().forEach(l -> {
476             l.getListToscaDataDefinition().forEach(c -> {
477                 List<String> capabilitySources = c.getCapabilitySources();
478                 if (capabilitySources == null) {
479                     capabilitySources = new ArrayList<>();
480                 }
481                 capabilitySources.add((String) nodeType.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
482                 c.setCapabilitySources(capabilitySources);
483             });
484         });
485         if (!capabiltiesAll.isEmpty()) {
486             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES, EdgeLabelEnum.CAPABILITIES, capabiltiesAll);
487             if (assosiateElementToData.isRight()) {
488                 return assosiateElementToData.right().value();
489             }
490         }
491         return StorageOperationStatus.OK;
492     }
493
494     private StorageOperationStatus associateRequirementsToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
495         // Note : currently only one derived supported!!!!
496         Either<Map<String, ListRequirementDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.REQUIREMENTS);
497         if (dataFromDerived.isRight()) {
498             return dataFromDerived.right().value();
499         }
500         Map<String, ListRequirementDataDefinition> requirementsAll = dataFromDerived.left().value();
501
502         Map<String, ListRequirementDataDefinition> requirements = nodeType.getRequirements();
503         if (requirements != null) {
504             if (requirementsAll == null) {
505                 requirementsAll = new HashMap<>();
506             }
507             requirements.values().forEach(l -> {
508                 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
509                     String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
510                     p.setUniqueId(uid);
511                 });
512             });
513
514             ToscaDataDefinition.mergeDataMaps(requirementsAll, requirements);
515
516         }
517         if (!requirementsAll.isEmpty()) {
518             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.REQUIREMENTS, EdgeLabelEnum.REQUIREMENTS, requirementsAll);
519             if (assosiateElementToData.isRight()) {
520                 return assosiateElementToData.right().value();
521             }
522         }
523         return StorageOperationStatus.OK;
524     }
525
526     private StorageOperationStatus associateAttributesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
527         // Note : currently only one derived supported!!!!
528         Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ATTRIBUTES);
529         if (dataFromDerived.isRight()) {
530             return dataFromDerived.right().value();
531         }
532         Map<String, PropertyDataDefinition> attributesAll = dataFromDerived.left().value();
533
534         Map<String, PropertyDataDefinition> attributes = nodeType.getAttributes();
535         if (attributes != null) {
536             attributes.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
537                 String uid = UniqueIdBuilder.buildAttributeUid(nodeTypeVertex.getUniqueId(), p.getName());
538                 p.setUniqueId(uid);
539             });
540             ToscaDataDefinition.mergeDataMaps(attributesAll, attributes);
541         }
542         if (!attributesAll.isEmpty()) {
543             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.ATTRIBUTES, EdgeLabelEnum.ATTRIBUTES, attributesAll);
544             if (assosiateElementToData.isRight()) {
545                 return assosiateElementToData.right().value();
546             }
547         }
548         return StorageOperationStatus.OK;
549     }
550
551     // TODO get from derived
552     private StorageOperationStatus associateCapabilitiesPropertiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
553         // // Note : currently only one derived supported!!!!
554         Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
555         if (dataFromDerived.isRight()) {
556             return dataFromDerived.right().value();
557         }
558         Map<String, MapPropertiesDataDefinition> propertiesAll = dataFromDerived.left().value();
559         Map<String, MapPropertiesDataDefinition> capabiltiesProps = nodeType.getCapabilitiesProperties();
560         if (capabiltiesProps != null) {
561             capabiltiesProps.values().forEach(l -> {
562                 if (l.getMapToscaDataDefinition() != null && l.getMapToscaDataDefinition().values() != null) {
563                     Collection<PropertyDataDefinition> mapToscaDataDefinition = l.getMapToscaDataDefinition().values();
564                     mapToscaDataDefinition.stream().filter(p -> p != null && p.getUniqueId() == null).forEach(p -> {
565                         String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
566                         p.setUniqueId(uid);
567                     });
568                 }
569             });
570             ToscaDataDefinition.mergeDataMaps(propertiesAll, capabiltiesProps);
571         }
572         if (!propertiesAll.isEmpty()) {
573             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, propertiesAll);
574             if (assosiateElementToData.isRight()) {
575                 return assosiateElementToData.right().value();
576             }
577         }
578         return StorageOperationStatus.OK;
579     }
580
581     public Either<List<GraphVertex>, StorageOperationStatus> findDerivedResources(NodeType nodeType) {
582
583         List<GraphVertex> derivedResources = new ArrayList<>();
584         List<String> derivedFromResources = nodeType.getDerivedFrom();
585         if (derivedFromResources != null && !derivedFromResources.isEmpty()) {
586
587             for (String parentResource : derivedFromResources) {
588                 Either<List<GraphVertex>, JanusGraphOperationStatus> getParentResources = derivedResourceResolver.findDerivedResources(parentResource);
589                 List<GraphVertex> resources = null;
590                 if (getParentResources.isRight()) {
591                     log.error("Cannot find parent resource by tosca resource name {} in the graph.", parentResource);
592                     return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
593
594                 } else {
595                     resources = getParentResources.left().value();
596                     if (resources == null || resources.size() == 0) {
597                         log.error("Cannot find parent resource by tosca name {} in the graph. resources size is empty", parentResource);
598                         return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
599                     } else {
600                         if (resources.size() > 1) {
601                             return handleMultipleParent(parentResource, derivedResources, resources);
602                         } else {
603                             GraphVertex parentResourceData = resources.get(0);
604                             derivedResources.add(parentResourceData);
605                         }
606                     }
607
608                 }
609
610             }
611         }
612         return Either.left(derivedResources);
613     }
614
615     Either<List<GraphVertex>, StorageOperationStatus> handleMultipleParent(String parentResource, List<GraphVertex> derivedResource, List<GraphVertex> fetchedDerivedResources) {
616
617         Either<List<GraphVertex>, StorageOperationStatus> result = Either.left(derivedResource);
618         try {
619             fetchedDerivedResources.sort((d1, d2) -> {
620                 return new Double(Double.parseDouble((String) d1.getMetadataProperty(GraphPropertyEnum.VERSION))).compareTo(Double.parseDouble((String) d2.getMetadataProperty(GraphPropertyEnum.VERSION)));
621             });
622
623             int actualHighestIndex = fetchedDerivedResources.size() - 1;
624             derivedResource.add(fetchedDerivedResources.get(actualHighestIndex));
625             fetchedDerivedResources.remove(actualHighestIndex);
626
627             StorageOperationStatus status = fixMultipleParent(fetchedDerivedResources);
628             if (status != StorageOperationStatus.OK) {
629                 result = Either.right(status);
630             }
631         } catch (Exception e) {
632             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during handle multiple parent {}. Exception is  {}", parentResource, e.getMessage());
633             result = Either.right(StorageOperationStatus.GENERAL_ERROR);
634         }
635         return result;
636     }
637
638     private StorageOperationStatus fixMultipleParent(List<GraphVertex> fetchedDerivedResources) {
639         StorageOperationStatus result = StorageOperationStatus.OK;
640         for (GraphVertex fetchedDerivedResource : fetchedDerivedResources) {
641             fetchedDerivedResource.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
642             Either<GraphVertex, JanusGraphOperationStatus> updateVertexRes = janusGraphDao.updateVertex(fetchedDerivedResource);
643             if (updateVertexRes.isRight()) {
644                 JanusGraphOperationStatus titatStatus = updateVertexRes.right().value();
645                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set highest version of node type {} to false. Status is  {}", fetchedDerivedResource.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME), titatStatus);
646                 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(titatStatus);
647                 break;
648             }
649         }
650         return result;
651     }
652
653     private GraphVertex fillMetadata(GraphVertex nodeTypeVertex, NodeType nodeType) {
654         nodeTypeVertex.setLabel(VertexTypeEnum.NODE_TYPE);
655
656         fillCommonMetadata(nodeTypeVertex, nodeType);
657
658         return nodeTypeVertex;
659     }
660
661     @Override
662     public Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex) {
663         Either<ToscaElement, StorageOperationStatus> nodeType = getToscaElement(toscaElementVertex, new ComponentParametersView());
664         if (nodeType.isRight()) {
665             log.debug("Failed to fetch tosca element {} error {}", toscaElementVertex.getUniqueId(), nodeType.right().value());
666             return nodeType;
667         }
668         JanusGraphOperationStatus status = disassociateAndDeleteCommonElements(toscaElementVertex);
669         if (status != JanusGraphOperationStatus.OK) {
670             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
671         }
672         status = janusGraphDao
673             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
674         if (status != JanusGraphOperationStatus.OK) {
675             log.debug("Failed to disassociate capabilties for {} error {}", toscaElementVertex.getUniqueId(), status);
676             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
677         }
678         status = janusGraphDao
679             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
680         if (status != JanusGraphOperationStatus.OK) {
681             log.debug("Failed to disassociate capabilties properties for {} error {}", toscaElementVertex.getUniqueId(), status);
682             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
683         }
684         status = janusGraphDao
685             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
686         if (status != JanusGraphOperationStatus.OK) {
687             log.debug("Failed to disassociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
688             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
689         }
690         status = janusGraphDao
691             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
692         if (status != JanusGraphOperationStatus.OK) {
693             log.debug("Failed to disassociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
694             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
695         }
696         status = janusGraphDao
697             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INTERFACE_ARTIFACTS);
698         if (status != JanusGraphOperationStatus.OK) {
699             log.debug("Failed to disassociate interface artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
700             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
701         }
702         toscaElementVertex.getVertex().remove();
703         log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
704
705         return nodeType;
706     }
707
708     @SuppressWarnings("unchecked")
709     @Override
710     public Either<NodeType, StorageOperationStatus> createToscaElement(ToscaElement toscaElement) {
711         return createNodeType((NodeType) toscaElement);
712     }
713
714     @Override
715     protected <T extends ToscaElement> JanusGraphOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement) {
716         return setResourceCategoryFromGraph(vertexComponent, toscaElement);
717     }
718
719     @Override
720     protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV) {
721         return validateResourceCategory(toscaElementToUpdate, elementV);
722     }
723
724     @Override
725     protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV) {
726
727         NodeType nodeType = (NodeType) toscaElementToUpdate;
728
729         List<String> derivedFromResources = nodeType.getDerivedFrom();
730
731         // now supported only single derived from
732         if (derivedFromResources != null && !derivedFromResources.isEmpty() && derivedFromResources.get(0) != null) {
733             String firstDerived = derivedFromResources.get(0);
734             boolean derivedFromGenericType = null != nodeType.getDerivedFromGenericType();
735             Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
736                 .getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
737             if (childVertex.isRight()) {
738                 JanusGraphOperationStatus getchieldError = childVertex.right().value();
739                 log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchieldError);
740                 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getchieldError);
741             }
742             GraphVertex firstDerivedInChain = childVertex.left().value();
743
744             String firstCurrentDerived = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME);
745             if (!firstDerived.equals(firstCurrentDerived) || derivedFromGenericType) {
746
747                 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
748                 propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
749
750                 propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, firstDerived);
751                 propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
752
753                 Either<List<GraphVertex>, JanusGraphOperationStatus> getParentResources = janusGraphDao
754                     .getByCriteria(VertexTypeEnum.NODE_TYPE, propertiesToMatch, JsonParseFlagEnum.NoParse);
755
756                 if (getParentResources.isRight()) {
757                     JanusGraphOperationStatus error = getParentResources.right().value();
758                     CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch derived by criteria {}. error {} ", propertiesToMatch, error);
759                     return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
760                 }
761                 // must be only one
762                 GraphVertex newDerivedV = getParentResources.left().value().get(0);
763                 return updateDerived(toscaElementToUpdate, nodeTypeV, firstDerivedInChain, newDerivedV, false);
764             }
765         }
766         return StorageOperationStatus.OK;
767     }
768
769     /**
770      *
771      * @param toscaElementToUpdate
772      * @param nodeTypeV
773      * @param preDerivedV
774      * @param newDerivedV
775      * @param mergeValues
776      * @return
777      */
778     protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV, GraphVertex preDerivedV, GraphVertex newDerivedV, boolean mergeValues) {
779         Set<String> preDerivedChainIdList = new HashSet();
780         preDerivedChainIdList.add(preDerivedV.getUniqueId());
781         Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
782             .getChildVertex(preDerivedV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
783         while (childVertex.isLeft()) {
784             GraphVertex currentChield = childVertex.left().value();
785             preDerivedChainIdList.add(currentChield.getUniqueId());
786             childVertex = janusGraphDao
787                 .getChildVertex(currentChield, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
788         }
789
790         List<GraphVertex> derivedResources = new ArrayList<>();
791         derivedResources.add(newDerivedV);
792         StorageOperationStatus updateStatus = updateDataFromNewDerived(derivedResources, nodeTypeV, (NodeType) toscaElementToUpdate, mergeValues, preDerivedChainIdList);
793         if (updateStatus != StorageOperationStatus.OK) {
794             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update data for {} from new derived {} ", nodeTypeV.getUniqueId(), newDerivedV.getUniqueId(), updateStatus);
795             return updateStatus;
796         }
797
798         Either<Edge, JanusGraphOperationStatus> deleteEdge = janusGraphDao
799             .deleteEdge(nodeTypeV, preDerivedV, EdgeLabelEnum.DERIVED_FROM);
800         if (deleteEdge.isRight()) {
801             JanusGraphOperationStatus deleteError = deleteEdge.right().value();
802             log.debug("Failed to disassociate element {} from derived {} , error {}", nodeTypeV.getUniqueId(), preDerivedV.getUniqueId(), deleteError);
803             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteError);
804         }
805
806         janusGraphDao.createEdge(nodeTypeV, newDerivedV, EdgeLabelEnum.DERIVED_FROM, new HashMap<>());
807
808         return StorageOperationStatus.OK;
809     }
810
811     private StorageOperationStatus associateDerivedDataByType(EdgeLabelEnum edgeLabel, GraphVertex nodeTypeV, NodeType nodeToUpdate, List<GraphVertex> newDerived) {
812
813         switch (edgeLabel) {
814         case CAPABILITIES:
815             return associateCapabilitiesToResource(nodeTypeV, nodeToUpdate, newDerived);
816         case REQUIREMENTS:
817             return associateRequirementsToResource(nodeTypeV, nodeToUpdate, newDerived);
818         case PROPERTIES:
819             return associatePropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
820         case ATTRIBUTES:
821             return associateAttributesToResource(nodeTypeV, nodeToUpdate, newDerived);
822         case ADDITIONAL_INFORMATION:
823             return addAdditionalInformationToResource(nodeTypeV, nodeToUpdate, newDerived);
824         case CAPABILITIES_PROPERTIES:
825             return associateCapabilitiesPropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
826         default:
827             return StorageOperationStatus.OK;
828         }
829
830     }
831
832     private StorageOperationStatus updateDataFromNewDerived(List<GraphVertex> newDerived, GraphVertex nodeTypeV, NodeType nodeToUpdate, boolean mergeValues, Set<String> preDerivedChainIdList) {
833         EnumSet<EdgeLabelEnum> edgeLabels = EnumSet.of(EdgeLabelEnum.CAPABILITIES, EdgeLabelEnum.REQUIREMENTS, EdgeLabelEnum.PROPERTIES, EdgeLabelEnum.ATTRIBUTES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.ADDITIONAL_INFORMATION);
834         StorageOperationStatus status = null;
835         for (EdgeLabelEnum edge : edgeLabels) {
836             status = updateDataByType(newDerived, nodeTypeV, edge, nodeToUpdate, mergeValues, preDerivedChainIdList);
837             if (status != StorageOperationStatus.OK) {
838                 break;
839             }
840         }
841         return status;
842
843     }
844
845     private <T extends ToscaDataDefinition> StorageOperationStatus updateDataByType(List<GraphVertex> newDerivedList, GraphVertex nodeTypeV, EdgeLabelEnum label, NodeType nodeElement, boolean mergeValues, Set<String> preDerivedChainIdList) {
846         log.debug("Update data from derived for element {} type {}", nodeTypeV.getUniqueId(), label);
847         Either<GraphVertex, JanusGraphOperationStatus> dataFromGraph = getDataVertex(nodeTypeV, label);
848         if (dataFromGraph.isRight()) {
849             if (JanusGraphOperationStatus.NOT_FOUND == dataFromGraph.right().value())
850                 return associateDerivedDataByType(label, nodeTypeV, nodeElement, newDerivedList);
851             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(dataFromGraph.right().value());
852         }
853         GraphVertex dataV = dataFromGraph.left().value();
854
855         Map<String, T> mapFromGraph = (Map<String, T>) dataV.getJson();
856         Map<String, T> valuesFrmPrev = null;
857         if (isSimpleHierarchy(label)) {
858             if (mergeValues) {
859                 valuesFrmPrev = mapFromGraph.entrySet().stream().filter(e -> e.getValue().getOwnerId() != null).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
860             }
861             mapFromGraph.entrySet().removeIf(e -> preDerivedChainIdList.contains(e.getValue().getOwnerId()));
862         } else {
863             final Map<String, T> valuesFrmPrevFinal = new HashMap<>();
864             mapFromGraph.entrySet().stream().forEach(e -> {
865                 T value = e.getValue();
866                 value = ToscaDataDefinition.removeAndCollectByOwnerId(value, preDerivedChainIdList);
867                 valuesFrmPrevFinal.put(e.getKey(), value);
868             });
869             valuesFrmPrev = valuesFrmPrevFinal;
870             mapFromGraph.entrySet().removeIf(e->e.getValue().isEmpty());
871         }
872
873         Either<Map<String, T>, StorageOperationStatus> dataFromDerived = getDataFromDerived(newDerivedList, label);
874         if (dataFromDerived.isRight()) {
875             return dataFromDerived.right().value();
876         }
877         Map<String, T> dataFromDerivedAll = dataFromDerived.left().value();
878
879         Either<Map<String, T>, String> merged = ToscaDataDefinition.mergeDataMaps(dataFromDerivedAll, mapFromGraph);
880         if (merged.isRight()) {
881             log.debug("property {} cannot be overriden", merged.right().value());
882             return StorageOperationStatus.INVALID_PROPERTY;
883         }
884         if (mergeValues && valuesFrmPrev != null) {
885             valuesFrmPrev.entrySet().forEach(e -> {
886                 T newData = merged.left().value().get(e.getKey());
887                 if (newData != null) {
888                     if (isSimpleHierarchy(label)) {
889                         e.getValue().mergeFunction(newData, true);
890                     }else{
891                         e.getValue().updateIfExist(newData, true);
892                     }
893                 }
894             });
895         }
896         dataV.setJson(dataFromDerivedAll);
897         Either<GraphVertex, JanusGraphOperationStatus> updateDataV = updateOrCopyOnUpdate(dataV, nodeTypeV, label);
898         if (updateDataV.isRight()) {
899             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateDataV.right().value());
900         }
901         return StorageOperationStatus.OK;
902     }
903
904     private boolean isSimpleHierarchy(EdgeLabelEnum label) {
905         switch (label) {
906         case PROPERTIES:
907         case ATTRIBUTES:
908         case ADDITIONAL_INFORMATION:
909         case ARTIFACTS:
910         case GROUPS:
911         case INPUTS:
912             return true;
913         default:
914             return false;
915         }
916     }
917
918     @Override
919     public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag) {
920         fillMetadata(elementV, (NodeType) toscaElementToUpdate);
921     }
922
923     public Either<ToscaElement, StorageOperationStatus> shouldUpdateDerivedVersion(ToscaElement toscaElementToUpdate, GraphVertex nodeTypeV) {
924         NodeType nodeType = (NodeType) toscaElementToUpdate;
925
926         Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
927             .getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
928         if (childVertex.isRight()) {
929             JanusGraphOperationStatus getchildError = childVertex.right().value();
930             if (getchildError == JanusGraphOperationStatus.NOT_FOUND) {
931                 log.debug("derived resource for element {} not found", nodeTypeV.getUniqueId());
932                 return Either.right(StorageOperationStatus.OK);
933             }
934
935             log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchildError);
936             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getchildError));
937         }
938         GraphVertex firstDerivedInChain = childVertex.left().value();
939
940         String currentVersion = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.VERSION);
941
942         Map<GraphPropertyEnum, Object> props = new HashMap<>();
943         props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, nodeType.getDerivedFrom().get(0));
944         props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
945         props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
946
947         Map<GraphPropertyEnum, Object> propsHasNot = new HashMap<>();
948         propsHasNot.put(GraphPropertyEnum.IS_DELETED, true);
949         Either<List<GraphVertex>, JanusGraphOperationStatus> byCriteria = janusGraphDao
950             .getByCriteria(VertexTypeEnum.NODE_TYPE, props, propsHasNot, JsonParseFlagEnum.NoParse);
951         if (byCriteria.isRight()) {
952             log.debug("Failed to fetch derived by props {} error {}", props, byCriteria.right().value());
953             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(byCriteria.right().value()));
954         }
955         List<GraphVertex> lastDerived = byCriteria.left().value();
956         // now supported only one derived!!! Change in future!(Evg)
957         GraphVertex derivedFromHighest = lastDerived.get(0);
958         String highestVersion = (String) derivedFromHighest.getMetadataProperty(GraphPropertyEnum.VERSION);
959         if (!highestVersion.equals(currentVersion)) {
960
961             // need to update to latest version of derived from
962             StorageOperationStatus updateDerived = updateDerived(toscaElementToUpdate, nodeTypeV, firstDerivedInChain, derivedFromHighest, true);
963
964             if (updateDerived != StorageOperationStatus.OK) {
965                 log.debug("Failed to update {} to highest derived {} from error {}", nodeTypeV.getUniqueId(), derivedFromHighest.getUniqueId(), updateDerived);
966                 return Either.right(updateDerived);
967             }
968             return getToscaElement(nodeTypeV.getUniqueId(), new ComponentParametersView());
969         }
970         // no version changes
971         return Either.right(StorageOperationStatus.OK);
972     }
973
974 }