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