2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
23 import fj.data.Either;
24 import org.apache.tinkerpop.gremlin.structure.Direction;
25 import org.apache.tinkerpop.gremlin.structure.Edge;
26 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
27 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
28 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
29 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
30 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
31 import org.openecomp.sdc.be.datatypes.elements.*;
32 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
33 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
34 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
35 import org.openecomp.sdc.be.model.ComponentParametersView;
36 import org.openecomp.sdc.be.model.DerivedNodeTypeResolver;
37 import org.openecomp.sdc.be.model.LifecycleStateEnum;
38 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.NodeType;
39 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement;
40 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElementTypeEnum;
41 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
42 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
43 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
44 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
45 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
46 import org.openecomp.sdc.common.log.wrappers.Logger;
47 import org.springframework.beans.factory.annotation.Qualifier;
50 import java.util.regex.Pattern;
51 import java.util.stream.Collectors;
53 @org.springframework.stereotype.Component("node-type-operation")
54 public class NodeTypeOperation extends ToscaElementOperation {
55 public static final Pattern uuidNewVersion = Pattern.compile("^\\d+.1");
56 public static final Pattern uuidNormativeNewVersion = Pattern.compile("^\\d+.0");
57 private static final Logger log = Logger.getLogger(NodeTypeOperation.class);
58 private DerivedNodeTypeResolver derivedResourceResolver;
61 public NodeTypeOperation(@Qualifier("derived-resource-resolver") DerivedNodeTypeResolver derivedNodeTypeResolver) {
62 this.derivedResourceResolver = derivedNodeTypeResolver;
65 public Either<NodeType, StorageOperationStatus> createNodeType(NodeType nodeType) {
67 Either<NodeType, StorageOperationStatus> result = null;
69 nodeType.generateUUID();
71 nodeType = getResourceMetaDataFromResource(nodeType);
72 String resourceUniqueId = nodeType.getUniqueId();
73 if (resourceUniqueId == null) {
74 resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId();
75 nodeType.setUniqueId(resourceUniqueId);
78 // get derived from resources
79 List<GraphVertex> derivedResources = null;
80 Either<List<GraphVertex>, StorageOperationStatus> derivedResourcesResult = findDerivedResources(nodeType);
81 if (derivedResourcesResult.isRight()) {
82 result = Either.right(derivedResourcesResult.right().value());
85 derivedResources = derivedResourcesResult.left().value();
88 GraphVertex nodeTypeVertex = new GraphVertex(VertexTypeEnum.NODE_TYPE);
89 fillToscaElementVertexData(nodeTypeVertex, nodeType, JsonParseFlagEnum.ParseAll);
91 Either<GraphVertex, JanusGraphOperationStatus> createdVertex = janusGraphDao.createVertex(nodeTypeVertex);
92 if (createdVertex.isRight()) {
93 JanusGraphOperationStatus status = createdVertex.right().value();
94 log.error("Error returned after creating resource data node {}. status returned is ", nodeTypeVertex, status);
95 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
98 nodeTypeVertex = createdVertex.left().value();
100 StorageOperationStatus assosiateCommon = assosiateCommonForToscaElement(nodeTypeVertex, nodeType, derivedResources);
101 if (assosiateCommon != StorageOperationStatus.OK) {
102 result = Either.right(assosiateCommon);
106 StorageOperationStatus associateDerived = assosiateToDerived(nodeTypeVertex, derivedResources);
107 if (associateDerived != StorageOperationStatus.OK) {
108 result = Either.right(associateDerived);
111 StorageOperationStatus associateCategory = assosiateResourceMetadataToCategory(nodeTypeVertex, nodeType);
112 if (associateCategory != StorageOperationStatus.OK) {
113 result = Either.right(associateCategory);
117 StorageOperationStatus associateAttributes = associateAttributesToResource(nodeTypeVertex, nodeType, derivedResources);
118 if (associateAttributes != StorageOperationStatus.OK) {
119 result = Either.right(associateAttributes);
123 StorageOperationStatus associateRequirements = associateRequirementsToResource(nodeTypeVertex, nodeType, derivedResources);
124 if (associateRequirements != StorageOperationStatus.OK) {
125 result = Either.right(associateRequirements);
129 StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(nodeTypeVertex, nodeType, derivedResources);
130 if (associateCapabilities != StorageOperationStatus.OK) {
131 result = Either.right(associateCapabilities);
134 StorageOperationStatus associateCapabilitiesProps = associateCapabilitiesPropertiesToResource(nodeTypeVertex, nodeType, derivedResources);
135 if (associateCapabilitiesProps != StorageOperationStatus.OK) {
136 result = Either.right(associateCapabilitiesProps);
140 StorageOperationStatus associateInterfaces = associateInterfacesToResource(nodeTypeVertex, nodeType, derivedResources);
141 if (associateInterfaces != StorageOperationStatus.OK) {
142 result = Either.right(associateInterfaces);
146 StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(nodeTypeVertex, nodeType, derivedResources);
147 if (addAdditionalInformation != StorageOperationStatus.OK) {
148 result = Either.right(addAdditionalInformation);
151 result = Either.left(nodeType);
156 private StorageOperationStatus associateInterfacesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
157 // Note : currently only one derived supported!!!!
158 Either<Map<String, InterfaceDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.INTERFACE_ARTIFACTS);
159 if (dataFromDerived.isRight()) {
160 return dataFromDerived.right().value();
162 Map<String, InterfaceDataDefinition> interfacArtsAll = dataFromDerived.left().value();
164 Map<String, InterfaceDataDefinition> interfacArts = nodeType.getInterfaceArtifacts();
165 if (interfacArts != null) {
166 interfacArtsAll.putAll(interfacArts);
168 if (!interfacArtsAll.isEmpty()) {
169 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.INTERFACE_ARTIFACTS, EdgeLabelEnum.INTERFACE_ARTIFACTS, interfacArtsAll);
170 if (assosiateElementToData.isRight()) {
171 return assosiateElementToData.right().value();
174 return StorageOperationStatus.OK;
178 public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView) {
180 Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(uniqueId, ToscaElementTypeEnum.NODE_TYPE, JsonParseFlagEnum.ParseMetadata);
181 if (componentByLabelAndId.isRight()) {
182 return Either.right(componentByLabelAndId.right().value());
184 GraphVertex componentV = componentByLabelAndId.left().value();
186 return getToscaElement(componentV, componentParametersView);
190 // -------------------------------------------------------------
192 public Either<ToscaElement, StorageOperationStatus> getToscaElement(GraphVertex componentV, ComponentParametersView componentParametersView) {
193 NodeType toscaElement;
194 toscaElement = convertToComponent(componentV);
195 JanusGraphOperationStatus status = null;
196 if (!componentParametersView.isIgnoreUsers()) {
197 status = setCreatorFromGraph(componentV, toscaElement);
198 if (status != JanusGraphOperationStatus.OK) {
199 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
202 status = setLastModifierFromGraph(componentV, toscaElement);
203 if (status != JanusGraphOperationStatus.OK) {
204 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
208 if (!componentParametersView.isIgnoreProperties()) {
209 status = setResourcePropertiesFromGraph(componentV, toscaElement);
210 if (status != JanusGraphOperationStatus.OK && status != JanusGraphOperationStatus.NOT_FOUND) {
211 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
215 if (!componentParametersView.isIgnoreAttributesFrom()) {
216 status = setResourceAttributesFromGraph(componentV, toscaElement);
217 if (status != JanusGraphOperationStatus.OK) {
218 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
222 if (!componentParametersView.isIgnoreDerivedFrom()) {
223 status = setResourceDerivedFromGraph(componentV, toscaElement);
224 if (status != JanusGraphOperationStatus.OK) {
225 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
229 if (!componentParametersView.isIgnoreCategories()) {
230 status = setResourceCategoryFromGraph(componentV, toscaElement);
231 if (status != JanusGraphOperationStatus.OK) {
232 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
235 if (!componentParametersView.isIgnoreRequirements()) {
236 status = setResourceRequirementsFromGraph(componentV, toscaElement);
237 if (status != JanusGraphOperationStatus.OK) {
238 log.error("Failed to set requirement of resource {}. status is {}", componentV.getUniqueId(), status);
239 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
242 if (!componentParametersView.isIgnoreCapabilities()) {
243 status = setResourceCapabilitiesFromGraph(componentV, toscaElement);
244 if (status != JanusGraphOperationStatus.OK) {
245 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
249 if (!componentParametersView.isIgnoreArtifacts()) {
250 status = setArtifactsFromGraph(componentV, toscaElement);
251 if (status != JanusGraphOperationStatus.OK) {
252 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
255 if (!componentParametersView.isIgnoreAdditionalInformation()) {
256 status = setAdditionalInformationFromGraph(componentV, toscaElement);
257 if (status != JanusGraphOperationStatus.OK) {
258 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
261 if (!componentParametersView.isIgnoreInterfaces()) {
262 status = setInterfacesFromGraph(componentV, toscaElement);
263 if (status != JanusGraphOperationStatus.OK) {
264 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
267 if (!componentParametersView.isIgnoreAllVersions()) {
268 status = setAllVersions(componentV, toscaElement);
269 if (status != JanusGraphOperationStatus.OK && status != JanusGraphOperationStatus.NOT_FOUND) {
270 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
274 if (!componentParametersView.isIgnoreCapabiltyProperties()) {
275 status = setComponentCapPropertiesFromGraph(componentV, toscaElement);
276 if (status != JanusGraphOperationStatus.OK) {
277 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
281 return Either.left(toscaElement);
284 private JanusGraphOperationStatus setComponentCapPropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
285 Either<Map<String, MapPropertiesDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
286 if (result.isLeft()) {
287 toscaElement.setCapabilitiesProperties(result.left().value());
289 if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
290 return result.right().value();
293 return JanusGraphOperationStatus.OK;
296 private JanusGraphOperationStatus setInterfacesFromGraph(GraphVertex componentV, NodeType toscaElement) {
297 Either<Map<String, InterfaceDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INTERFACE_ARTIFACTS);
298 if (result.isLeft()) {
299 toscaElement.setInterfaceArtifacts(result.left().value());
301 if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
302 return result.right().value();
305 return JanusGraphOperationStatus.OK;
308 protected <T extends ToscaElement> JanusGraphOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement) {
309 return setResourceCapabilitiesFromGraph(componentV, (NodeType) toscaElement);
312 private JanusGraphOperationStatus setResourceCapabilitiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
313 Either<Map<String, ListCapabilityDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES);
314 if (result.isLeft()) {
315 toscaElement.setCapabilities(result.left().value());
317 if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
318 return result.right().value();
321 return JanusGraphOperationStatus.OK;
324 private JanusGraphOperationStatus setResourceDerivedFromGraph(final GraphVertex componentV,
325 final NodeType toscaElement) {
326 final List<String> derivedFromList = new ArrayList<>();
327 final Map<String, String> derivedFromMapOfIdToName = new LinkedHashMap<>();
329 final JanusGraphOperationStatus listFromGraphStatus = findResourcesPathRecursively(componentV, derivedFromList,
330 derivedFromMapOfIdToName);
331 if (JanusGraphOperationStatus.OK != listFromGraphStatus) {
332 return listFromGraphStatus;
335 if (!derivedFromList.isEmpty()) {
336 if (derivedFromList.size() > 1) {
337 final List<String> lastDerivedFrom = new ArrayList<>();
338 lastDerivedFrom.add(derivedFromList.get(1));
339 toscaElement.setDerivedFrom(lastDerivedFrom);
341 toscaElement.setDerivedFrom(null);
343 toscaElement.setDerivedList(derivedFromList);
344 toscaElement.setDerivedFromMapOfIdToName(derivedFromMapOfIdToName);
346 return JanusGraphOperationStatus.OK;
349 private JanusGraphOperationStatus findResourcesPathRecursively(final GraphVertex nodeTypeV,
350 final List<String> resourcesPathList,
351 final Map<String, String> derivedFromMapOfIdToName) {
352 Either<GraphVertex, JanusGraphOperationStatus> parentResourceRes = janusGraphDao
353 .getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
354 resourcesPathList.add((String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
355 derivedFromMapOfIdToName.put(nodeTypeV.getUniqueId(),
356 (String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
357 while (parentResourceRes.isLeft()) {
358 final GraphVertex parent = parentResourceRes.left().value();
359 resourcesPathList.add((String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
360 derivedFromMapOfIdToName
361 .put(parent.getUniqueId(), (String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
362 parentResourceRes = janusGraphDao
363 .getChildVertex(parent, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
365 final JanusGraphOperationStatus operationStatus = parentResourceRes.right().value();
367 if (operationStatus != JanusGraphOperationStatus.NOT_FOUND) {
368 return operationStatus;
370 return JanusGraphOperationStatus.OK;
375 protected <T extends ToscaElement> JanusGraphOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement) {
376 return setResourceRequirementsFromGraph(componentV, (NodeType) toscaElement);
379 private JanusGraphOperationStatus setResourceRequirementsFromGraph(GraphVertex componentV, NodeType toscaElement) {
380 Either<Map<String, ListRequirementDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.REQUIREMENTS);
381 if (result.isLeft()) {
382 toscaElement.setRequirements(result.left().value());
384 if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
385 return result.right().value();
388 return JanusGraphOperationStatus.OK;
391 private JanusGraphOperationStatus setResourceAttributesFromGraph(GraphVertex componentV, NodeType toscaElement) {
392 Either<Map<String, AttributeDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ATTRIBUTES);
393 if (result.isLeft()) {
394 toscaElement.setAttributes(result.left().value());
396 if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
397 return result.right().value();
400 return JanusGraphOperationStatus.OK;
403 private JanusGraphOperationStatus setResourcePropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
404 Either<Map<String, PropertyDataDefinition>, JanusGraphOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.PROPERTIES);
405 if (result.isLeft()) {
406 toscaElement.setProperties(result.left().value());
408 if (result.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
409 return result.right().value();
412 return JanusGraphOperationStatus.OK;
415 private StorageOperationStatus assosiateToDerived(GraphVertex nodeTypeVertex, List<GraphVertex> derivedResources) {
416 for (GraphVertex derivedV : derivedResources) {
417 JanusGraphOperationStatus
418 createEdge = janusGraphDao
419 .createEdge(nodeTypeVertex, derivedV, EdgeLabelEnum.DERIVED_FROM, null);
420 if (createEdge != JanusGraphOperationStatus.OK) {
421 log.trace("Failed to associate resource {} to derived with id {}", nodeTypeVertex.getUniqueId(), derivedV.getUniqueId());
422 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdge);
425 return StorageOperationStatus.OK;
428 private StorageOperationStatus addAdditionalInformationToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
429 // Note : currently only one derived supported!!!!
430 Either<Map<String, AdditionalInfoParameterDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ADDITIONAL_INFORMATION);
431 if (dataFromDerived.isRight()) {
432 return dataFromDerived.right().value();
434 Map<String, AdditionalInfoParameterDataDefinition> addInformationAll = dataFromDerived.left().value();
436 Map<String, AdditionalInfoParameterDataDefinition> addInformation = nodeType.getAdditionalInformation();
437 if (addInformation != null) {
438 ToscaDataDefinition.mergeDataMaps(addInformationAll, addInformation);
440 if (!addInformationAll.isEmpty()) {
441 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, addInformationAll);
442 if (assosiateElementToData.isRight()) {
443 return assosiateElementToData.right().value();
446 return StorageOperationStatus.OK;
449 private StorageOperationStatus associateCapabilitiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
450 // Note : currently only one derived supported!!!!
451 Either<Map<String, ListCapabilityDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES);
452 if (dataFromDerived.isRight()) {
453 return dataFromDerived.right().value();
455 Map<String, ListCapabilityDataDefinition> capabiltiesAll = dataFromDerived.left().value();
457 Map<String, ListCapabilityDataDefinition> capabilties = nodeType.getCapabilities();
458 if (capabilties != null) {
459 if (capabiltiesAll == null) {
460 capabiltiesAll = new HashMap<>();
462 capabilties.values().forEach(l -> {
463 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
464 String uid = UniqueIdBuilder.buildCapabilityUid(nodeTypeVertex.getUniqueId(), p.getName());
469 ToscaDataDefinition.mergeDataMaps(capabiltiesAll, capabilties);
470 capabiltiesAll.values().forEach(l -> {
471 l.getListToscaDataDefinition().forEach(c -> {
472 List<String> capabilitySources = c.getCapabilitySources();
473 if (capabilitySources == null) {
474 capabilitySources = new ArrayList<>();
476 capabilitySources.add((String) nodeType.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
477 c.setCapabilitySources(capabilitySources);
481 capabiltiesAll.values().forEach(l -> {
482 l.getListToscaDataDefinition().forEach(c -> {
483 List<String> capabilitySources = c.getCapabilitySources();
484 if (capabilitySources == null) {
485 capabilitySources = new ArrayList<>();
487 capabilitySources.add((String) nodeType.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
488 c.setCapabilitySources(capabilitySources);
491 if (!capabiltiesAll.isEmpty()) {
492 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES, EdgeLabelEnum.CAPABILITIES, capabiltiesAll);
493 if (assosiateElementToData.isRight()) {
494 return assosiateElementToData.right().value();
497 return StorageOperationStatus.OK;
500 private StorageOperationStatus associateRequirementsToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
501 // Note : currently only one derived supported!!!!
502 Either<Map<String, ListRequirementDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.REQUIREMENTS);
503 if (dataFromDerived.isRight()) {
504 return dataFromDerived.right().value();
506 Map<String, ListRequirementDataDefinition> requirementsAll = dataFromDerived.left().value();
508 Map<String, ListRequirementDataDefinition> requirements = nodeType.getRequirements();
509 if (requirements != null) {
510 if (requirementsAll == null) {
511 requirementsAll = new HashMap<>();
513 requirements.values().forEach(l -> {
514 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
515 String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
520 ToscaDataDefinition.mergeDataMaps(requirementsAll, requirements);
523 if (!requirementsAll.isEmpty()) {
524 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.REQUIREMENTS, EdgeLabelEnum.REQUIREMENTS, requirementsAll);
525 if (assosiateElementToData.isRight()) {
526 return assosiateElementToData.right().value();
529 return StorageOperationStatus.OK;
532 private StorageOperationStatus associateAttributesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
533 // Note : currently only one derived supported!!!!
534 Either<Map<String, AttributeDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ATTRIBUTES);
535 if (dataFromDerived.isRight()) {
536 return dataFromDerived.right().value();
538 Map<String, AttributeDataDefinition> attributesAll = dataFromDerived.left().value();
540 Map<String, AttributeDataDefinition> attributes = nodeType.getAttributes();
541 if (attributes != null) {
542 attributes.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
543 String uid = UniqueIdBuilder.buildAttributeUid(nodeTypeVertex.getUniqueId(), p.getName());
546 ToscaDataDefinition.mergeDataMaps(attributesAll, attributes);
548 if (!attributesAll.isEmpty()) {
549 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.ATTRIBUTES, EdgeLabelEnum.ATTRIBUTES, attributesAll);
550 if (assosiateElementToData.isRight()) {
551 return assosiateElementToData.right().value();
554 return StorageOperationStatus.OK;
557 // TODO get from derived
558 private StorageOperationStatus associateCapabilitiesPropertiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
559 // // Note : currently only one derived supported!!!!
560 Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
561 if (dataFromDerived.isRight()) {
562 return dataFromDerived.right().value();
564 Map<String, MapPropertiesDataDefinition> propertiesAll = dataFromDerived.left().value();
565 Map<String, MapPropertiesDataDefinition> capabiltiesProps = nodeType.getCapabilitiesProperties();
566 if (capabiltiesProps != null) {
567 capabiltiesProps.values().forEach(l -> {
568 if (l.getMapToscaDataDefinition() != null && l.getMapToscaDataDefinition().values() != null) {
569 Collection<PropertyDataDefinition> mapToscaDataDefinition = l.getMapToscaDataDefinition().values();
570 mapToscaDataDefinition.stream().filter(p -> p != null && p.getUniqueId() == null).forEach(p -> {
571 String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
576 ToscaDataDefinition.mergeDataMaps(propertiesAll, capabiltiesProps);
578 if (!propertiesAll.isEmpty()) {
579 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, propertiesAll);
580 if (assosiateElementToData.isRight()) {
581 return assosiateElementToData.right().value();
584 return StorageOperationStatus.OK;
587 public Either<List<GraphVertex>, StorageOperationStatus> findDerivedResources(NodeType nodeType) {
589 List<GraphVertex> derivedResources = new ArrayList<>();
590 List<String> derivedFromResources = nodeType.getDerivedFrom();
591 if (derivedFromResources != null && !derivedFromResources.isEmpty()) {
593 for (String parentResource : derivedFromResources) {
594 Either<List<GraphVertex>, JanusGraphOperationStatus> getParentResources = derivedResourceResolver.findDerivedResources(parentResource);
595 List<GraphVertex> resources = null;
596 if (getParentResources.isRight()) {
597 log.error("Cannot find parent resource by tosca resource name {} in the graph.", parentResource);
598 return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
601 resources = getParentResources.left().value();
602 if (resources == null || resources.size() == 0) {
603 log.error("Cannot find parent resource by tosca name {} in the graph. resources size is empty", parentResource);
604 return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
606 if (resources.size() > 1) {
607 return handleMultipleParent(parentResource, derivedResources, resources);
609 GraphVertex parentResourceData = resources.get(0);
610 derivedResources.add(parentResourceData);
618 return Either.left(derivedResources);
621 Either<List<GraphVertex>, StorageOperationStatus> handleMultipleParent(String parentResource, List<GraphVertex> derivedResource, List<GraphVertex> fetchedDerivedResources) {
623 Either<List<GraphVertex>, StorageOperationStatus> result = Either.left(derivedResource);
625 fetchedDerivedResources.sort((d1, d2) -> {
626 return new Double(Double.parseDouble((String) d1.getMetadataProperty(GraphPropertyEnum.VERSION))).compareTo(Double.parseDouble((String) d2.getMetadataProperty(GraphPropertyEnum.VERSION)));
629 int actualHighestIndex = fetchedDerivedResources.size() - 1;
630 derivedResource.add(fetchedDerivedResources.get(actualHighestIndex));
631 fetchedDerivedResources.remove(actualHighestIndex);
633 StorageOperationStatus status = fixMultipleParent(fetchedDerivedResources);
634 if (status != StorageOperationStatus.OK) {
635 result = Either.right(status);
637 } catch (Exception e) {
638 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during handle multiple parent {}. Exception is {}", parentResource, e.getMessage());
639 result = Either.right(StorageOperationStatus.GENERAL_ERROR);
644 private StorageOperationStatus fixMultipleParent(List<GraphVertex> fetchedDerivedResources) {
645 StorageOperationStatus result = StorageOperationStatus.OK;
646 for (GraphVertex fetchedDerivedResource : fetchedDerivedResources) {
647 fetchedDerivedResource.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
648 Either<GraphVertex, JanusGraphOperationStatus> updateVertexRes = janusGraphDao.updateVertex(fetchedDerivedResource);
649 if (updateVertexRes.isRight()) {
650 JanusGraphOperationStatus titatStatus = updateVertexRes.right().value();
651 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set highest version of node type {} to false. Status is {}", fetchedDerivedResource.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME), titatStatus);
652 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(titatStatus);
659 private GraphVertex fillMetadata(GraphVertex nodeTypeVertex, NodeType nodeType) {
660 nodeTypeVertex.setLabel(VertexTypeEnum.NODE_TYPE);
662 fillCommonMetadata(nodeTypeVertex, nodeType);
663 nodeTypeVertex.setJsonMetadataField(JsonPresentationFields.ATTRIBUTES, nodeType.getAttributes());
665 return nodeTypeVertex;
669 public Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex) {
670 Either<ToscaElement, StorageOperationStatus> nodeType = getToscaElement(toscaElementVertex, new ComponentParametersView());
671 if (nodeType.isRight()) {
672 log.debug("Failed to fetch tosca element {} error {}", toscaElementVertex.getUniqueId(), nodeType.right().value());
675 JanusGraphOperationStatus status = disassociateAndDeleteCommonElements(toscaElementVertex);
676 if (status != JanusGraphOperationStatus.OK) {
677 Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
679 status = janusGraphDao
680 .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
681 if (status != JanusGraphOperationStatus.OK) {
682 log.debug("Failed to disassociate capabilties for {} error {}", toscaElementVertex.getUniqueId(), status);
683 Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
685 status = janusGraphDao
686 .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
687 if (status != JanusGraphOperationStatus.OK) {
688 log.debug("Failed to disassociate capabilties properties for {} error {}", toscaElementVertex.getUniqueId(), status);
689 Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
691 status = janusGraphDao
692 .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
693 if (status != JanusGraphOperationStatus.OK) {
694 log.debug("Failed to disassociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
695 Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
697 status = janusGraphDao
698 .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
699 if (status != JanusGraphOperationStatus.OK) {
700 log.debug("Failed to disassociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
701 Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
703 status = janusGraphDao
704 .disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INTERFACE_ARTIFACTS);
705 if (status != JanusGraphOperationStatus.OK) {
706 log.debug("Failed to disassociate interface artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
707 Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
709 toscaElementVertex.getVertex().remove();
710 log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
715 @SuppressWarnings("unchecked")
717 public Either<NodeType, StorageOperationStatus> createToscaElement(ToscaElement toscaElement) {
718 return createNodeType((NodeType) toscaElement);
722 protected <T extends ToscaElement> JanusGraphOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement) {
723 return setResourceCategoryFromGraph(vertexComponent, toscaElement);
727 protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV) {
728 return validateResourceCategory(toscaElementToUpdate, elementV);
732 protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV) {
734 NodeType nodeType = (NodeType) toscaElementToUpdate;
736 List<String> derivedFromResources = nodeType.getDerivedFrom();
738 // now supported only single derived from
739 if (derivedFromResources != null && !derivedFromResources.isEmpty() && derivedFromResources.get(0) != null) {
740 String firstDerived = derivedFromResources.get(0);
741 boolean derivedFromGenericType = null != nodeType.getDerivedFromGenericType();
742 Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
743 .getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
744 if (childVertex.isRight()) {
745 JanusGraphOperationStatus getchieldError = childVertex.right().value();
746 log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchieldError);
747 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getchieldError);
749 GraphVertex firstDerivedInChain = childVertex.left().value();
751 String firstCurrentDerived = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME);
752 if (!firstDerived.equals(firstCurrentDerived) || derivedFromGenericType) {
754 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
755 propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
757 propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, firstDerived);
758 propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
760 Either<List<GraphVertex>, JanusGraphOperationStatus> getParentResources = janusGraphDao
761 .getByCriteria(VertexTypeEnum.NODE_TYPE, propertiesToMatch, JsonParseFlagEnum.NoParse);
763 if (getParentResources.isRight()) {
764 JanusGraphOperationStatus error = getParentResources.right().value();
765 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch derived by criteria {}. error {} ", propertiesToMatch, error);
766 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(error);
769 GraphVertex newDerivedV = getParentResources.left().value().get(0);
770 return updateDerived(toscaElementToUpdate, nodeTypeV, firstDerivedInChain, newDerivedV, false);
773 return StorageOperationStatus.OK;
778 * @param toscaElementToUpdate
785 protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV, GraphVertex preDerivedV, GraphVertex newDerivedV, boolean mergeValues) {
786 Set<String> preDerivedChainIdList = new HashSet();
787 preDerivedChainIdList.add(preDerivedV.getUniqueId());
788 Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
789 .getChildVertex(preDerivedV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
790 while (childVertex.isLeft()) {
791 GraphVertex currentChield = childVertex.left().value();
792 preDerivedChainIdList.add(currentChield.getUniqueId());
793 childVertex = janusGraphDao
794 .getChildVertex(currentChield, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
797 List<GraphVertex> derivedResources = new ArrayList<>();
798 derivedResources.add(newDerivedV);
799 StorageOperationStatus updateStatus = updateDataFromNewDerived(derivedResources, nodeTypeV, (NodeType) toscaElementToUpdate, mergeValues, preDerivedChainIdList);
800 if (updateStatus != StorageOperationStatus.OK) {
801 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update data for {} from new derived {} ", nodeTypeV.getUniqueId(), newDerivedV.getUniqueId(), updateStatus);
805 Either<Edge, JanusGraphOperationStatus> deleteEdge = janusGraphDao
806 .deleteEdge(nodeTypeV, preDerivedV, EdgeLabelEnum.DERIVED_FROM);
807 if (deleteEdge.isRight()) {
808 JanusGraphOperationStatus deleteError = deleteEdge.right().value();
809 log.debug("Failed to disassociate element {} from derived {} , error {}", nodeTypeV.getUniqueId(), preDerivedV.getUniqueId(), deleteError);
810 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteError);
813 janusGraphDao.createEdge(nodeTypeV, newDerivedV, EdgeLabelEnum.DERIVED_FROM, new HashMap<>());
815 return StorageOperationStatus.OK;
818 private StorageOperationStatus associateDerivedDataByType(EdgeLabelEnum edgeLabel, GraphVertex nodeTypeV, NodeType nodeToUpdate, List<GraphVertex> newDerived) {
822 return associateCapabilitiesToResource(nodeTypeV, nodeToUpdate, newDerived);
824 return associateRequirementsToResource(nodeTypeV, nodeToUpdate, newDerived);
826 return associatePropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
828 return associateAttributesToResource(nodeTypeV, nodeToUpdate, newDerived);
829 case ADDITIONAL_INFORMATION:
830 return addAdditionalInformationToResource(nodeTypeV, nodeToUpdate, newDerived);
831 case CAPABILITIES_PROPERTIES:
832 return associateCapabilitiesPropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
834 return StorageOperationStatus.OK;
839 private StorageOperationStatus updateDataFromNewDerived(List<GraphVertex> newDerived, GraphVertex nodeTypeV, NodeType nodeToUpdate, boolean mergeValues, Set<String> preDerivedChainIdList) {
840 EnumSet<EdgeLabelEnum> edgeLabels = EnumSet.of(EdgeLabelEnum.CAPABILITIES, EdgeLabelEnum.REQUIREMENTS, EdgeLabelEnum.PROPERTIES, EdgeLabelEnum.ATTRIBUTES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.ADDITIONAL_INFORMATION);
841 StorageOperationStatus status = null;
842 for (EdgeLabelEnum edge : edgeLabels) {
843 status = updateDataByType(newDerived, nodeTypeV, edge, nodeToUpdate, mergeValues, preDerivedChainIdList);
844 if (status != StorageOperationStatus.OK) {
852 private <T extends ToscaDataDefinition> StorageOperationStatus updateDataByType(List<GraphVertex> newDerivedList, GraphVertex nodeTypeV, EdgeLabelEnum label, NodeType nodeElement, boolean mergeValues, Set<String> preDerivedChainIdList) {
853 log.debug("Update data from derived for element {} type {}", nodeTypeV.getUniqueId(), label);
854 Either<GraphVertex, JanusGraphOperationStatus> dataFromGraph = getDataVertex(nodeTypeV, label);
855 if (dataFromGraph.isRight()) {
856 if (JanusGraphOperationStatus.NOT_FOUND == dataFromGraph.right().value())
857 return associateDerivedDataByType(label, nodeTypeV, nodeElement, newDerivedList);
858 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(dataFromGraph.right().value());
860 GraphVertex dataV = dataFromGraph.left().value();
862 Map<String, T> mapFromGraph = (Map<String, T>) dataV.getJson();
863 Map<String, T> valuesFrmPrev = null;
864 if (isSimpleHierarchy(label)) {
866 valuesFrmPrev = mapFromGraph.entrySet().stream().filter(e -> e.getValue().getOwnerId() != null).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
868 mapFromGraph.entrySet().removeIf(e -> preDerivedChainIdList.contains(e.getValue().getOwnerId()));
870 final Map<String, T> valuesFrmPrevFinal = new HashMap<>();
871 mapFromGraph.entrySet().stream().forEach(e -> {
872 T value = e.getValue();
873 value = ToscaDataDefinition.removeAndCollectByOwnerId(value, preDerivedChainIdList);
874 valuesFrmPrevFinal.put(e.getKey(), value);
876 valuesFrmPrev = valuesFrmPrevFinal;
877 mapFromGraph.entrySet().removeIf(e->e.getValue().isEmpty());
880 Either<Map<String, T>, StorageOperationStatus> dataFromDerived = getDataFromDerived(newDerivedList, label);
881 if (dataFromDerived.isRight()) {
882 return dataFromDerived.right().value();
884 Map<String, T> dataFromDerivedAll = dataFromDerived.left().value();
886 Either<Map<String, T>, String> merged = ToscaDataDefinition.mergeDataMaps(dataFromDerivedAll, mapFromGraph);
887 if (merged.isRight()) {
888 log.debug("property {} cannot be overriden", merged.right().value());
889 return StorageOperationStatus.INVALID_PROPERTY;
891 if (mergeValues && valuesFrmPrev != null) {
892 valuesFrmPrev.entrySet().forEach(e -> {
893 T newData = merged.left().value().get(e.getKey());
894 if (newData != null) {
895 if (isSimpleHierarchy(label)) {
896 e.getValue().mergeFunction(newData, true);
898 e.getValue().updateIfExist(newData, true);
903 dataV.setJson(dataFromDerivedAll);
904 Either<GraphVertex, JanusGraphOperationStatus> updateDataV = updateOrCopyOnUpdate(dataV, nodeTypeV, label);
905 if (updateDataV.isRight()) {
906 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateDataV.right().value());
908 return StorageOperationStatus.OK;
911 private boolean isSimpleHierarchy(EdgeLabelEnum label) {
915 case ADDITIONAL_INFORMATION:
926 public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag) {
927 fillMetadata(elementV, (NodeType) toscaElementToUpdate);
930 public Either<ToscaElement, StorageOperationStatus> shouldUpdateDerivedVersion(ToscaElement toscaElementToUpdate, GraphVertex nodeTypeV) {
931 NodeType nodeType = (NodeType) toscaElementToUpdate;
933 Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
934 .getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
935 if (childVertex.isRight()) {
936 JanusGraphOperationStatus getchildError = childVertex.right().value();
937 if (getchildError == JanusGraphOperationStatus.NOT_FOUND) {
938 log.debug("derived resource for element {} not found", nodeTypeV.getUniqueId());
939 return Either.right(StorageOperationStatus.OK);
942 log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchildError);
943 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getchildError));
945 GraphVertex firstDerivedInChain = childVertex.left().value();
947 String currentVersion = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.VERSION);
949 Map<GraphPropertyEnum, Object> props = new HashMap<>();
950 props.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, nodeType.getDerivedFrom().get(0));
951 props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
952 props.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
954 Map<GraphPropertyEnum, Object> propsHasNot = new HashMap<>();
955 propsHasNot.put(GraphPropertyEnum.IS_DELETED, true);
956 Either<List<GraphVertex>, JanusGraphOperationStatus> byCriteria = janusGraphDao
957 .getByCriteria(VertexTypeEnum.NODE_TYPE, props, propsHasNot, JsonParseFlagEnum.NoParse);
958 if (byCriteria.isRight()) {
959 log.debug("Failed to fetch derived by props {} error {}", props, byCriteria.right().value());
960 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(byCriteria.right().value()));
962 List<GraphVertex> lastDerived = byCriteria.left().value();
963 // now supported only one derived!!! Change in future!(Evg)
964 GraphVertex derivedFromHighest = lastDerived.get(0);
965 String highestVersion = (String) derivedFromHighest.getMetadataProperty(GraphPropertyEnum.VERSION);
966 if (!highestVersion.equals(currentVersion)) {
968 // need to update to latest version of derived from
969 StorageOperationStatus updateDerived = updateDerived(toscaElementToUpdate, nodeTypeV, firstDerivedInChain, derivedFromHighest, true);
971 if (updateDerived != StorageOperationStatus.OK) {
972 log.debug("Failed to update {} to highest derived {} from error {}", nodeTypeV.getUniqueId(), derivedFromHighest.getUniqueId(), updateDerived);
973 return Either.right(updateDerived);
975 return getToscaElement(nodeTypeV.getUniqueId(), new ComponentParametersView());
977 // no version changes
978 return Either.right(StorageOperationStatus.OK);