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