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