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