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