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