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.jsontitan.operations;
23 import fj.data.Either;
25 import org.apache.tinkerpop.gremlin.structure.Direction;
26 import org.apache.tinkerpop.gremlin.structure.Edge;
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.dao.titan.TitanOperationStatus;
32 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
33 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
34 import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
35 import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
37 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
38 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
39 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
40 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
41 import org.openecomp.sdc.be.model.ComponentParametersView;
42 import org.openecomp.sdc.be.model.DerivedNodeTypeResolver;
43 import org.openecomp.sdc.be.model.LifecycleStateEnum;
44 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
45 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
46 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
47 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
48 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
49 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
50 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
51 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54 import org.springframework.beans.factory.annotation.Qualifier;
56 import java.util.ArrayList;
57 import java.util.Collection;
58 import java.util.Collections;
59 import java.util.EnumSet;
60 import java.util.HashMap;
61 import java.util.List;
63 import java.util.regex.Pattern;
65 @org.springframework.stereotype.Component("node-type-operation")
66 public class NodeTypeOperation extends ToscaElementOperation {
67 public static Pattern uuidNewVersion = Pattern.compile("^\\d{1,}.1");
68 public static Pattern uuidNormativeNewVersion = Pattern.compile("^\\d{1,}.0");
70 private static Logger log = LoggerFactory.getLogger(NodeTypeOperation.class.getName());
72 private DerivedNodeTypeResolver derivedResourceResolver;
74 public NodeTypeOperation(@Qualifier("derived-resource-resolver") DerivedNodeTypeResolver derivedNodeTypeResolver) {
75 this.derivedResourceResolver = derivedNodeTypeResolver;
78 public Either<NodeType, StorageOperationStatus> createNodeType(NodeType nodeType) {
80 Either<NodeType, StorageOperationStatus> result = null;
82 nodeType.generateUUID();
84 nodeType = getResourceMetaDataFromResource(nodeType);
85 String resourceUniqueId = nodeType.getUniqueId();
86 if (resourceUniqueId == null) {
87 resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId();
88 nodeType.setUniqueId(resourceUniqueId);
91 // get derived from resources
92 List<GraphVertex> derivedResources = null;
93 Either<List<GraphVertex>, StorageOperationStatus> derivedResourcesResult = findDerivedResources(nodeType);
94 if (derivedResourcesResult.isRight()) {
95 result = Either.right(derivedResourcesResult.right().value());
98 derivedResources = derivedResourcesResult.left().value();
101 GraphVertex nodeTypeVertex = new GraphVertex(VertexTypeEnum.NODE_TYPE);
102 fillToscaElementVertexData(nodeTypeVertex, nodeType, JsonParseFlagEnum.ParseAll);
104 Either<GraphVertex, TitanOperationStatus> createdVertex = titanDao.createVertex(nodeTypeVertex);
105 if (createdVertex.isRight()) {
106 TitanOperationStatus status = createdVertex.right().value();
107 log.error("Error returned after creating resource data node {}. status returned is ", nodeTypeVertex, status);
108 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
111 nodeTypeVertex = createdVertex.left().value();
113 StorageOperationStatus assosiateCommon = assosiateCommonForToscaElement(nodeTypeVertex, nodeType, derivedResources);
114 if (assosiateCommon != StorageOperationStatus.OK) {
115 result = Either.right(assosiateCommon);
119 StorageOperationStatus associateDerived = assosiateToDerived(nodeTypeVertex, derivedResources);
120 if (associateDerived != StorageOperationStatus.OK) {
121 result = Either.right(associateDerived);
124 StorageOperationStatus associateCategory = assosiateResourceMetadataToCategory(nodeTypeVertex, nodeType);
125 if (associateCategory != StorageOperationStatus.OK) {
126 result = Either.right(associateCategory);
130 StorageOperationStatus associateAttributes = associateAttributesToResource(nodeTypeVertex, nodeType, derivedResources);
131 if (associateAttributes != StorageOperationStatus.OK) {
132 result = Either.right(associateAttributes);
136 StorageOperationStatus associateRequirements = associateRequirementsToResource(nodeTypeVertex, nodeType, derivedResources);
137 if (associateRequirements != StorageOperationStatus.OK) {
138 result = Either.right(associateRequirements);
142 StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(nodeTypeVertex, nodeType, derivedResources);
143 if (associateCapabilities != StorageOperationStatus.OK) {
144 result = Either.right(associateCapabilities);
147 StorageOperationStatus associateCapabilitiesProps = associateCapabilitiesPropertiesToResource(nodeTypeVertex, nodeType, derivedResources);
148 if (associateCapabilitiesProps != StorageOperationStatus.OK) {
149 result = Either.right(associateCapabilitiesProps);
153 StorageOperationStatus associateInterfaces = associateInterfacesToResource(nodeTypeVertex, nodeType, derivedResources);
154 if (associateInterfaces != StorageOperationStatus.OK) {
155 result = Either.right(associateInterfaces);
159 StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(nodeTypeVertex, nodeType, derivedResources);
160 if (addAdditionalInformation != StorageOperationStatus.OK) {
161 result = Either.right(addAdditionalInformation);
164 result = Either.left(nodeType);
169 private StorageOperationStatus associateInterfacesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
170 // Note : currently only one derived supported!!!!
171 Either<Map<String, InterfaceDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.INTERFACE_ARTIFACTS);
172 if (dataFromDerived.isRight()) {
173 return dataFromDerived.right().value();
175 Map<String, InterfaceDataDefinition> interfacArtsAll = dataFromDerived.left().value();
177 Map<String, InterfaceDataDefinition> interfacArts = nodeType.getInterfaceArtifacts();
178 if (interfacArts != null) {
179 interfacArtsAll.putAll(interfacArts);
181 if (!interfacArtsAll.isEmpty()) {
182 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.INTERFACE_ARTIFACTS, EdgeLabelEnum.INTERFACE_ARTIFACTS, interfacArtsAll);
183 if (assosiateElementToData.isRight()) {
184 return assosiateElementToData.right().value();
187 return StorageOperationStatus.OK;
191 public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView) {
193 Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(uniqueId, ToscaElementTypeEnum.NodeType, JsonParseFlagEnum.ParseMetadata);
194 if (componentByLabelAndId.isRight()) {
195 return Either.right(componentByLabelAndId.right().value());
197 GraphVertex componentV = componentByLabelAndId.left().value();
199 return getToscaElement(componentV, componentParametersView);
203 // -------------------------------------------------------------
205 public Either<ToscaElement, StorageOperationStatus> getToscaElement(GraphVertex componentV, ComponentParametersView componentParametersView) {
206 NodeType toscaElement;
207 toscaElement = convertToComponent(componentV);
208 TitanOperationStatus status = null;
209 if (false == componentParametersView.isIgnoreUsers()) {
210 status = setCreatorFromGraph(componentV, toscaElement);
211 if (status != TitanOperationStatus.OK) {
212 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
215 status = setLastModifierFromGraph(componentV, toscaElement);
216 if (status != TitanOperationStatus.OK) {
217 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
221 if (false == componentParametersView.isIgnoreProperties()) {
222 status = setResourcePropertiesFromGraph(componentV, toscaElement);
223 if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
224 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
228 if (false == componentParametersView.isIgnoreAttributesFrom()) {
229 status = setResourceAttributesFromGraph(componentV, toscaElement);
230 if (status != TitanOperationStatus.OK) {
231 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
235 if (false == componentParametersView.isIgnoreDerivedFrom()) {
236 status = setResourceDerivedFromGraph(componentV, toscaElement);
237 if (status != TitanOperationStatus.OK) {
238 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
242 if (false == componentParametersView.isIgnoreCategories()) {
243 status = setResourceCategoryFromGraph(componentV, toscaElement);
244 if (status != TitanOperationStatus.OK) {
245 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
248 if (false == componentParametersView.isIgnoreRequirements()) {
249 status = setResourceRequirementsFromGraph(componentV, toscaElement);
250 if (status != TitanOperationStatus.OK) {
251 log.error("Failed to set requirement of resource {}. status is {}", componentV.getUniqueId(), status);
252 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
255 if (false == componentParametersView.isIgnoreCapabilities()) {
256 status = setResourceCapabilitiesFromGraph(componentV, toscaElement);
257 if (status != TitanOperationStatus.OK) {
258 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
262 if (false == componentParametersView.isIgnoreArtifacts()) {
263 status = setArtifactsFromGraph(componentV, toscaElement);
264 if (status != TitanOperationStatus.OK) {
265 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
268 if (false == componentParametersView.isIgnoreAdditionalInformation()) {
269 status = setAdditionalInformationFromGraph(componentV, toscaElement);
270 if (status != TitanOperationStatus.OK) {
271 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
274 if (false == componentParametersView.isIgnoreInterfaces()) {
275 status = setInterfacesFromGraph(componentV, toscaElement);
276 if (status != TitanOperationStatus.OK) {
277 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
280 if (false == componentParametersView.isIgnoreAllVersions()) {
281 status = setAllVersions(componentV, toscaElement);
282 if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
283 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
287 if (false == componentParametersView.isIgnoreCapabiltyProperties()) {
288 status = setComponentCapPropertiesFromGraph(componentV, toscaElement);
289 if (status != TitanOperationStatus.OK) {
290 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
294 return Either.left(toscaElement);
297 private TitanOperationStatus setComponentCapPropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
298 Either<Map<String, MapPropertiesDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
299 if (result.isLeft()) {
300 toscaElement.setCapabiltiesProperties(result.left().value());
302 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
303 return result.right().value();
306 return TitanOperationStatus.OK;
309 private TitanOperationStatus setInterfacesFromGraph(GraphVertex componentV, NodeType toscaElement) {
310 Either<Map<String, InterfaceDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INTERFACE_ARTIFACTS);
311 if (result.isLeft()) {
312 toscaElement.setInterfaceArtifacts(result.left().value());
314 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
315 return result.right().value();
318 return TitanOperationStatus.OK;
321 protected <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement) {
322 return setResourceCapabilitiesFromGraph(componentV, (NodeType) toscaElement);
325 private TitanOperationStatus setResourceCapabilitiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
326 Either<Map<String, ListCapabilityDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES);
327 if (result.isLeft()) {
328 toscaElement.setCapabilties(result.left().value());
330 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
331 return result.right().value();
334 return TitanOperationStatus.OK;
337 private TitanOperationStatus setResourceDerivedFromGraph(GraphVertex componentV, NodeType toscaElement) {
338 List<String> derivedFromList = new ArrayList<String>();
340 TitanOperationStatus listFromGraphStatus = findResourcesPathRecursively(componentV, derivedFromList);
341 if (TitanOperationStatus.OK != listFromGraphStatus) {
342 return listFromGraphStatus;
345 if (false == derivedFromList.isEmpty()) {
346 if (derivedFromList.size() > 1) {
347 List<String> lastDerivedFrom = new ArrayList<String>();
348 lastDerivedFrom.add(derivedFromList.get(1));
349 toscaElement.setDerivedFrom(lastDerivedFrom);
350 toscaElement.setDerivedList(derivedFromList);
352 toscaElement.setDerivedFrom(null);
353 toscaElement.setDerivedList(derivedFromList);
357 return TitanOperationStatus.OK;
360 protected TitanOperationStatus findResourcesPathRecursively(GraphVertex nodeTypeV, List<String> resourcesPathList) {
361 Either<GraphVertex, TitanOperationStatus> parentResourceRes = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
362 resourcesPathList.add((String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
363 while (parentResourceRes.isLeft()) {
365 GraphVertex parent = parentResourceRes.left().value();
366 resourcesPathList.add((String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
367 parentResourceRes = titanDao.getChildVertex(parent, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
369 TitanOperationStatus operationStatus = parentResourceRes.right().value();
371 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
372 return operationStatus;
374 return TitanOperationStatus.OK;
379 protected <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement) {
380 return setResourceRequirementsFromGraph(componentV, (NodeType) toscaElement);
383 private TitanOperationStatus setResourceRequirementsFromGraph(GraphVertex componentV, NodeType toscaElement) {
384 Either<Map<String, ListRequirementDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.REQUIREMENTS);
385 if (result.isLeft()) {
386 toscaElement.setRequirements(result.left().value());
388 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
389 return result.right().value();
392 return TitanOperationStatus.OK;
395 private TitanOperationStatus setResourceAttributesFromGraph(GraphVertex componentV, NodeType toscaElement) {
396 Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ATTRIBUTES);
397 if (result.isLeft()) {
398 toscaElement.setAttributes(result.left().value());
400 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
401 return result.right().value();
404 return TitanOperationStatus.OK;
407 private TitanOperationStatus setResourcePropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
408 Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.PROPERTIES);
409 if (result.isLeft()) {
410 toscaElement.setProperties(result.left().value());
412 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
413 return result.right().value();
416 return TitanOperationStatus.OK;
419 private StorageOperationStatus assosiateToDerived(GraphVertex nodeTypeVertex, List<GraphVertex> derivedResources) {
420 for (GraphVertex derivedV : derivedResources) {
421 TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, derivedV, EdgeLabelEnum.DERIVED_FROM, null);
422 if (createEdge != TitanOperationStatus.OK) {
423 log.trace("Failed to associate resource {} to derived with id {}", nodeTypeVertex.getUniqueId(), derivedV.getUniqueId());
424 return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
427 return StorageOperationStatus.OK;
430 private StorageOperationStatus addAdditionalInformationToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
431 // Note : currently only one derived supported!!!!
432 Either<Map<String, AdditionalInfoParameterDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ADDITIONAL_INFORMATION);
433 if (dataFromDerived.isRight()) {
434 return dataFromDerived.right().value();
436 Map<String, AdditionalInfoParameterDataDefinition> addInformationAll = dataFromDerived.left().value();
438 Map<String, AdditionalInfoParameterDataDefinition> addInformation = nodeType.getAdditionalInformation();
439 if (addInformation != null) {
440 ToscaDataDefinition.mergeDataMaps(addInformationAll, addInformation);
442 if (!addInformationAll.isEmpty()) {
443 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, addInformationAll);
444 if (assosiateElementToData.isRight()) {
445 return assosiateElementToData.right().value();
448 return StorageOperationStatus.OK;
451 private StorageOperationStatus associateCapabilitiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
452 // Note : currently only one derived supported!!!!
453 Either<Map<String, ListCapabilityDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES);
454 if (dataFromDerived.isRight()) {
455 return dataFromDerived.right().value();
457 Map<String, ListCapabilityDataDefinition> capabiltiesAll = dataFromDerived.left().value();
459 Map<String, ListCapabilityDataDefinition> capabilties = nodeType.getCapabilties();
460 if (capabilties != null) {
461 if (capabiltiesAll == null) {
462 capabiltiesAll = new HashMap<>();
464 capabilties.values().forEach(l -> {
465 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
466 String uid = UniqueIdBuilder.buildCapabilityUid(nodeTypeVertex.getUniqueId(), p.getName());
471 ToscaDataDefinition.mergeDataMaps(capabiltiesAll, capabilties);
474 capabiltiesAll.values().forEach(l -> {
475 l.getListToscaDataDefinition().forEach(c -> {
476 List<String> capabilitySources = c.getCapabilitySources();
477 if ( capabilitySources == null ){
478 capabilitySources = new ArrayList<>();
480 capabilitySources.add((String) nodeType.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
481 c.setCapabilitySources(capabilitySources);
486 if (!capabiltiesAll.isEmpty()) {
487 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILTIES, EdgeLabelEnum.CAPABILITIES, capabiltiesAll);
488 if (assosiateElementToData.isRight()) {
489 return assosiateElementToData.right().value();
492 return StorageOperationStatus.OK;
495 private StorageOperationStatus associateRequirementsToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
496 // Note : currently only one derived supported!!!!
497 Either<Map<String, ListRequirementDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.REQUIREMENTS);
498 if (dataFromDerived.isRight()) {
499 return dataFromDerived.right().value();
501 Map<String, ListRequirementDataDefinition> requirementsAll = dataFromDerived.left().value();
503 Map<String, ListRequirementDataDefinition> requirements = nodeType.getRequirements();
504 if (requirements != null) {
505 if (requirementsAll == null) {
506 requirementsAll = new HashMap<>();
508 requirements.values().forEach(l -> {
509 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
510 String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
515 ToscaDataDefinition.mergeDataMaps(requirementsAll, requirements);
518 if (!requirementsAll.isEmpty()) {
519 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.REQUIREMENTS, EdgeLabelEnum.REQUIREMENTS, requirementsAll);
520 if (assosiateElementToData.isRight()) {
521 return assosiateElementToData.right().value();
524 return StorageOperationStatus.OK;
527 private StorageOperationStatus associateAttributesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
528 // Note : currently only one derived supported!!!!
529 Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ATTRIBUTES);
530 if (dataFromDerived.isRight()) {
531 return dataFromDerived.right().value();
533 Map<String, PropertyDataDefinition> attributesAll = dataFromDerived.left().value();
535 Map<String, PropertyDataDefinition> attributes = nodeType.getAttributes();
536 if (attributes != null) {
537 attributes.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
538 String uid = UniqueIdBuilder.buildAttributeUid(nodeTypeVertex.getUniqueId(), p.getName());
541 ToscaDataDefinition.mergeDataMaps(attributesAll, attributes);
543 if (!attributesAll.isEmpty()) {
544 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ATTRIBUTES, EdgeLabelEnum.ATTRIBUTES, attributesAll);
545 if (assosiateElementToData.isRight()) {
546 return assosiateElementToData.right().value();
549 return StorageOperationStatus.OK;
552 // TODO get from derived
553 private StorageOperationStatus associateCapabilitiesPropertiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
554 // // Note : currently only one derived supported!!!!
555 Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
556 if (dataFromDerived.isRight()) {
557 return dataFromDerived.right().value();
559 Map<String, MapPropertiesDataDefinition> propertiesAll = dataFromDerived.left().value();
560 Map<String, MapPropertiesDataDefinition> capabiltiesProps = nodeType.getCapabiltiesProperties();
561 if (capabiltiesProps != null) {
562 capabiltiesProps.values().forEach(l -> {
563 if (l.getMapToscaDataDefinition() != null && l.getMapToscaDataDefinition().values() != null) {
564 Collection<PropertyDataDefinition> mapToscaDataDefinition = l.getMapToscaDataDefinition().values();
565 mapToscaDataDefinition.stream().filter(p -> p != null && p.getUniqueId() == null).forEach(p -> {
566 String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
571 ToscaDataDefinition.mergeDataMaps(propertiesAll, capabiltiesProps);
573 if (!propertiesAll.isEmpty()) {
574 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, propertiesAll);
575 if (assosiateElementToData.isRight()) {
576 return assosiateElementToData.right().value();
579 return StorageOperationStatus.OK;
582 public Either<List<GraphVertex>, StorageOperationStatus> findDerivedResources(NodeType nodeType) {
584 List<GraphVertex> derivedResources = new ArrayList<GraphVertex>();
585 List<String> derivedFromResources = nodeType.getDerivedFrom();
586 if (derivedFromResources != null && false == derivedFromResources.isEmpty()) {
588 for (String parentResource : derivedFromResources) {
589 Either<List<GraphVertex>, TitanOperationStatus> getParentResources = derivedResourceResolver.findDerivedResources(parentResource);
590 List<GraphVertex> resources = null;
591 if (getParentResources.isRight()) {
592 log.error("Cannot find parent resource by tosca resource name {} in the graph.", parentResource);
593 return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
596 resources = getParentResources.left().value();
597 if (resources == null || resources.size() == 0) {
598 log.error("Cannot find parent resource by tosca name {} in the graph. resources size is empty", parentResource);
599 return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
601 if (resources.size() > 1) {
602 return handleMultipleParent(parentResource, derivedResources, resources);
604 GraphVertex parentResourceData = resources.get(0);
605 derivedResources.add(parentResourceData);
613 return Either.left(derivedResources);
616 Either<List<GraphVertex>, StorageOperationStatus> handleMultipleParent(String parentResource, List<GraphVertex> derivedResource, List<GraphVertex> fetchedDerivedResources){
618 Either<List<GraphVertex>, StorageOperationStatus> result = Either.left(derivedResource);
620 fetchedDerivedResources.sort((d1,d2)->{
621 return new Double(Double.parseDouble((String)d1.getMetadataProperty(GraphPropertyEnum.VERSION)))
622 .compareTo(Double.parseDouble((String)d2.getMetadataProperty(GraphPropertyEnum.VERSION)));
625 int actualHighestIndex = fetchedDerivedResources.size() - 1;
626 derivedResource.add(fetchedDerivedResources.get(actualHighestIndex));
627 fetchedDerivedResources.remove(actualHighestIndex);
629 StorageOperationStatus status = fixMultipleParent(fetchedDerivedResources);
630 if(status != StorageOperationStatus.OK){
631 result = Either.right(status);
633 } catch (Exception e){
634 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during handle multiple parent {}. Exception is {}",
635 parentResource, e.getMessage());
636 result = Either.right(StorageOperationStatus.GENERAL_ERROR);
641 private StorageOperationStatus fixMultipleParent(List<GraphVertex> fetchedDerivedResources) {
642 StorageOperationStatus result = StorageOperationStatus.OK;
643 for(GraphVertex fetchedDerivedResource : fetchedDerivedResources){
644 fetchedDerivedResource.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
645 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(fetchedDerivedResource);
646 if (updateVertexRes.isRight()) {
647 TitanOperationStatus titatStatus = updateVertexRes.right().value();
648 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set highest version of node type {} to false. Status is {}",
649 fetchedDerivedResource.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME), titatStatus);
650 result = DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus);
657 private GraphVertex fillMetadata(GraphVertex nodeTypeVertex, NodeType nodeType) {
658 nodeTypeVertex.setLabel(VertexTypeEnum.NODE_TYPE);
660 fillCommonMetadata(nodeTypeVertex, nodeType);
662 return nodeTypeVertex;
666 public Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex) {
667 Either<ToscaElement, StorageOperationStatus> nodeType = getToscaElement(toscaElementVertex, new ComponentParametersView());
668 if (nodeType.isRight()) {
669 log.debug("Failed to fetch tosca element {} error {}", toscaElementVertex.getUniqueId(), nodeType.right().value());
672 TitanOperationStatus status = disassociateAndDeleteCommonElements(toscaElementVertex);
673 if (status != TitanOperationStatus.OK) {
674 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
676 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
677 if (status != TitanOperationStatus.OK) {
678 log.debug("Failed to disassociate capabilties for {} error {}", toscaElementVertex.getUniqueId(), status);
679 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
681 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
682 if (status != TitanOperationStatus.OK) {
683 log.debug("Failed to disassociate capabilties properties for {} error {}", toscaElementVertex.getUniqueId(), status);
684 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
686 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
687 if (status != TitanOperationStatus.OK) {
688 log.debug("Failed to disassociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
689 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
691 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
692 if (status != TitanOperationStatus.OK) {
693 log.debug("Failed to disassociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
694 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
696 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INTERFACE_ARTIFACTS);
697 if (status != TitanOperationStatus.OK) {
698 log.debug("Failed to disassociate interface artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
699 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
701 toscaElementVertex.getVertex().remove();
702 log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
707 @SuppressWarnings("unchecked")
709 public Either<NodeType, StorageOperationStatus> createToscaElement(ToscaElement toscaElement) {
710 return createNodeType((NodeType) toscaElement);
714 protected <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement) {
715 return setResourceCategoryFromGraph(vertexComponent, toscaElement);
719 protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV) {
720 return validateResourceCategory(toscaElementToUpdate, elementV);
724 protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV) {
726 NodeType nodeType = (NodeType) toscaElementToUpdate;
727 List<GraphVertex> derivedResources = new ArrayList<>();
729 List<String> derivedFromResources = nodeType.getDerivedFrom();
731 // now supported only single derived from
732 if (derivedFromResources != null && !derivedFromResources.isEmpty() && derivedFromResources.get(0) != null) {
733 String firstDerived = derivedFromResources.get(0);
734 boolean derivedFromGenericType = null != nodeType.getDerivedFromGenericType();
735 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
736 if (childVertex.isRight()) {
737 TitanOperationStatus getchieldError = childVertex.right().value();
738 log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchieldError);
739 return DaoStatusConverter.convertTitanStatusToStorageStatus(getchieldError);
741 GraphVertex firstDerivedInChain = childVertex.left().value();
743 String firstCurrentDerived = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME);
744 if (!firstDerived.equals(firstCurrentDerived) || derivedFromGenericType) {
746 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
747 propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
749 propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, firstDerived);
750 propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
752 Either<List<GraphVertex>, TitanOperationStatus> getParentResources = titanDao.getByCriteria(VertexTypeEnum.NODE_TYPE, propertiesToMatch, JsonParseFlagEnum.NoParse);
754 if (getParentResources.isRight()) {
755 TitanOperationStatus error = getParentResources.right().value();
756 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch derived by criteria {}. error {} ", propertiesToMatch, error);
757 return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
760 GraphVertex newDerived = getParentResources.left().value().get(0);
761 derivedResources.add(newDerived);
762 StorageOperationStatus updateStatus = updateDataFromNewDerived(derivedResources, nodeTypeV, (NodeType)toscaElementToUpdate);
763 if (updateStatus != StorageOperationStatus.OK) {
764 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update data for {} from new derived {} ", nodeTypeV.getUniqueId(), newDerived.getUniqueId(), updateStatus);
768 Either<Edge, TitanOperationStatus> deleteEdge = titanDao.deleteEdge(nodeTypeV, firstDerivedInChain, EdgeLabelEnum.DERIVED_FROM);
769 if (deleteEdge.isRight()) {
770 TitanOperationStatus deleteError = deleteEdge.right().value();
771 log.debug("Failed to disassociate element {} from derived {} , error {}", nodeTypeV.getUniqueId(), firstDerivedInChain.getUniqueId(), deleteError);
772 return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteError);
775 titanDao.createEdge(nodeTypeV, newDerived, EdgeLabelEnum.DERIVED_FROM, new HashMap<>());
779 return StorageOperationStatus.OK;
782 private StorageOperationStatus associateDerivedDataByType(EdgeLabelEnum edgeLabel, GraphVertex nodeTypeV, NodeType nodeToUpdate, List<GraphVertex> newDerived) {
786 return associateCapabilitiesToResource(nodeTypeV, nodeToUpdate, newDerived);
788 return associateRequirementsToResource(nodeTypeV, nodeToUpdate, newDerived);
790 return associatePropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
792 return associateAttributesToResource(nodeTypeV, nodeToUpdate, newDerived);
793 case ADDITIONAL_INFORMATION:
794 return addAdditionalInformationToResource(nodeTypeV, nodeToUpdate, newDerived);
795 case CAPABILITIES_PROPERTIES:
796 return associateCapabilitiesPropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
798 return StorageOperationStatus.OK;
803 private StorageOperationStatus updateDataFromNewDerived(List<GraphVertex> newDerived, GraphVertex nodeTypeV, NodeType nodeToUpdate) {
804 EnumSet<EdgeLabelEnum> edgeLabels = EnumSet.of(EdgeLabelEnum.CAPABILITIES, EdgeLabelEnum.REQUIREMENTS, EdgeLabelEnum.PROPERTIES, EdgeLabelEnum.ATTRIBUTES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.ADDITIONAL_INFORMATION);
805 StorageOperationStatus status = null;
806 for (EdgeLabelEnum edge : edgeLabels){
807 status = updateDataByType(newDerived, nodeTypeV, edge, nodeToUpdate);
808 if (status != StorageOperationStatus.OK) {
816 private <T extends ToscaDataDefinition> StorageOperationStatus updateDataByType(List<GraphVertex> newDerivedList, GraphVertex nodeTypeV, EdgeLabelEnum label, NodeType nodeElement) {
817 log.debug("Update data from derived for element {} type {}", nodeTypeV.getUniqueId(), label);
818 Either<GraphVertex, TitanOperationStatus> dataFromGraph = getDataVertex(nodeTypeV, label);
819 if (dataFromGraph.isRight()) {
820 if (TitanOperationStatus.NOT_FOUND == dataFromGraph.right().value())
821 return associateDerivedDataByType(label, nodeTypeV, nodeElement, newDerivedList);
822 return DaoStatusConverter.convertTitanStatusToStorageStatus(dataFromGraph.right().value());
824 GraphVertex dataV = dataFromGraph.left().value();
826 Map<String, T> mapFromGraph = (Map<String, T>) dataV.getJson();
827 mapFromGraph.entrySet().removeIf(e -> e.getValue().getOwnerId() != null);
830 Either<Map<String, T>, StorageOperationStatus> dataFromDerived = getDataFromDerived(newDerivedList, label);
831 if (dataFromDerived.isRight()) {
832 return dataFromDerived.right().value();
834 Map<String, T> dataFromDerivedAll = dataFromDerived.left().value();
836 Either<Map<String, T>, String> merged = ToscaDataDefinition.mergeDataMaps(dataFromDerivedAll, mapFromGraph);
837 if(merged.isRight()){
838 log.debug("property {} cannot be overriden", merged.right().value());
839 return StorageOperationStatus.INVALID_PROPERTY;
841 dataV.setJson(dataFromDerivedAll);
842 Either<GraphVertex, TitanOperationStatus> updateDataV = updateOrCopyOnUpdate(dataV, nodeTypeV, label);
843 if (updateDataV.isRight()) {
844 return DaoStatusConverter.convertTitanStatusToStorageStatus(updateDataV.right().value());
846 return StorageOperationStatus.OK;
850 public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag) {
851 fillMetadata(elementV, (NodeType) toscaElementToUpdate);