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