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