Support for defining attributes on a node_type
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsonjanusgraph / operations / NodeTypeOperation.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
22
23 import fj.data.Either;
24 import org.apache.tinkerpop.gremlin.structure.Direction;
25 import org.apache.tinkerpop.gremlin.structure.Edge;
26 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
27 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
28 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
29 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
30 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
31 import org.openecomp.sdc.be.datatypes.elements.*;
32 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
33 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
34 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
35 import org.openecomp.sdc.be.model.ComponentParametersView;
36 import org.openecomp.sdc.be.model.DerivedNodeTypeResolver;
37 import org.openecomp.sdc.be.model.LifecycleStateEnum;
38 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.NodeType;
39 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement;
40 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElementTypeEnum;
41 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
42 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
43 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
44 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
45 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
46 import org.openecomp.sdc.common.log.wrappers.Logger;
47 import org.springframework.beans.factory.annotation.Qualifier;
48
49 import java.util.*;
50 import java.util.regex.Pattern;
51 import java.util.stream.Collectors;
52
53 @org.springframework.stereotype.Component("node-type-operation")
54 public class NodeTypeOperation extends ToscaElementOperation {
55     public static final Pattern uuidNewVersion = Pattern.compile("^\\d+.1");
56     public static final Pattern uuidNormativeNewVersion = Pattern.compile("^\\d+.0");
57     private static final Logger log = Logger.getLogger(NodeTypeOperation.class);
58     private DerivedNodeTypeResolver derivedResourceResolver;
59
60     
61     public NodeTypeOperation(@Qualifier("derived-resource-resolver") DerivedNodeTypeResolver derivedNodeTypeResolver) {
62         this.derivedResourceResolver = derivedNodeTypeResolver;
63     }
64
65     public Either<NodeType, StorageOperationStatus> createNodeType(NodeType nodeType) {
66
67         Either<NodeType, StorageOperationStatus> result = null;
68
69         nodeType.generateUUID();
70
71         nodeType = getResourceMetaDataFromResource(nodeType);
72         String resourceUniqueId = nodeType.getUniqueId();
73         if (resourceUniqueId == null) {
74             resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId();
75             nodeType.setUniqueId(resourceUniqueId);
76         }
77
78         // get derived from resources
79         List<GraphVertex> derivedResources = null;
80         Either<List<GraphVertex>, StorageOperationStatus> derivedResourcesResult = findDerivedResources(nodeType);
81         if (derivedResourcesResult.isRight()) {
82             result = Either.right(derivedResourcesResult.right().value());
83             return result;
84         } else {
85             derivedResources = derivedResourcesResult.left().value();
86         }
87
88         GraphVertex nodeTypeVertex = new GraphVertex(VertexTypeEnum.NODE_TYPE);
89         fillToscaElementVertexData(nodeTypeVertex, nodeType, JsonParseFlagEnum.ParseAll);
90
91         Either<GraphVertex, JanusGraphOperationStatus> createdVertex = janusGraphDao.createVertex(nodeTypeVertex);
92         if (createdVertex.isRight()) {
93             JanusGraphOperationStatus status = createdVertex.right().value();
94             log.error("Error returned after creating resource data node {}. status returned is ", nodeTypeVertex, status);
95             result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
96             return result;
97         }
98         nodeTypeVertex = createdVertex.left().value();
99
100         StorageOperationStatus assosiateCommon = assosiateCommonForToscaElement(nodeTypeVertex, nodeType, derivedResources);
101         if (assosiateCommon != StorageOperationStatus.OK) {
102             result = Either.right(assosiateCommon);
103             return result;
104         }
105
106         StorageOperationStatus associateDerived = assosiateToDerived(nodeTypeVertex, derivedResources);
107         if (associateDerived != StorageOperationStatus.OK) {
108             result = Either.right(associateDerived);
109             return result;
110         }
111         StorageOperationStatus associateCategory = assosiateResourceMetadataToCategory(nodeTypeVertex, nodeType);
112         if (associateCategory != StorageOperationStatus.OK) {
113             result = Either.right(associateCategory);
114             return result;
115         }
116
117         StorageOperationStatus associateAttributes = associateAttributesToResource(nodeTypeVertex, nodeType, derivedResources);
118         if (associateAttributes != StorageOperationStatus.OK) {
119             result = Either.right(associateAttributes);
120             return result;
121         }
122
123         StorageOperationStatus associateRequirements = associateRequirementsToResource(nodeTypeVertex, nodeType, derivedResources);
124         if (associateRequirements != StorageOperationStatus.OK) {
125             result = Either.right(associateRequirements);
126             return result;
127         }
128
129         StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(nodeTypeVertex, nodeType, derivedResources);
130         if (associateCapabilities != StorageOperationStatus.OK) {
131             result = Either.right(associateCapabilities);
132             return result;
133         }
134         StorageOperationStatus associateCapabilitiesProps = associateCapabilitiesPropertiesToResource(nodeTypeVertex, nodeType, derivedResources);
135         if (associateCapabilitiesProps != StorageOperationStatus.OK) {
136             result = Either.right(associateCapabilitiesProps);
137             return result;
138         }
139
140         StorageOperationStatus associateInterfaces = associateInterfacesToResource(nodeTypeVertex, nodeType, derivedResources);
141         if (associateInterfaces != StorageOperationStatus.OK) {
142             result = Either.right(associateInterfaces);
143             return result;
144         }
145
146         StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(nodeTypeVertex, nodeType, derivedResources);
147         if (addAdditionalInformation != StorageOperationStatus.OK) {
148             result = Either.right(addAdditionalInformation);
149             return result;
150         }
151         result = Either.left(nodeType);
152         return result;
153
154     }
155
156     private StorageOperationStatus associateInterfacesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
157         // Note : currently only one derived supported!!!!
158         Either<Map<String, InterfaceDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.INTERFACE_ARTIFACTS);
159         if (dataFromDerived.isRight()) {
160             return dataFromDerived.right().value();
161         }
162         Map<String, InterfaceDataDefinition> interfacArtsAll = dataFromDerived.left().value();
163
164         Map<String, InterfaceDataDefinition> interfacArts = nodeType.getInterfaceArtifacts();
165         if (interfacArts != null) {
166             interfacArtsAll.putAll(interfacArts);
167         }
168         if (!interfacArtsAll.isEmpty()) {
169             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.INTERFACE_ARTIFACTS, EdgeLabelEnum.INTERFACE_ARTIFACTS, interfacArtsAll);
170             if (assosiateElementToData.isRight()) {
171                 return assosiateElementToData.right().value();
172             }
173         }
174         return StorageOperationStatus.OK;
175     }
176
177     @Override
178     public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView) {
179
180         Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(uniqueId, ToscaElementTypeEnum.NODE_TYPE, JsonParseFlagEnum.ParseMetadata);
181         if (componentByLabelAndId.isRight()) {
182             return Either.right(componentByLabelAndId.right().value());
183         }
184         GraphVertex componentV = componentByLabelAndId.left().value();
185
186         return getToscaElement(componentV, componentParametersView);
187
188     }
189
190     // -------------------------------------------------------------
191     @Override
192     public Either<ToscaElement, StorageOperationStatus> getToscaElement(GraphVertex componentV, ComponentParametersView componentParametersView) {
193         NodeType toscaElement;
194         toscaElement = convertToComponent(componentV);
195         JanusGraphOperationStatus status = null;
196         if (!componentParametersView.isIgnoreUsers()) {
197             status = setCreatorFromGraph(componentV, toscaElement);
198             if (status != JanusGraphOperationStatus.OK) {
199                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
200             }
201
202             status = setLastModifierFromGraph(componentV, toscaElement);
203             if (status != JanusGraphOperationStatus.OK) {
204                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
205             }
206         }
207
208         if (!componentParametersView.isIgnoreProperties()) {
209             status = setResourcePropertiesFromGraph(componentV, toscaElement);
210             if (status != JanusGraphOperationStatus.OK && status != JanusGraphOperationStatus.NOT_FOUND) {
211                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
212             }
213         }
214
215         if (!componentParametersView.isIgnoreAttributesFrom()) {
216             status = setResourceAttributesFromGraph(componentV, toscaElement);
217             if (status != JanusGraphOperationStatus.OK) {
218                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
219             }
220         }
221
222         if (!componentParametersView.isIgnoreDerivedFrom()) {
223             status = setResourceDerivedFromGraph(componentV, toscaElement);
224             if (status != JanusGraphOperationStatus.OK) {
225                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
226             }
227         }
228
229         if (!componentParametersView.isIgnoreCategories()) {
230             status = setResourceCategoryFromGraph(componentV, toscaElement);
231             if (status != JanusGraphOperationStatus.OK) {
232                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
233             }
234         }
235         if (!componentParametersView.isIgnoreRequirements()) {
236             status = setResourceRequirementsFromGraph(componentV, toscaElement);
237             if (status != JanusGraphOperationStatus.OK) {
238                 log.error("Failed to set requirement of resource {}. status is {}", componentV.getUniqueId(), status);
239                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
240             }
241         }
242         if (!componentParametersView.isIgnoreCapabilities()) {
243             status = setResourceCapabilitiesFromGraph(componentV, toscaElement);
244             if (status != JanusGraphOperationStatus.OK) {
245                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
246             }
247         }
248
249         if (!componentParametersView.isIgnoreArtifacts()) {
250             status = setArtifactsFromGraph(componentV, toscaElement);
251             if (status != JanusGraphOperationStatus.OK) {
252                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
253             }
254         }
255         if (!componentParametersView.isIgnoreAdditionalInformation()) {
256             status = setAdditionalInformationFromGraph(componentV, toscaElement);
257             if (status != JanusGraphOperationStatus.OK) {
258                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
259             }
260         }
261         if (!componentParametersView.isIgnoreInterfaces()) {
262             status = setInterfacesFromGraph(componentV, toscaElement);
263             if (status != JanusGraphOperationStatus.OK) {
264                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
265             }
266         }
267         if (!componentParametersView.isIgnoreAllVersions()) {
268             status = setAllVersions(componentV, toscaElement);
269             if (status != JanusGraphOperationStatus.OK && status != JanusGraphOperationStatus.NOT_FOUND) {
270                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
271             }
272         }
273
274         if (!componentParametersView.isIgnoreCapabiltyProperties()) {
275             status = setComponentCapPropertiesFromGraph(componentV, toscaElement);
276             if (status != JanusGraphOperationStatus.OK) {
277                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
278
279             }
280         }
281         return Either.left(toscaElement);
282     }
283
284     private JanusGraphOperationStatus setComponentCapPropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
285         Either<Map<String, MapPropertiesDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
286         if (result.isLeft()) {
287             toscaElement.setCapabilitiesProperties(result.left().value());
288         } else {
289             if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
290                 return result.right().value();
291             }
292         }
293         return JanusGraphOperationStatus.OK;
294     }
295
296     private JanusGraphOperationStatus setInterfacesFromGraph(GraphVertex componentV, NodeType toscaElement) {
297         Either<Map<String, InterfaceDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INTERFACE_ARTIFACTS);
298         if (result.isLeft()) {
299             toscaElement.setInterfaceArtifacts(result.left().value());
300         } else {
301             if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
302                 return result.right().value();
303             }
304         }
305         return JanusGraphOperationStatus.OK;
306     }
307
308     protected <T extends ToscaElement> JanusGraphOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement) {
309         return setResourceCapabilitiesFromGraph(componentV, (NodeType) toscaElement);
310     }
311
312     private JanusGraphOperationStatus setResourceCapabilitiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
313         Either<Map<String, ListCapabilityDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES);
314         if (result.isLeft()) {
315             toscaElement.setCapabilities(result.left().value());
316         } else {
317             if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
318                 return result.right().value();
319             }
320         }
321         return JanusGraphOperationStatus.OK;
322     }
323
324     private JanusGraphOperationStatus setResourceDerivedFromGraph(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, AttributeDataDefinition>, 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, AttributeDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ATTRIBUTES);
535         if (dataFromDerived.isRight()) {
536             return dataFromDerived.right().value();
537         }
538         Map<String, AttributeDataDefinition> attributesAll = dataFromDerived.left().value();
539
540         Map<String, AttributeDataDefinition> 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         nodeTypeVertex.setJsonMetadataField(JsonPresentationFields.ATTRIBUTES, nodeType.getAttributes());
664
665         return nodeTypeVertex;
666     }
667
668     @Override
669     public Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex) {
670         Either<ToscaElement, StorageOperationStatus> nodeType = getToscaElement(toscaElementVertex, new ComponentParametersView());
671         if (nodeType.isRight()) {
672             log.debug("Failed to fetch tosca element {} error {}", toscaElementVertex.getUniqueId(), nodeType.right().value());
673             return nodeType;
674         }
675         JanusGraphOperationStatus status = disassociateAndDeleteCommonElements(toscaElementVertex);
676         if (status != JanusGraphOperationStatus.OK) {
677             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
678         }
679         status = janusGraphDao
680             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
681         if (status != JanusGraphOperationStatus.OK) {
682             log.debug("Failed to disassociate capabilties for {} error {}", toscaElementVertex.getUniqueId(), status);
683             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
684         }
685         status = janusGraphDao
686             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
687         if (status != JanusGraphOperationStatus.OK) {
688             log.debug("Failed to disassociate capabilties properties for {} error {}", toscaElementVertex.getUniqueId(), status);
689             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
690         }
691         status = janusGraphDao
692             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
693         if (status != JanusGraphOperationStatus.OK) {
694             log.debug("Failed to disassociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
695             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
696         }
697         status = janusGraphDao
698             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
699         if (status != JanusGraphOperationStatus.OK) {
700             log.debug("Failed to disassociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
701             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
702         }
703         status = janusGraphDao
704             .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INTERFACE_ARTIFACTS);
705         if (status != JanusGraphOperationStatus.OK) {
706             log.debug("Failed to disassociate interface artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
707             Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
708         }
709         toscaElementVertex.getVertex().remove();
710         log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
711
712         return nodeType;
713     }
714
715     @SuppressWarnings("unchecked")
716     @Override
717     public Either<NodeType, StorageOperationStatus> createToscaElement(ToscaElement toscaElement) {
718         return createNodeType((NodeType) toscaElement);
719     }
720
721     @Override
722     protected <T extends ToscaElement> JanusGraphOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement) {
723         return setResourceCategoryFromGraph(vertexComponent, toscaElement);
724     }
725
726     @Override
727     protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV) {
728         return validateResourceCategory(toscaElementToUpdate, elementV);
729     }
730
731     @Override
732     protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV) {
733
734         NodeType nodeType = (NodeType) toscaElementToUpdate;
735
736         List<String> derivedFromResources = nodeType.getDerivedFrom();
737
738         // now supported only single derived from
739         if (derivedFromResources != null && !derivedFromResources.isEmpty() && derivedFromResources.get(0) != null) {
740             String firstDerived = derivedFromResources.get(0);
741             boolean derivedFromGenericType = null != nodeType.getDerivedFromGenericType();
742             Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
743                 .getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
744             if (childVertex.isRight()) {
745                 JanusGraphOperationStatus getchieldError = childVertex.right().value();
746                 log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchieldError);
747                 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getchieldError);
748             }
749             GraphVertex firstDerivedInChain = childVertex.left().value();
750
751             String firstCurrentDerived = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME);
752             if (!firstDerived.equals(firstCurrentDerived) || derivedFromGenericType) {
753
754                 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
755                 propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
756
757                 propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, firstDerived);
758                 propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
759
760                 Either<List<GraphVertex>, JanusGraphOperationStatus> getParentResources = janusGraphDao
761                     .getByCriteria(VertexTypeEnum.NODE_TYPE, propertiesToMatch, JsonParseFlagEnum.NoParse);
762
763                 if (getParentResources.isRight()) {
764                     JanusGraphOperationStatus error = getParentResources.right().value();
765                     CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch derived by criteria {}. error {} ", propertiesToMatch, error);
766                     return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
767                 }
768                 // must be only one
769                 GraphVertex newDerivedV = getParentResources.left().value().get(0);
770                 return updateDerived(toscaElementToUpdate, nodeTypeV, firstDerivedInChain, newDerivedV, false);
771             }
772         }
773         return StorageOperationStatus.OK;
774     }
775
776     /**
777      *
778      * @param toscaElementToUpdate
779      * @param nodeTypeV
780      * @param preDerivedV
781      * @param newDerivedV
782      * @param mergeValues
783      * @return
784      */
785     protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV, GraphVertex preDerivedV, GraphVertex newDerivedV, boolean mergeValues) {
786         Set<String> preDerivedChainIdList = new HashSet();
787         preDerivedChainIdList.add(preDerivedV.getUniqueId());
788         Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
789             .getChildVertex(preDerivedV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
790         while (childVertex.isLeft()) {
791             GraphVertex currentChield = childVertex.left().value();
792             preDerivedChainIdList.add(currentChield.getUniqueId());
793             childVertex = janusGraphDao
794                 .getChildVertex(currentChield, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
795         }
796
797         List<GraphVertex> derivedResources = new ArrayList<>();
798         derivedResources.add(newDerivedV);
799         StorageOperationStatus updateStatus = updateDataFromNewDerived(derivedResources, nodeTypeV, (NodeType) toscaElementToUpdate, mergeValues, preDerivedChainIdList);
800         if (updateStatus != StorageOperationStatus.OK) {
801             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update data for {} from new derived {} ", nodeTypeV.getUniqueId(), newDerivedV.getUniqueId(), updateStatus);
802             return updateStatus;
803         }
804
805         Either<Edge, JanusGraphOperationStatus> deleteEdge = janusGraphDao
806             .deleteEdge(nodeTypeV, preDerivedV, EdgeLabelEnum.DERIVED_FROM);
807         if (deleteEdge.isRight()) {
808             JanusGraphOperationStatus deleteError = deleteEdge.right().value();
809             log.debug("Failed to disassociate element {} from derived {} , error {}", nodeTypeV.getUniqueId(), preDerivedV.getUniqueId(), deleteError);
810             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteError);
811         }
812
813         janusGraphDao.createEdge(nodeTypeV, newDerivedV, EdgeLabelEnum.DERIVED_FROM, new HashMap<>());
814
815         return StorageOperationStatus.OK;
816     }
817
818     private StorageOperationStatus associateDerivedDataByType(EdgeLabelEnum edgeLabel, GraphVertex nodeTypeV, NodeType nodeToUpdate, List<GraphVertex> newDerived) {
819
820         switch (edgeLabel) {
821         case CAPABILITIES:
822             return associateCapabilitiesToResource(nodeTypeV, nodeToUpdate, newDerived);
823         case REQUIREMENTS:
824             return associateRequirementsToResource(nodeTypeV, nodeToUpdate, newDerived);
825         case PROPERTIES:
826             return associatePropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
827         case ATTRIBUTES:
828             return associateAttributesToResource(nodeTypeV, nodeToUpdate, newDerived);
829         case ADDITIONAL_INFORMATION:
830             return addAdditionalInformationToResource(nodeTypeV, nodeToUpdate, newDerived);
831         case CAPABILITIES_PROPERTIES:
832             return associateCapabilitiesPropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
833         default:
834             return StorageOperationStatus.OK;
835         }
836
837     }
838
839     private StorageOperationStatus updateDataFromNewDerived(List<GraphVertex> newDerived, GraphVertex nodeTypeV, NodeType nodeToUpdate, boolean mergeValues, Set<String> preDerivedChainIdList) {
840         EnumSet<EdgeLabelEnum> edgeLabels = EnumSet.of(EdgeLabelEnum.CAPABILITIES, EdgeLabelEnum.REQUIREMENTS, EdgeLabelEnum.PROPERTIES, EdgeLabelEnum.ATTRIBUTES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.ADDITIONAL_INFORMATION);
841         StorageOperationStatus status = null;
842         for (EdgeLabelEnum edge : edgeLabels) {
843             status = updateDataByType(newDerived, nodeTypeV, edge, nodeToUpdate, mergeValues, preDerivedChainIdList);
844             if (status != StorageOperationStatus.OK) {
845                 break;
846             }
847         }
848         return status;
849
850     }
851
852     private <T extends ToscaDataDefinition> StorageOperationStatus updateDataByType(List<GraphVertex> newDerivedList, GraphVertex nodeTypeV, EdgeLabelEnum label, NodeType nodeElement, boolean mergeValues, Set<String> preDerivedChainIdList) {
853         log.debug("Update data from derived for element {} type {}", nodeTypeV.getUniqueId(), label);
854         Either<GraphVertex, JanusGraphOperationStatus> dataFromGraph = getDataVertex(nodeTypeV, label);
855         if (dataFromGraph.isRight()) {
856             if (JanusGraphOperationStatus.NOT_FOUND == dataFromGraph.right().value())
857                 return associateDerivedDataByType(label, nodeTypeV, nodeElement, newDerivedList);
858             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(dataFromGraph.right().value());
859         }
860         GraphVertex dataV = dataFromGraph.left().value();
861
862         Map<String, T> mapFromGraph = (Map<String, T>) dataV.getJson();
863         Map<String, T> valuesFrmPrev = null;
864         if (isSimpleHierarchy(label)) {
865             if (mergeValues) {
866                 valuesFrmPrev = mapFromGraph.entrySet().stream().filter(e -> e.getValue().getOwnerId() != null).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
867             }
868             mapFromGraph.entrySet().removeIf(e -> preDerivedChainIdList.contains(e.getValue().getOwnerId()));
869         } else {
870             final Map<String, T> valuesFrmPrevFinal = new HashMap<>();
871             mapFromGraph.entrySet().stream().forEach(e -> {
872                 T value = e.getValue();
873                 value = ToscaDataDefinition.removeAndCollectByOwnerId(value, preDerivedChainIdList);
874                 valuesFrmPrevFinal.put(e.getKey(), value);
875             });
876             valuesFrmPrev = valuesFrmPrevFinal;
877             mapFromGraph.entrySet().removeIf(e->e.getValue().isEmpty());
878         }
879
880         Either<Map<String, T>, StorageOperationStatus> dataFromDerived = getDataFromDerived(newDerivedList, label);
881         if (dataFromDerived.isRight()) {
882             return dataFromDerived.right().value();
883         }
884         Map<String, T> dataFromDerivedAll = dataFromDerived.left().value();
885
886         Either<Map<String, T>, String> merged = ToscaDataDefinition.mergeDataMaps(dataFromDerivedAll, mapFromGraph);
887         if (merged.isRight()) {
888             log.debug("property {} cannot be overriden", merged.right().value());
889             return StorageOperationStatus.INVALID_PROPERTY;
890         }
891         if (mergeValues && valuesFrmPrev != null) {
892             valuesFrmPrev.entrySet().forEach(e -> {
893                 T newData = merged.left().value().get(e.getKey());
894                 if (newData != null) {
895                     if (isSimpleHierarchy(label)) {
896                         e.getValue().mergeFunction(newData, true);
897                     }else{
898                         e.getValue().updateIfExist(newData, true);
899                     }
900                 }
901             });
902         }
903         dataV.setJson(dataFromDerivedAll);
904         Either<GraphVertex, JanusGraphOperationStatus> updateDataV = updateOrCopyOnUpdate(dataV, nodeTypeV, label);
905         if (updateDataV.isRight()) {
906             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateDataV.right().value());
907         }
908         return StorageOperationStatus.OK;
909     }
910
911     private boolean isSimpleHierarchy(EdgeLabelEnum label) {
912         switch (label) {
913         case PROPERTIES:
914         case ATTRIBUTES:
915         case ADDITIONAL_INFORMATION:
916         case ARTIFACTS:
917         case GROUPS:
918         case INPUTS:
919             return true;
920         default:
921             return false;
922         }
923     }
924
925     @Override
926     public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag) {
927         fillMetadata(elementV, (NodeType) toscaElementToUpdate);
928     }
929
930     public Either<ToscaElement, StorageOperationStatus> shouldUpdateDerivedVersion(ToscaElement toscaElementToUpdate, GraphVertex nodeTypeV) {
931         NodeType nodeType = (NodeType) toscaElementToUpdate;
932
933         Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
934             .getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
935         if (childVertex.isRight()) {
936             JanusGraphOperationStatus getchildError = childVertex.right().value();
937             if (getchildError == JanusGraphOperationStatus.NOT_FOUND) {
938                 log.debug("derived resource for element {} not found", nodeTypeV.getUniqueId());
939                 return Either.right(StorageOperationStatus.OK);
940             }
941
942             log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchildError);
943             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getchildError));
944         }
945         GraphVertex firstDerivedInChain = childVertex.left().value();
946
947         String currentVersion = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.VERSION);
948
949         Map<GraphPropertyEnum, Object> props = new HashMap<>();
950         props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, nodeType.getDerivedFrom().get(0));
951         props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
952         props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
953
954         Map<GraphPropertyEnum, Object> propsHasNot = new HashMap<>();
955         propsHasNot.put(GraphPropertyEnum.IS_DELETED, true);
956         Either<List<GraphVertex>, JanusGraphOperationStatus> byCriteria = janusGraphDao
957             .getByCriteria(VertexTypeEnum.NODE_TYPE, props, propsHasNot, JsonParseFlagEnum.NoParse);
958         if (byCriteria.isRight()) {
959             log.debug("Failed to fetch derived by props {} error {}", props, byCriteria.right().value());
960             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(byCriteria.right().value()));
961         }
962         List<GraphVertex> lastDerived = byCriteria.left().value();
963         // now supported only one derived!!! Change in future!(Evg)
964         GraphVertex derivedFromHighest = lastDerived.get(0);
965         String highestVersion = (String) derivedFromHighest.getMetadataProperty(GraphPropertyEnum.VERSION);
966         if (!highestVersion.equals(currentVersion)) {
967
968             // need to update to latest version of derived from
969             StorageOperationStatus updateDerived = updateDerived(toscaElementToUpdate, nodeTypeV, firstDerivedInChain, derivedFromHighest, true);
970
971             if (updateDerived != StorageOperationStatus.OK) {
972                 log.debug("Failed to update {} to highest derived {} from error {}", nodeTypeV.getUniqueId(), derivedFromHighest.getUniqueId(), updateDerived);
973                 return Either.right(updateDerived);
974             }
975             return getToscaElement(nodeTypeV.getUniqueId(), new ComponentParametersView());
976         }
977         // no version changes
978         return Either.right(StorageOperationStatus.OK);
979     }
980
981 }