9a70e9c837e2ec7b60d02077be6e507bdd5b97c9
[sdc.git] /
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(final GraphVertex componentV,
325                                                                   final NodeType toscaElement) {
326         final List<String> derivedFromList = new ArrayList<>();
327         final Map<String, String> derivedFromMapOfIdToName = new LinkedHashMap<>();
328
329         final JanusGraphOperationStatus listFromGraphStatus = findResourcesPathRecursively(componentV, derivedFromList,
330             derivedFromMapOfIdToName);
331         if (JanusGraphOperationStatus.OK != listFromGraphStatus) {
332             return listFromGraphStatus;
333         }
334
335         if (!derivedFromList.isEmpty()) {
336             if (derivedFromList.size() > 1) {
337                 final List<String> lastDerivedFrom = new ArrayList<>();
338                 lastDerivedFrom.add(derivedFromList.get(1));
339                 toscaElement.setDerivedFrom(lastDerivedFrom);
340             } else {
341                 toscaElement.setDerivedFrom(null);
342             }
343             toscaElement.setDerivedList(derivedFromList);
344             toscaElement.setDerivedFromMapOfIdToName(derivedFromMapOfIdToName);
345         }
346         return JanusGraphOperationStatus.OK;
347     }
348
349     private JanusGraphOperationStatus findResourcesPathRecursively(final GraphVertex nodeTypeV,
350                                                                      final List<String> resourcesPathList,
351                                                                      final Map<String, String> derivedFromMapOfIdToName) {
352         Either<GraphVertex, JanusGraphOperationStatus> parentResourceRes = janusGraphDao
353             .getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
354         resourcesPathList.add((String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
355         derivedFromMapOfIdToName.put(nodeTypeV.getUniqueId(),
356             (String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
357         while (parentResourceRes.isLeft()) {
358             final GraphVertex parent = parentResourceRes.left().value();
359             resourcesPathList.add((String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
360             derivedFromMapOfIdToName
361                 .put(parent.getUniqueId(), (String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
362             parentResourceRes = janusGraphDao
363                 .getChildVertex(parent, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
364         }
365         final JanusGraphOperationStatus operationStatus = parentResourceRes.right().value();
366
367         if (operationStatus != JanusGraphOperationStatus.NOT_FOUND) {
368             return operationStatus;
369         } else {
370             return JanusGraphOperationStatus.OK;
371         }
372
373     }
374
375     protected <T extends ToscaElement> JanusGraphOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement) {
376         return setResourceRequirementsFromGraph(componentV, (NodeType) toscaElement);
377     }
378
379     private JanusGraphOperationStatus setResourceRequirementsFromGraph(GraphVertex componentV, NodeType toscaElement) {
380         Either<Map<String, ListRequirementDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.REQUIREMENTS);
381         if (result.isLeft()) {
382             toscaElement.setRequirements(result.left().value());
383         } else {
384             if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
385                 return result.right().value();
386             }
387         }
388         return JanusGraphOperationStatus.OK;
389     }
390
391     private JanusGraphOperationStatus setResourceAttributesFromGraph(GraphVertex componentV, NodeType toscaElement) {
392         Either<Map<String, PropertyDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ATTRIBUTES);
393         if (result.isLeft()) {
394             toscaElement.setAttributes(result.left().value());
395         } else {
396             if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
397                 return result.right().value();
398             }
399         }
400         return JanusGraphOperationStatus.OK;
401     }
402
403     private JanusGraphOperationStatus setResourcePropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
404         Either<Map<String, PropertyDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.PROPERTIES);
405         if (result.isLeft()) {
406             toscaElement.setProperties(result.left().value());
407         } else {
408             if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
409                 return result.right().value();
410             }
411         }
412         return JanusGraphOperationStatus.OK;
413     }
414
415     private StorageOperationStatus assosiateToDerived(GraphVertex nodeTypeVertex, List<GraphVertex> derivedResources) {
416         for (GraphVertex derivedV : derivedResources) {
417             JanusGraphOperationStatus
418                 createEdge = janusGraphDao
419                 .createEdge(nodeTypeVertex, derivedV, EdgeLabelEnum.DERIVED_FROM, null);
420             if (createEdge != JanusGraphOperationStatus.OK) {
421                 log.trace("Failed to associate resource {} to derived with id {}", nodeTypeVertex.getUniqueId(), derivedV.getUniqueId());
422                 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdge);
423             }
424         }
425         return StorageOperationStatus.OK;
426     }
427
428     private StorageOperationStatus addAdditionalInformationToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
429         // Note : currently only one derived supported!!!!
430         Either<Map<String, AdditionalInfoParameterDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ADDITIONAL_INFORMATION);
431         if (dataFromDerived.isRight()) {
432             return dataFromDerived.right().value();
433         }
434         Map<String, AdditionalInfoParameterDataDefinition> addInformationAll = dataFromDerived.left().value();
435
436         Map<String, AdditionalInfoParameterDataDefinition> addInformation = nodeType.getAdditionalInformation();
437         if (addInformation != null) {
438             ToscaDataDefinition.mergeDataMaps(addInformationAll, addInformation);
439         }
440         if (!addInformationAll.isEmpty()) {
441             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, addInformationAll);
442             if (assosiateElementToData.isRight()) {
443                 return assosiateElementToData.right().value();
444             }
445         }
446         return StorageOperationStatus.OK;
447     }
448
449     private StorageOperationStatus associateCapabilitiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
450         // Note : currently only one derived supported!!!!
451         Either<Map<String, ListCapabilityDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES);
452         if (dataFromDerived.isRight()) {
453             return dataFromDerived.right().value();
454         }
455         Map<String, ListCapabilityDataDefinition> capabiltiesAll = dataFromDerived.left().value();
456
457         Map<String, ListCapabilityDataDefinition> capabilties = nodeType.getCapabilities();
458         if (capabilties != null) {
459             if (capabiltiesAll == null) {
460                 capabiltiesAll = new HashMap<>();
461             }
462             capabilties.values().forEach(l -> {
463                 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
464                     String uid = UniqueIdBuilder.buildCapabilityUid(nodeTypeVertex.getUniqueId(), p.getName());
465                     p.setUniqueId(uid);
466                 });
467             });
468
469             ToscaDataDefinition.mergeDataMaps(capabiltiesAll, capabilties);
470             capabiltiesAll.values().forEach(l -> {
471                 l.getListToscaDataDefinition().forEach(c -> {
472                     List<String> capabilitySources = c.getCapabilitySources();
473                     if (capabilitySources == null) {
474                         capabilitySources = new ArrayList<>();
475                     }
476                     capabilitySources.add((String) nodeType.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
477                     c.setCapabilitySources(capabilitySources);
478                 });
479             });
480         }
481         capabiltiesAll.values().forEach(l -> {
482             l.getListToscaDataDefinition().forEach(c -> {
483                 List<String> capabilitySources = c.getCapabilitySources();
484                 if (capabilitySources == null) {
485                     capabilitySources = new ArrayList<>();
486                 }
487                 capabilitySources.add((String) nodeType.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
488                 c.setCapabilitySources(capabilitySources);
489             });
490         });
491         if (!capabiltiesAll.isEmpty()) {
492             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES, EdgeLabelEnum.CAPABILITIES, capabiltiesAll);
493             if (assosiateElementToData.isRight()) {
494                 return assosiateElementToData.right().value();
495             }
496         }
497         return StorageOperationStatus.OK;
498     }
499
500     private StorageOperationStatus associateRequirementsToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
501         // Note : currently only one derived supported!!!!
502         Either<Map<String, ListRequirementDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.REQUIREMENTS);
503         if (dataFromDerived.isRight()) {
504             return dataFromDerived.right().value();
505         }
506         Map<String, ListRequirementDataDefinition> requirementsAll = dataFromDerived.left().value();
507
508         Map<String, ListRequirementDataDefinition> requirements = nodeType.getRequirements();
509         if (requirements != null) {
510             if (requirementsAll == null) {
511                 requirementsAll = new HashMap<>();
512             }
513             requirements.values().forEach(l -> {
514                 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
515                     String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
516                     p.setUniqueId(uid);
517                 });
518             });
519
520             ToscaDataDefinition.mergeDataMaps(requirementsAll, requirements);
521
522         }
523         if (!requirementsAll.isEmpty()) {
524             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.REQUIREMENTS, EdgeLabelEnum.REQUIREMENTS, requirementsAll);
525             if (assosiateElementToData.isRight()) {
526                 return assosiateElementToData.right().value();
527             }
528         }
529         return StorageOperationStatus.OK;
530     }
531
532     private StorageOperationStatus associateAttributesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
533         // Note : currently only one derived supported!!!!
534         Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ATTRIBUTES);
535         if (dataFromDerived.isRight()) {
536             return dataFromDerived.right().value();
537         }
538         Map<String, PropertyDataDefinition> attributesAll = dataFromDerived.left().value();
539
540         Map<String, PropertyDataDefinition> attributes = nodeType.getAttributes();
541         if (attributes != null) {
542             attributes.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
543                 String uid = UniqueIdBuilder.buildAttributeUid(nodeTypeVertex.getUniqueId(), p.getName());
544                 p.setUniqueId(uid);
545             });
546             ToscaDataDefinition.mergeDataMaps(attributesAll, attributes);
547         }
548         if (!attributesAll.isEmpty()) {
549             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.ATTRIBUTES, EdgeLabelEnum.ATTRIBUTES, attributesAll);
550             if (assosiateElementToData.isRight()) {
551                 return assosiateElementToData.right().value();
552             }
553         }
554         return StorageOperationStatus.OK;
555     }
556
557     // TODO get from derived
558     private StorageOperationStatus associateCapabilitiesPropertiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
559         // // Note : currently only one derived supported!!!!
560         Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
561         if (dataFromDerived.isRight()) {
562             return dataFromDerived.right().value();
563         }
564         Map<String, MapPropertiesDataDefinition> propertiesAll = dataFromDerived.left().value();
565         Map<String, MapPropertiesDataDefinition> capabiltiesProps = nodeType.getCapabilitiesProperties();
566         if (capabiltiesProps != null) {
567             capabiltiesProps.values().forEach(l -> {
568                 if (l.getMapToscaDataDefinition() != null && l.getMapToscaDataDefinition().values() != null) {
569                     Collection<PropertyDataDefinition> mapToscaDataDefinition = l.getMapToscaDataDefinition().values();
570                     mapToscaDataDefinition.stream().filter(p -> p != null && p.getUniqueId() == null).forEach(p -> {
571                         String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
572                         p.setUniqueId(uid);
573                     });
574                 }
575             });
576             ToscaDataDefinition.mergeDataMaps(propertiesAll, capabiltiesProps);
577         }
578         if (!propertiesAll.isEmpty()) {
579             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, propertiesAll);
580             if (assosiateElementToData.isRight()) {
581                 return assosiateElementToData.right().value();
582             }
583         }
584         return StorageOperationStatus.OK;
585     }
586
587     public Either<List<GraphVertex>, StorageOperationStatus> findDerivedResources(NodeType nodeType) {
588
589         List<GraphVertex> derivedResources = new ArrayList<>();
590         List<String> derivedFromResources = nodeType.getDerivedFrom();
591         if (derivedFromResources != null && !derivedFromResources.isEmpty()) {
592
593             for (String parentResource : derivedFromResources) {
594                 Either<List<GraphVertex>, JanusGraphOperationStatus> getParentResources = derivedResourceResolver.findDerivedResources(parentResource);
595                 List<GraphVertex> resources = null;
596                 if (getParentResources.isRight()) {
597                     log.error("Cannot find parent resource by tosca resource name {} in the graph.", parentResource);
598                     return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
599
600                 } else {
601                     resources = getParentResources.left().value();
602                     if (resources == null || resources.size() == 0) {
603                         log.error("Cannot find parent resource by tosca name {} in the graph. resources size is empty", parentResource);
604                         return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
605                     } else {
606                         if (resources.size() > 1) {
607                             return handleMultipleParent(parentResource, derivedResources, resources);
608                         } else {
609                             GraphVertex parentResourceData = resources.get(0);
610                             derivedResources.add(parentResourceData);
611                         }
612                     }
613
614                 }
615
616             }
617         }
618         return Either.left(derivedResources);
619     }
620
621     Either<List<GraphVertex>, StorageOperationStatus> handleMultipleParent(String parentResource, List<GraphVertex> derivedResource, List<GraphVertex> fetchedDerivedResources) {
622
623         Either<List<GraphVertex>, StorageOperationStatus> result = Either.left(derivedResource);
624         try {
625             fetchedDerivedResources.sort((d1, d2) -> {
626                 return new Double(Double.parseDouble((String) d1.getMetadataProperty(GraphPropertyEnum.VERSION))).compareTo(Double.parseDouble((String) d2.getMetadataProperty(GraphPropertyEnum.VERSION)));
627             });
628
629             int actualHighestIndex = fetchedDerivedResources.size() - 1;
630             derivedResource.add(fetchedDerivedResources.get(actualHighestIndex));
631             fetchedDerivedResources.remove(actualHighestIndex);
632
633             StorageOperationStatus status = fixMultipleParent(fetchedDerivedResources);
634             if (status != StorageOperationStatus.OK) {
635                 result = Either.right(status);
636             }
637         } catch (Exception e) {
638             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during handle multiple parent {}. Exception is  {}", parentResource, e.getMessage());
639             result = Either.right(StorageOperationStatus.GENERAL_ERROR);
640         }
641         return result;
642     }
643
644     private StorageOperationStatus fixMultipleParent(List<GraphVertex> fetchedDerivedResources) {
645         StorageOperationStatus result = StorageOperationStatus.OK;
646         for (GraphVertex fetchedDerivedResource : fetchedDerivedResources) {
647             fetchedDerivedResource.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
648             Either<GraphVertex, JanusGraphOperationStatus> updateVertexRes = janusGraphDao.updateVertex(fetchedDerivedResource);
649             if (updateVertexRes.isRight()) {
650                 JanusGraphOperationStatus titatStatus = updateVertexRes.right().value();
651                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set highest version of node type {} to false. Status is  {}", fetchedDerivedResource.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME), titatStatus);
652                 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(titatStatus);
653                 break;
654             }
655         }
656         return result;
657     }
658
659     private GraphVertex fillMetadata(GraphVertex nodeTypeVertex, NodeType nodeType) {
660         nodeTypeVertex.setLabel(VertexTypeEnum.NODE_TYPE);
661
662         fillCommonMetadata(nodeTypeVertex, nodeType);
663
664         return nodeTypeVertex;
665     }
666
667     @Override
668     public Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex) {
669         Either<ToscaElement, StorageOperationStatus> nodeType = getToscaElement(toscaElementVertex, new ComponentParametersView());
670         if (nodeType.isRight()) {
671             log.debug("Failed to fetch tosca element {} error {}", toscaElementVertex.getUniqueId(), nodeType.right().value());
672             return nodeType;
673         }
674         JanusGraphOperationStatus status = disassociateAndDeleteCommonElements(toscaElementVertex);
675         if (status != JanusGraphOperationStatus.OK) {
676             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
677         }
678         status = janusGraphDao
679             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
680         if (status != JanusGraphOperationStatus.OK) {
681             log.debug("Failed to disassociate capabilties for {} error {}", toscaElementVertex.getUniqueId(), status);
682             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
683         }
684         status = janusGraphDao
685             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
686         if (status != JanusGraphOperationStatus.OK) {
687             log.debug("Failed to disassociate capabilties properties for {} error {}", toscaElementVertex.getUniqueId(), status);
688             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
689         }
690         status = janusGraphDao
691             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
692         if (status != JanusGraphOperationStatus.OK) {
693             log.debug("Failed to disassociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
694             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
695         }
696         status = janusGraphDao
697             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
698         if (status != JanusGraphOperationStatus.OK) {
699             log.debug("Failed to disassociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
700             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
701         }
702         status = janusGraphDao
703             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INTERFACE_ARTIFACTS);
704         if (status != JanusGraphOperationStatus.OK) {
705             log.debug("Failed to disassociate interface artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
706             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
707         }
708         toscaElementVertex.getVertex().remove();
709         log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
710
711         return nodeType;
712     }
713
714     @SuppressWarnings("unchecked")
715     @Override
716     public Either<NodeType, StorageOperationStatus> createToscaElement(ToscaElement toscaElement) {
717         return createNodeType((NodeType) toscaElement);
718     }
719
720     @Override
721     protected <T extends ToscaElement> JanusGraphOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement) {
722         return setResourceCategoryFromGraph(vertexComponent, toscaElement);
723     }
724
725     @Override
726     protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV) {
727         return validateResourceCategory(toscaElementToUpdate, elementV);
728     }
729
730     @Override
731     protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV) {
732
733         NodeType nodeType = (NodeType) toscaElementToUpdate;
734
735         List<String> derivedFromResources = nodeType.getDerivedFrom();
736
737         // now supported only single derived from
738         if (derivedFromResources != null && !derivedFromResources.isEmpty() && derivedFromResources.get(0) != null) {
739             String firstDerived = derivedFromResources.get(0);
740             boolean derivedFromGenericType = null != nodeType.getDerivedFromGenericType();
741             Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
742                 .getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
743             if (childVertex.isRight()) {
744                 JanusGraphOperationStatus getchieldError = childVertex.right().value();
745                 log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchieldError);
746                 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getchieldError);
747             }
748             GraphVertex firstDerivedInChain = childVertex.left().value();
749
750             String firstCurrentDerived = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME);
751             if (!firstDerived.equals(firstCurrentDerived) || derivedFromGenericType) {
752
753                 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
754                 propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
755
756                 propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, firstDerived);
757                 propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
758
759                 Either<List<GraphVertex>, JanusGraphOperationStatus> getParentResources = janusGraphDao
760                     .getByCriteria(VertexTypeEnum.NODE_TYPE, propertiesToMatch, JsonParseFlagEnum.NoParse);
761
762                 if (getParentResources.isRight()) {
763                     JanusGraphOperationStatus error = getParentResources.right().value();
764                     CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch derived by criteria {}. error {} ", propertiesToMatch, error);
765                     return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
766                 }
767                 // must be only one
768                 GraphVertex newDerivedV = getParentResources.left().value().get(0);
769                 return updateDerived(toscaElementToUpdate, nodeTypeV, firstDerivedInChain, newDerivedV, false);
770             }
771         }
772         return StorageOperationStatus.OK;
773     }
774
775     /**
776      *
777      * @param toscaElementToUpdate
778      * @param nodeTypeV
779      * @param preDerivedV
780      * @param newDerivedV
781      * @param mergeValues
782      * @return
783      */
784     protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV, GraphVertex preDerivedV, GraphVertex newDerivedV, boolean mergeValues) {
785         Set<String> preDerivedChainIdList = new HashSet();
786         preDerivedChainIdList.add(preDerivedV.getUniqueId());
787         Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
788             .getChildVertex(preDerivedV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
789         while (childVertex.isLeft()) {
790             GraphVertex currentChield = childVertex.left().value();
791             preDerivedChainIdList.add(currentChield.getUniqueId());
792             childVertex = janusGraphDao
793                 .getChildVertex(currentChield, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
794         }
795
796         List<GraphVertex> derivedResources = new ArrayList<>();
797         derivedResources.add(newDerivedV);
798         StorageOperationStatus updateStatus = updateDataFromNewDerived(derivedResources, nodeTypeV, (NodeType) toscaElementToUpdate, mergeValues, preDerivedChainIdList);
799         if (updateStatus != StorageOperationStatus.OK) {
800             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update data for {} from new derived {} ", nodeTypeV.getUniqueId(), newDerivedV.getUniqueId(), updateStatus);
801             return updateStatus;
802         }
803
804         Either<Edge, JanusGraphOperationStatus> deleteEdge = janusGraphDao
805             .deleteEdge(nodeTypeV, preDerivedV, EdgeLabelEnum.DERIVED_FROM);
806         if (deleteEdge.isRight()) {
807             JanusGraphOperationStatus deleteError = deleteEdge.right().value();
808             log.debug("Failed to disassociate element {} from derived {} , error {}", nodeTypeV.getUniqueId(), preDerivedV.getUniqueId(), deleteError);
809             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteError);
810         }
811
812         janusGraphDao.createEdge(nodeTypeV, newDerivedV, EdgeLabelEnum.DERIVED_FROM, new HashMap<>());
813
814         return StorageOperationStatus.OK;
815     }
816
817     private StorageOperationStatus associateDerivedDataByType(EdgeLabelEnum edgeLabel, GraphVertex nodeTypeV, NodeType nodeToUpdate, List<GraphVertex> newDerived) {
818
819         switch (edgeLabel) {
820         case CAPABILITIES:
821             return associateCapabilitiesToResource(nodeTypeV, nodeToUpdate, newDerived);
822         case REQUIREMENTS:
823             return associateRequirementsToResource(nodeTypeV, nodeToUpdate, newDerived);
824         case PROPERTIES:
825             return associatePropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
826         case ATTRIBUTES:
827             return associateAttributesToResource(nodeTypeV, nodeToUpdate, newDerived);
828         case ADDITIONAL_INFORMATION:
829             return addAdditionalInformationToResource(nodeTypeV, nodeToUpdate, newDerived);
830         case CAPABILITIES_PROPERTIES:
831             return associateCapabilitiesPropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
832         default:
833             return StorageOperationStatus.OK;
834         }
835
836     }
837
838     private StorageOperationStatus updateDataFromNewDerived(List<GraphVertex> newDerived, GraphVertex nodeTypeV, NodeType nodeToUpdate, boolean mergeValues, Set<String> preDerivedChainIdList) {
839         EnumSet<EdgeLabelEnum> edgeLabels = EnumSet.of(EdgeLabelEnum.CAPABILITIES, EdgeLabelEnum.REQUIREMENTS, EdgeLabelEnum.PROPERTIES, EdgeLabelEnum.ATTRIBUTES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.ADDITIONAL_INFORMATION);
840         StorageOperationStatus status = null;
841         for (EdgeLabelEnum edge : edgeLabels) {
842             status = updateDataByType(newDerived, nodeTypeV, edge, nodeToUpdate, mergeValues, preDerivedChainIdList);
843             if (status != StorageOperationStatus.OK) {
844                 break;
845             }
846         }
847         return status;
848
849     }
850
851     private <T extends ToscaDataDefinition> StorageOperationStatus updateDataByType(List<GraphVertex> newDerivedList, GraphVertex nodeTypeV, EdgeLabelEnum label, NodeType nodeElement, boolean mergeValues, Set<String> preDerivedChainIdList) {
852         log.debug("Update data from derived for element {} type {}", nodeTypeV.getUniqueId(), label);
853         Either<GraphVertex, JanusGraphOperationStatus> dataFromGraph = getDataVertex(nodeTypeV, label);
854         if (dataFromGraph.isRight()) {
855             if (JanusGraphOperationStatus.NOT_FOUND == dataFromGraph.right().value())
856                 return associateDerivedDataByType(label, nodeTypeV, nodeElement, newDerivedList);
857             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(dataFromGraph.right().value());
858         }
859         GraphVertex dataV = dataFromGraph.left().value();
860
861         Map<String, T> mapFromGraph = (Map<String, T>) dataV.getJson();
862         Map<String, T> valuesFrmPrev = null;
863         if (isSimpleHierarchy(label)) {
864             if (mergeValues) {
865                 valuesFrmPrev = mapFromGraph.entrySet().stream().filter(e -> e.getValue().getOwnerId() != null).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
866             }
867             mapFromGraph.entrySet().removeIf(e -> preDerivedChainIdList.contains(e.getValue().getOwnerId()));
868         } else {
869             final Map<String, T> valuesFrmPrevFinal = new HashMap<>();
870             mapFromGraph.entrySet().stream().forEach(e -> {
871                 T value = e.getValue();
872                 value = ToscaDataDefinition.removeAndCollectByOwnerId(value, preDerivedChainIdList);
873                 valuesFrmPrevFinal.put(e.getKey(), value);
874             });
875             valuesFrmPrev = valuesFrmPrevFinal;
876             mapFromGraph.entrySet().removeIf(e->e.getValue().isEmpty());
877         }
878
879         Either<Map<String, T>, StorageOperationStatus> dataFromDerived = getDataFromDerived(newDerivedList, label);
880         if (dataFromDerived.isRight()) {
881             return dataFromDerived.right().value();
882         }
883         Map<String, T> dataFromDerivedAll = dataFromDerived.left().value();
884
885         Either<Map<String, T>, String> merged = ToscaDataDefinition.mergeDataMaps(dataFromDerivedAll, mapFromGraph);
886         if (merged.isRight()) {
887             log.debug("property {} cannot be overriden", merged.right().value());
888             return StorageOperationStatus.INVALID_PROPERTY;
889         }
890         if (mergeValues && valuesFrmPrev != null) {
891             valuesFrmPrev.entrySet().forEach(e -> {
892                 T newData = merged.left().value().get(e.getKey());
893                 if (newData != null) {
894                     if (isSimpleHierarchy(label)) {
895                         e.getValue().mergeFunction(newData, true);
896                     }else{
897                         e.getValue().updateIfExist(newData, true);
898                     }
899                 }
900             });
901         }
902         dataV.setJson(dataFromDerivedAll);
903         Either<GraphVertex, JanusGraphOperationStatus> updateDataV = updateOrCopyOnUpdate(dataV, nodeTypeV, label);
904         if (updateDataV.isRight()) {
905             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateDataV.right().value());
906         }
907         return StorageOperationStatus.OK;
908     }
909
910     private boolean isSimpleHierarchy(EdgeLabelEnum label) {
911         switch (label) {
912         case PROPERTIES:
913         case ATTRIBUTES:
914         case ADDITIONAL_INFORMATION:
915         case ARTIFACTS:
916         case GROUPS:
917         case INPUTS:
918             return true;
919         default:
920             return false;
921         }
922     }
923
924     @Override
925     public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag) {
926         fillMetadata(elementV, (NodeType) toscaElementToUpdate);
927     }
928
929     public Either<ToscaElement, StorageOperationStatus> shouldUpdateDerivedVersion(ToscaElement toscaElementToUpdate, GraphVertex nodeTypeV) {
930         NodeType nodeType = (NodeType) toscaElementToUpdate;
931
932         Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
933             .getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
934         if (childVertex.isRight()) {
935             JanusGraphOperationStatus getchildError = childVertex.right().value();
936             if (getchildError == JanusGraphOperationStatus.NOT_FOUND) {
937                 log.debug("derived resource for element {} not found", nodeTypeV.getUniqueId());
938                 return Either.right(StorageOperationStatus.OK);
939             }
940
941             log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchildError);
942             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getchildError));
943         }
944         GraphVertex firstDerivedInChain = childVertex.left().value();
945
946         String currentVersion = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.VERSION);
947
948         Map<GraphPropertyEnum, Object> props = new HashMap<>();
949         props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, nodeType.getDerivedFrom().get(0));
950         props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
951         props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
952
953         Map<GraphPropertyEnum, Object> propsHasNot = new HashMap<>();
954         propsHasNot.put(GraphPropertyEnum.IS_DELETED, true);
955         Either<List<GraphVertex>, JanusGraphOperationStatus> byCriteria = janusGraphDao
956             .getByCriteria(VertexTypeEnum.NODE_TYPE, props, propsHasNot, JsonParseFlagEnum.NoParse);
957         if (byCriteria.isRight()) {
958             log.debug("Failed to fetch derived by props {} error {}", props, byCriteria.right().value());
959             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(byCriteria.right().value()));
960         }
961         List<GraphVertex> lastDerived = byCriteria.left().value();
962         // now supported only one derived!!! Change in future!(Evg)
963         GraphVertex derivedFromHighest = lastDerived.get(0);
964         String highestVersion = (String) derivedFromHighest.getMetadataProperty(GraphPropertyEnum.VERSION);
965         if (!highestVersion.equals(currentVersion)) {
966
967             // need to update to latest version of derived from
968             StorageOperationStatus updateDerived = updateDerived(toscaElementToUpdate, nodeTypeV, firstDerivedInChain, derivedFromHighest, true);
969
970             if (updateDerived != StorageOperationStatus.OK) {
971                 log.debug("Failed to update {} to highest derived {} from error {}", nodeTypeV.getUniqueId(), derivedFromHighest.getUniqueId(), updateDerived);
972                 return Either.right(updateDerived);
973             }
974             return getToscaElement(nodeTypeV.getUniqueId(), new ComponentParametersView());
975         }
976         // no version changes
977         return Either.right(StorageOperationStatus.OK);
978     }
979
980 }