[sdc] update to the current code base
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsontitan / operations / NodeTypeOperation.java
1 package org.openecomp.sdc.be.model.jsontitan.operations;
2
3 import fj.data.Either;
4
5 import org.apache.tinkerpop.gremlin.structure.Direction;
6 import org.apache.tinkerpop.gremlin.structure.Edge;
7 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
8 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
9 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
10 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
11 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
12 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
13 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
14 import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
15 import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
16 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
17 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
18 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
19 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
20 import org.openecomp.sdc.be.model.ComponentParametersView;
21 import org.openecomp.sdc.be.model.DerivedNodeTypeResolver;
22 import org.openecomp.sdc.be.model.LifecycleStateEnum;
23 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
24 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
25 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
26 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
27 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
28 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
29 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
30 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import org.springframework.beans.factory.annotation.Qualifier;
34
35 import java.util.ArrayList;
36 import java.util.Collection;
37 import java.util.EnumSet;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.regex.Pattern;
42
43 @org.springframework.stereotype.Component("node-type-operation")
44 public class NodeTypeOperation extends ToscaElementOperation {
45         public static Pattern uuidNewVersion = Pattern.compile("^\\d{1,}.1");
46         public static Pattern uuidNormativeNewVersion = Pattern.compile("^\\d{1,}.0");
47
48         private static Logger log = LoggerFactory.getLogger(NodeTypeOperation.class.getName());
49
50         private DerivedNodeTypeResolver derivedResourceResolver;
51
52         public NodeTypeOperation(@Qualifier("derived-resource-resolver") DerivedNodeTypeResolver derivedNodeTypeResolver) {
53                 this.derivedResourceResolver = derivedNodeTypeResolver;
54         }
55
56         public Either<NodeType, StorageOperationStatus> createNodeType(NodeType nodeType) {
57
58                 Either<NodeType, StorageOperationStatus> result = null;
59
60                 nodeType.generateUUID();
61
62                 nodeType = getResourceMetaDataFromResource(nodeType);
63                 String resourceUniqueId = nodeType.getUniqueId();
64                 if (resourceUniqueId == null) {
65                         resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId();
66                         nodeType.setUniqueId(resourceUniqueId);
67                 }
68
69                 // get derived from resources
70                 List<GraphVertex> derivedResources = null;
71                 Either<List<GraphVertex>, StorageOperationStatus> derivedResourcesResult = findDerivedResources(nodeType);
72                 if (derivedResourcesResult.isRight()) {
73                         result = Either.right(derivedResourcesResult.right().value());
74                         return result;
75                 } else {
76                         derivedResources = derivedResourcesResult.left().value();
77                 }
78
79                 GraphVertex nodeTypeVertex = new GraphVertex(VertexTypeEnum.NODE_TYPE);
80                 fillToscaElementVertexData(nodeTypeVertex, nodeType, JsonParseFlagEnum.ParseAll);
81
82                 Either<GraphVertex, TitanOperationStatus> createdVertex = titanDao.createVertex(nodeTypeVertex);
83                 if (createdVertex.isRight()) {
84                         TitanOperationStatus status = createdVertex.right().value();
85                         log.error("Error returned after creating resource data node {}. status returned is ", nodeTypeVertex, status);
86                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
87                         return result;
88                 }
89                 nodeTypeVertex = createdVertex.left().value();
90
91                 StorageOperationStatus assosiateCommon = assosiateCommonForToscaElement(nodeTypeVertex, nodeType, derivedResources);
92                 if (assosiateCommon != StorageOperationStatus.OK) {
93                         result = Either.right(assosiateCommon);
94                         return result;
95                 }
96
97                 StorageOperationStatus associateDerived = assosiateToDerived(nodeTypeVertex, derivedResources);
98                 if (associateDerived != StorageOperationStatus.OK) {
99                         result = Either.right(associateDerived);
100                         return result;
101                 }
102                 StorageOperationStatus associateCategory = assosiateResourceMetadataToCategory(nodeTypeVertex, nodeType);
103                 if (associateCategory != StorageOperationStatus.OK) {
104                         result = Either.right(associateCategory);
105                         return result;
106                 }
107
108                 StorageOperationStatus associateAttributes = associateAttributesToResource(nodeTypeVertex, nodeType, derivedResources);
109                 if (associateAttributes != StorageOperationStatus.OK) {
110                         result = Either.right(associateAttributes);
111                         return result;
112                 }
113
114                 StorageOperationStatus associateRequirements = associateRequirementsToResource(nodeTypeVertex, nodeType, derivedResources);
115                 if (associateRequirements != StorageOperationStatus.OK) {
116                         result = Either.right(associateRequirements);
117                         return result;
118                 }
119
120                 StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(nodeTypeVertex, nodeType, derivedResources);
121                 if (associateCapabilities != StorageOperationStatus.OK) {
122                         result = Either.right(associateCapabilities);
123                         return result;
124                 }
125                 StorageOperationStatus associateCapabilitiesProps = associateCapabilitiesPropertiesToResource(nodeTypeVertex, nodeType, derivedResources);
126                 if (associateCapabilitiesProps != StorageOperationStatus.OK) {
127                         result = Either.right(associateCapabilitiesProps);
128                         return result;
129                 }
130
131                 StorageOperationStatus associateInterfaces = associateInterfacesToResource(nodeTypeVertex, nodeType, derivedResources);
132                 if (associateInterfaces != StorageOperationStatus.OK) {
133                         result = Either.right(associateInterfaces);
134                         return result;
135                 }
136
137                 StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(nodeTypeVertex, nodeType, derivedResources);
138                 if (addAdditionalInformation != StorageOperationStatus.OK) {
139                         result = Either.right(addAdditionalInformation);
140                         return result;
141                 }
142                 result = Either.left(nodeType);
143                 return result;
144
145         }
146
147         private StorageOperationStatus associateInterfacesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
148                 // Note : currently only one derived supported!!!!
149                 Either<Map<String, InterfaceDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.INTERFACE_ARTIFACTS);
150                 if (dataFromDerived.isRight()) {
151                         return dataFromDerived.right().value();
152                 }
153                 Map<String, InterfaceDataDefinition> interfacArtsAll = dataFromDerived.left().value();
154
155                 Map<String, InterfaceDataDefinition> interfacArts = nodeType.getInterfaceArtifacts();
156                 if (interfacArts != null) {
157                         interfacArtsAll.putAll(interfacArts);
158                 }
159                 if (!interfacArtsAll.isEmpty()) {
160                         Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.INTERFACE_ARTIFACTS, EdgeLabelEnum.INTERFACE_ARTIFACTS, interfacArtsAll);
161                         if (assosiateElementToData.isRight()) {
162                                 return assosiateElementToData.right().value();
163                         }
164                 }
165                 return StorageOperationStatus.OK;
166         }
167
168         @Override
169         public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView) {
170
171                 Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(uniqueId, ToscaElementTypeEnum.NodeType, JsonParseFlagEnum.ParseMetadata);
172                 if (componentByLabelAndId.isRight()) {
173                         return Either.right(componentByLabelAndId.right().value());
174                 }
175                 GraphVertex componentV = componentByLabelAndId.left().value();
176
177                 return getToscaElement(componentV, componentParametersView);
178
179         }
180
181         // -------------------------------------------------------------
182         @Override
183         public Either<ToscaElement, StorageOperationStatus> getToscaElement(GraphVertex componentV, ComponentParametersView componentParametersView) {
184                 NodeType toscaElement;
185                 toscaElement = convertToComponent(componentV);
186                 TitanOperationStatus status = null;
187                 if (false == componentParametersView.isIgnoreUsers()) {
188                         status = setCreatorFromGraph(componentV, toscaElement);
189                         if (status != TitanOperationStatus.OK) {
190                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
191                         }
192
193                         status = setLastModifierFromGraph(componentV, toscaElement);
194                         if (status != TitanOperationStatus.OK) {
195                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
196                         }
197                 }
198
199                 if (false == componentParametersView.isIgnoreProperties()) {
200                         status = setResourcePropertiesFromGraph(componentV, toscaElement);
201                         if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
202                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
203                         }
204                 }
205
206                 if (false == componentParametersView.isIgnoreAttributesFrom()) {
207                         status = setResourceAttributesFromGraph(componentV, toscaElement);
208                         if (status != TitanOperationStatus.OK) {
209                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
210                         }
211                 }
212
213                 if (false == componentParametersView.isIgnoreDerivedFrom()) {
214                         status = setResourceDerivedFromGraph(componentV, toscaElement);
215                         if (status != TitanOperationStatus.OK) {
216                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
217                         }
218                 }
219
220                 if (false == componentParametersView.isIgnoreCategories()) {
221                         status = setResourceCategoryFromGraph(componentV, toscaElement);
222                         if (status != TitanOperationStatus.OK) {
223                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
224                         }
225                 }
226                 if (false == componentParametersView.isIgnoreRequirements()) {
227                         status = setResourceRequirementsFromGraph(componentV, toscaElement);
228                         if (status != TitanOperationStatus.OK) {
229                                 log.error("Failed to set requirement of resource {}. status is {}", componentV.getUniqueId(), status);
230                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
231                         }
232                 }
233                 if (false == componentParametersView.isIgnoreCapabilities()) {
234                         status = setResourceCapabilitiesFromGraph(componentV, toscaElement);
235                         if (status != TitanOperationStatus.OK) {
236                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
237                         }
238                 }
239
240                 if (false == componentParametersView.isIgnoreArtifacts()) {
241                         status = setArtifactsFromGraph(componentV, toscaElement);
242                         if (status != TitanOperationStatus.OK) {
243                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
244                         }
245                 }
246                 if (false == componentParametersView.isIgnoreAdditionalInformation()) {
247                         status = setAdditionalInformationFromGraph(componentV, toscaElement);
248                         if (status != TitanOperationStatus.OK) {
249                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
250                         }
251                 }
252                 if (false == componentParametersView.isIgnoreInterfaces()) {
253                         status = setInterfacesFromGraph(componentV, toscaElement);
254                         if (status != TitanOperationStatus.OK) {
255                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
256                         }
257                 }
258                 if (false == componentParametersView.isIgnoreAllVersions()) {
259                         status = setAllVersions(componentV, toscaElement);
260                         if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
261                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
262                         }
263                 }
264
265                 if (false == componentParametersView.isIgnoreCapabiltyProperties()) {
266                         status = setComponentCapPropertiesFromGraph(componentV, toscaElement);
267                         if (status != TitanOperationStatus.OK) {
268                                 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
269
270                         }
271                 }
272                 return Either.left(toscaElement);
273         }
274
275         private TitanOperationStatus setComponentCapPropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
276                 Either<Map<String, MapPropertiesDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
277                 if (result.isLeft()) {
278                         toscaElement.setCapabiltiesProperties(result.left().value());
279                 } else {
280                         if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
281                                 return result.right().value();
282                         }
283                 }
284                 return TitanOperationStatus.OK;
285         }
286
287         private TitanOperationStatus setInterfacesFromGraph(GraphVertex componentV, NodeType toscaElement) {
288                 Either<Map<String, InterfaceDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INTERFACE_ARTIFACTS);
289                 if (result.isLeft()) {
290                         toscaElement.setInterfaceArtifacts(result.left().value());
291                 } else {
292                         if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
293                                 return result.right().value();
294                         }
295                 }
296                 return TitanOperationStatus.OK;
297         }
298
299         protected <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement) {
300                 return setResourceCapabilitiesFromGraph(componentV, (NodeType) toscaElement);
301         }
302
303         private TitanOperationStatus setResourceCapabilitiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
304                 Either<Map<String, ListCapabilityDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES);
305                 if (result.isLeft()) {
306                         toscaElement.setCapabilties(result.left().value());
307                 } else {
308                         if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
309                                 return result.right().value();
310                         }
311                 }
312                 return TitanOperationStatus.OK;
313         }
314
315         private TitanOperationStatus setResourceDerivedFromGraph(GraphVertex componentV, NodeType toscaElement) {
316                 List<String> derivedFromList = new ArrayList<String>();
317
318                 TitanOperationStatus listFromGraphStatus = findResourcesPathRecursively(componentV, derivedFromList);
319                 if (TitanOperationStatus.OK != listFromGraphStatus) {
320                         return listFromGraphStatus;
321                 }
322
323                 if (false == derivedFromList.isEmpty()) {
324                         if (derivedFromList.size() > 1) {
325                                 List<String> lastDerivedFrom = new ArrayList<String>();
326                                 lastDerivedFrom.add(derivedFromList.get(1));
327                                 toscaElement.setDerivedFrom(lastDerivedFrom);
328                                 toscaElement.setDerivedList(derivedFromList);
329                         } else {
330                                 toscaElement.setDerivedFrom(null);
331                                 toscaElement.setDerivedList(derivedFromList);
332                         }
333
334                 }
335                 return TitanOperationStatus.OK;
336         }
337
338         protected TitanOperationStatus findResourcesPathRecursively(GraphVertex nodeTypeV, List<String> resourcesPathList) {
339                 Either<GraphVertex, TitanOperationStatus> parentResourceRes = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
340                 resourcesPathList.add((String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
341                 while (parentResourceRes.isLeft()) {
342
343                         GraphVertex parent = parentResourceRes.left().value();
344                         resourcesPathList.add((String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
345                         parentResourceRes = titanDao.getChildVertex(parent, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
346                 }
347                 TitanOperationStatus operationStatus = parentResourceRes.right().value();
348
349                 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
350                         return operationStatus;
351                 } else {
352                         return TitanOperationStatus.OK;
353                 }
354
355         }
356
357         protected <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement) {
358                 return setResourceRequirementsFromGraph(componentV, (NodeType) toscaElement);
359         }
360
361         private TitanOperationStatus setResourceRequirementsFromGraph(GraphVertex componentV, NodeType toscaElement) {
362                 Either<Map<String, ListRequirementDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.REQUIREMENTS);
363                 if (result.isLeft()) {
364                         toscaElement.setRequirements(result.left().value());
365                 } else {
366                         if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
367                                 return result.right().value();
368                         }
369                 }
370                 return TitanOperationStatus.OK;
371         }
372
373         private TitanOperationStatus setResourceAttributesFromGraph(GraphVertex componentV, NodeType toscaElement) {
374                 Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ATTRIBUTES);
375                 if (result.isLeft()) {
376                         toscaElement.setAttributes(result.left().value());
377                 } else {
378                         if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
379                                 return result.right().value();
380                         }
381                 }
382                 return TitanOperationStatus.OK;
383         }
384
385         private TitanOperationStatus setResourcePropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
386                 Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.PROPERTIES);
387                 if (result.isLeft()) {
388                         toscaElement.setProperties(result.left().value());
389                 } else {
390                         if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
391                                 return result.right().value();
392                         }
393                 }
394                 return TitanOperationStatus.OK;
395         }
396
397         private StorageOperationStatus assosiateToDerived(GraphVertex nodeTypeVertex, List<GraphVertex> derivedResources) {
398                 for (GraphVertex derivedV : derivedResources) {
399                         TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, derivedV, EdgeLabelEnum.DERIVED_FROM, null);
400                         if (createEdge != TitanOperationStatus.OK) {
401                                 log.trace("Failed to associate resource {} to derived with id {}", nodeTypeVertex.getUniqueId(), derivedV.getUniqueId());
402                                 return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
403                         }
404                 }
405                 return StorageOperationStatus.OK;
406         }
407
408         private StorageOperationStatus addAdditionalInformationToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
409                 // Note : currently only one derived supported!!!!
410                 Either<Map<String, AdditionalInfoParameterDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ADDITIONAL_INFORMATION);
411                 if (dataFromDerived.isRight()) {
412                         return dataFromDerived.right().value();
413                 }
414                 Map<String, AdditionalInfoParameterDataDefinition> addInformationAll = dataFromDerived.left().value();
415
416                 Map<String, AdditionalInfoParameterDataDefinition> addInformation = nodeType.getAdditionalInformation();
417                 if (addInformation != null) {
418                         ToscaDataDefinition.mergeDataMaps(addInformationAll, addInformation);
419                 }
420                 if (!addInformationAll.isEmpty()) {
421                         Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, addInformationAll);
422                         if (assosiateElementToData.isRight()) {
423                                 return assosiateElementToData.right().value();
424                         }
425                 }
426                 return StorageOperationStatus.OK;
427         }
428
429         private StorageOperationStatus associateCapabilitiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
430                 // Note : currently only one derived supported!!!!
431                 Either<Map<String, ListCapabilityDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES);
432                 if (dataFromDerived.isRight()) {
433                         return dataFromDerived.right().value();
434                 }
435                 Map<String, ListCapabilityDataDefinition> capabiltiesAll = dataFromDerived.left().value();
436
437                 Map<String, ListCapabilityDataDefinition> capabilties = nodeType.getCapabilties();
438                 if (capabilties != null) {
439                         if (capabiltiesAll == null) {
440                                 capabiltiesAll = new HashMap<>();
441                         }
442                         capabilties.values().forEach(l -> {
443                                 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
444                                         String uid = UniqueIdBuilder.buildCapabilityUid(nodeTypeVertex.getUniqueId(), p.getName());
445                                         p.setUniqueId(uid);
446                                 });
447                         });
448
449                         ToscaDataDefinition.mergeDataMaps(capabiltiesAll, capabilties);
450                 }
451                 if (!capabiltiesAll.isEmpty()) {
452                         Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILTIES, EdgeLabelEnum.CAPABILITIES, capabiltiesAll);
453                         if (assosiateElementToData.isRight()) {
454                                 return assosiateElementToData.right().value();
455                         }
456                 }
457                 return StorageOperationStatus.OK;
458         }
459
460         private StorageOperationStatus associateRequirementsToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
461                 // Note : currently only one derived supported!!!!
462                 Either<Map<String, ListRequirementDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.REQUIREMENTS);
463                 if (dataFromDerived.isRight()) {
464                         return dataFromDerived.right().value();
465                 }
466                 Map<String, ListRequirementDataDefinition> requirementsAll = dataFromDerived.left().value();
467
468                 Map<String, ListRequirementDataDefinition> requirements = nodeType.getRequirements();
469                 if (requirements != null) {
470                         if (requirementsAll == null) {
471                                 requirementsAll = new HashMap<>();
472                         }
473                         requirements.values().forEach(l -> {
474                                 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
475                                         String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
476                                         p.setUniqueId(uid);
477                                 });
478                         });
479                         
480                         ToscaDataDefinition.mergeDataMaps(requirementsAll, requirements);
481
482                 }
483                 if (!requirementsAll.isEmpty()) {
484                         Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.REQUIREMENTS, EdgeLabelEnum.REQUIREMENTS, requirementsAll);
485                         if (assosiateElementToData.isRight()) {
486                                 return assosiateElementToData.right().value();
487                         }
488                 }
489                 return StorageOperationStatus.OK;
490         }
491
492         private StorageOperationStatus associateAttributesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
493                 // Note : currently only one derived supported!!!!
494                 Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ATTRIBUTES);
495                 if (dataFromDerived.isRight()) {
496                         return dataFromDerived.right().value();
497                 }
498                 Map<String, PropertyDataDefinition> attributesAll = dataFromDerived.left().value();
499
500                 Map<String, PropertyDataDefinition> attributes = nodeType.getAttributes();
501                 if (attributes != null) {
502                         attributes.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
503                                 String uid = UniqueIdBuilder.buildAttributeUid(nodeTypeVertex.getUniqueId(), p.getName());
504                                 p.setUniqueId(uid);
505                         });
506                         ToscaDataDefinition.mergeDataMaps(attributesAll, attributes);
507                 }
508                 if (!attributesAll.isEmpty()) {
509                         Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ATTRIBUTES, EdgeLabelEnum.ATTRIBUTES, attributesAll);
510                         if (assosiateElementToData.isRight()) {
511                                 return assosiateElementToData.right().value();
512                         }
513                 }
514                 return StorageOperationStatus.OK;
515         }
516
517         // TODO get from derived
518         private StorageOperationStatus associateCapabilitiesPropertiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
519                 // // Note : currently only one derived supported!!!!
520                 Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
521                 if (dataFromDerived.isRight()) {
522                         return dataFromDerived.right().value();
523                 }
524                 Map<String, MapPropertiesDataDefinition> propertiesAll = dataFromDerived.left().value();
525                 Map<String, MapPropertiesDataDefinition> capabiltiesProps = nodeType.getCapabiltiesProperties();
526                 if (capabiltiesProps != null) {
527                         capabiltiesProps.values().forEach(l -> {
528                                 if (l.getMapToscaDataDefinition() != null && l.getMapToscaDataDefinition().values() != null) {
529                                         Collection<PropertyDataDefinition> mapToscaDataDefinition = l.getMapToscaDataDefinition().values();
530                                         mapToscaDataDefinition.stream().filter(p -> p != null && p.getUniqueId() == null).forEach(p -> {
531                                                 String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
532                                                 p.setUniqueId(uid);
533                                         });
534                                 }
535                         });
536                         ToscaDataDefinition.mergeDataMaps(propertiesAll, capabiltiesProps);
537                 }
538                 if (!propertiesAll.isEmpty()) {
539                         Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, propertiesAll);
540                         if (assosiateElementToData.isRight()) {
541                                 return assosiateElementToData.right().value();
542                         }
543                 }
544                 return StorageOperationStatus.OK;
545         }
546
547         public Either<List<GraphVertex>, StorageOperationStatus> findDerivedResources(NodeType nodeType) {
548
549                 List<GraphVertex> derivedResources = new ArrayList<GraphVertex>();
550                 List<String> derivedFromResources = nodeType.getDerivedFrom();
551                 if (derivedFromResources != null && false == derivedFromResources.isEmpty()) {
552
553                         for (String parentResource : derivedFromResources) {
554                                 Either<List<GraphVertex>, TitanOperationStatus> getParentResources = derivedResourceResolver.findDerivedResources(parentResource);
555                                 List<GraphVertex> resources = null;
556                                 if (getParentResources.isRight()) {
557                                         log.error("Cannot find parent resource by tosca resource name {} in the graph.", parentResource);
558                                         return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
559
560                                 } else {
561                                         resources = getParentResources.left().value();
562                                         if (resources == null || resources.size() == 0) {
563                                                 log.error("Cannot find parent resource by tosca name {} in the graph. resources size is empty", parentResource);
564                                                 return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
565                                         } else {
566                                                 if (resources.size() > 1) {
567                                                         log.error("Multiple parent resources called {} found in the graph.", parentResource);
568                                                         return Either.right(StorageOperationStatus.MULTIPLE_PARENT_RESOURCE_FOUND);
569                                                 }
570                                                 GraphVertex parentResourceData = resources.get(0);
571                                                 derivedResources.add(parentResourceData);
572                                         }
573
574                                 }
575
576                         }
577                 }
578                 return Either.left(derivedResources);
579         }
580
581         private GraphVertex fillMetadata(GraphVertex nodeTypeVertex, NodeType nodeType) {
582                 nodeTypeVertex.setLabel(VertexTypeEnum.NODE_TYPE);
583
584                 fillCommonMetadata(nodeTypeVertex, nodeType);
585
586                 return nodeTypeVertex;
587         }
588
589         @Override
590         public Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex) {
591                 Either<ToscaElement, StorageOperationStatus> nodeType = getToscaElement(toscaElementVertex, new ComponentParametersView());
592                 if (nodeType.isRight()) {
593                         log.debug("Failed to fetch tosca element {} error {}", toscaElementVertex.getUniqueId(), nodeType.right().value());
594                         return nodeType;
595                 }
596                 TitanOperationStatus status = disassociateAndDeleteCommonElements(toscaElementVertex);
597                 if (status != TitanOperationStatus.OK) {
598                         Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
599                 }
600                 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
601                 if (status != TitanOperationStatus.OK) {
602                         log.debug("Failed to disassociate capabilties for {} error {}", toscaElementVertex.getUniqueId(), status);
603                         Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
604                 }
605                 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
606                 if (status != TitanOperationStatus.OK) {
607                         log.debug("Failed to disassociate capabilties properties for {} error {}", toscaElementVertex.getUniqueId(), status);
608                         Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
609                 }
610                 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
611                 if (status != TitanOperationStatus.OK) {
612                         log.debug("Failed to disassociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
613                         Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
614                 }
615                 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
616                 if (status != TitanOperationStatus.OK) {
617                         log.debug("Failed to disassociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
618                         Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
619                 }
620                 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INTERFACE_ARTIFACTS);
621                 if (status != TitanOperationStatus.OK) {
622                         log.debug("Failed to disassociate interface artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
623                         Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
624                 }
625                 toscaElementVertex.getVertex().remove();
626                 log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
627
628                 return nodeType;
629         }
630
631         @SuppressWarnings("unchecked")
632         @Override
633         public Either<NodeType, StorageOperationStatus> createToscaElement(ToscaElement toscaElement) {
634                 return createNodeType((NodeType) toscaElement);
635         }
636
637         @Override
638         protected <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement) {
639                 return setResourceCategoryFromGraph(vertexComponent, toscaElement);
640         }
641
642         @Override
643         protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV) {
644                 return validateResourceCategory(toscaElementToUpdate, elementV);
645         }
646
647         @Override
648         protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV) {
649
650                 NodeType nodeType = (NodeType) toscaElementToUpdate;
651                 List<GraphVertex> derivedResources = new ArrayList<>();
652
653                 List<String> derivedFromResources = nodeType.getDerivedFrom();
654
655                 // now supported only single derived from
656                 if (derivedFromResources != null && !derivedFromResources.isEmpty() && derivedFromResources.get(0) != null) {
657                         String firstDerived = derivedFromResources.get(0);
658                         boolean derivedFromGenericType = null != nodeType.getDerivedFromGenericType();
659                         Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
660                         if (childVertex.isRight()) {
661                                 TitanOperationStatus getchieldError = childVertex.right().value();
662                                 log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchieldError);
663                                 return DaoStatusConverter.convertTitanStatusToStorageStatus(getchieldError);
664                         }
665                         GraphVertex firstDerivedInChain = childVertex.left().value();
666
667                         String firstCurrentDerived = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME);
668                         if (!firstDerived.equals(firstCurrentDerived) || derivedFromGenericType) {
669
670                                 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
671                                 propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
672
673                                 propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, firstDerived);
674                                 propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
675
676                                 Either<List<GraphVertex>, TitanOperationStatus> getParentResources = titanDao.getByCriteria(VertexTypeEnum.NODE_TYPE, propertiesToMatch, JsonParseFlagEnum.NoParse);
677
678                                 if (getParentResources.isRight()) {
679                                         TitanOperationStatus error = getParentResources.right().value();
680                                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch derived by criteria {}. error {} ", propertiesToMatch, error);
681                                         return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
682                                 }
683                                 // must be only one
684                                 GraphVertex newDerived = getParentResources.left().value().get(0);
685                                 derivedResources.add(newDerived);
686                                 StorageOperationStatus updateStatus = updateDataFromNewDerived(derivedResources, nodeTypeV, (NodeType)toscaElementToUpdate);
687                                 if (updateStatus != StorageOperationStatus.OK) {
688                                         CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update data for {} from new derived {} ", nodeTypeV.getUniqueId(), newDerived.getUniqueId(), updateStatus);
689                                         return updateStatus;
690                                 }
691
692                                 Either<Edge, TitanOperationStatus> deleteEdge = titanDao.deleteEdge(nodeTypeV, firstDerivedInChain, EdgeLabelEnum.DERIVED_FROM);
693                                 if (deleteEdge.isRight()) {
694                                         TitanOperationStatus deleteError = deleteEdge.right().value();
695                                         log.debug("Failed to disassociate element {} from derived {} , error {}", nodeTypeV.getUniqueId(), firstDerivedInChain.getUniqueId(), deleteError);
696                                         return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteError);
697                                 }
698
699                                 titanDao.createEdge(nodeTypeV, newDerived, EdgeLabelEnum.DERIVED_FROM, new HashMap<>());
700                         }
701                 }
702
703                 return StorageOperationStatus.OK;
704         }
705         
706         private StorageOperationStatus associateDerivedDataByType(EdgeLabelEnum edgeLabel, GraphVertex nodeTypeV, NodeType nodeToUpdate, List<GraphVertex> newDerived) {
707                 
708                 switch (edgeLabel) {
709                 case CAPABILITIES:
710                         return associateCapabilitiesToResource(nodeTypeV, nodeToUpdate, newDerived);
711                 case REQUIREMENTS:
712                         return associateRequirementsToResource(nodeTypeV, nodeToUpdate, newDerived);
713                 case PROPERTIES:
714                         return associatePropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
715                 case ATTRIBUTES:
716                         return associateAttributesToResource(nodeTypeV, nodeToUpdate, newDerived);
717                 case ADDITIONAL_INFORMATION:
718                         return addAdditionalInformationToResource(nodeTypeV, nodeToUpdate, newDerived);
719                 case CAPABILITIES_PROPERTIES:
720                         return associateCapabilitiesPropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
721                 default:
722                         return StorageOperationStatus.OK;
723                 }
724
725         }
726
727         private StorageOperationStatus updateDataFromNewDerived(List<GraphVertex> newDerived, GraphVertex nodeTypeV, NodeType nodeToUpdate) {    
728                 EnumSet<EdgeLabelEnum> edgeLabels = EnumSet.of(EdgeLabelEnum.CAPABILITIES, EdgeLabelEnum.REQUIREMENTS, EdgeLabelEnum.PROPERTIES, EdgeLabelEnum.ATTRIBUTES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.ADDITIONAL_INFORMATION);
729                 StorageOperationStatus status = null;
730                 for (EdgeLabelEnum edge : edgeLabels){
731                         status = updateDataByType(newDerived, nodeTypeV, edge, nodeToUpdate);
732                         if (status != StorageOperationStatus.OK) {
733                                 break;
734                         }
735                 }
736                 return status;
737                 
738         }
739
740         private <T extends ToscaDataDefinition> StorageOperationStatus updateDataByType(List<GraphVertex> newDerivedList, GraphVertex nodeTypeV, EdgeLabelEnum label, NodeType nodeElement) {
741                 log.debug("Update data from derived for element {} type {}", nodeTypeV.getUniqueId(), label);
742                 Either<GraphVertex, TitanOperationStatus> dataFromGraph = getDataVertex(nodeTypeV, label);
743                 if (dataFromGraph.isRight()) {
744                         if (TitanOperationStatus.NOT_FOUND == dataFromGraph.right().value())
745                                 return associateDerivedDataByType(label, nodeTypeV, nodeElement, newDerivedList);
746                         return DaoStatusConverter.convertTitanStatusToStorageStatus(dataFromGraph.right().value());
747                 }
748                 GraphVertex dataV = dataFromGraph.left().value();
749
750                 Map<String, T> mapFromGraph = (Map<String, T>) dataV.getJson();
751                 mapFromGraph.entrySet().removeIf(e -> e.getValue().getOwnerId() != null);
752
753                 
754                 Either<Map<String, T>, StorageOperationStatus> dataFromDerived = getDataFromDerived(newDerivedList, label);
755                 if (dataFromDerived.isRight()) {
756                         return dataFromDerived.right().value();
757                 }
758                 Map<String, T> dataFromDerivedAll = dataFromDerived.left().value();
759                 
760                 Either<Map<String, T>, String> merged = ToscaDataDefinition.mergeDataMaps(dataFromDerivedAll, mapFromGraph);
761                 if(merged.isRight()){
762                         log.debug("property {} cannot be overriden", merged.right().value());
763                         return StorageOperationStatus.INVALID_PROPERTY;
764                 }
765                 dataV.setJson(dataFromDerivedAll);
766                 Either<GraphVertex, TitanOperationStatus> updateDataV = updateOrCopyOnUpdate(dataV, nodeTypeV, label);
767                 if (updateDataV.isRight()) {
768                         return DaoStatusConverter.convertTitanStatusToStorageStatus(updateDataV.right().value());
769                 }
770                 return StorageOperationStatus.OK;
771         }
772
773         @Override
774         public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag) {
775                 fillMetadata(elementV, (NodeType) toscaElementToUpdate);
776         }
777
778 }