1 package org.openecomp.sdc.asdctool.impl.migration.v1707.jsonmodel.relations;
5 import org.apache.commons.lang3.tuple.ImmutablePair;
6 import org.openecomp.sdc.asdctool.impl.migration.MigrationException;
7 import org.openecomp.sdc.asdctool.impl.migration.v1707.MigrationUtils;
8 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
9 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
10 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
11 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
12 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
13 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
14 import org.openecomp.sdc.be.datatypes.elements.MapDataDefinition;
15 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
16 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
17 import org.openecomp.sdc.be.model.Component;
18 import org.openecomp.sdc.be.model.ComponentInstance;
19 import org.openecomp.sdc.be.model.jsontitan.operations.TopologyTemplateOperation;
20 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
21 import org.openecomp.sdc.be.model.operations.api.ToscaDefinitionPathCalculator;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
25 import javax.annotation.Resource;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.List;
30 import java.util.stream.Collectors;
32 import static org.openecomp.sdc.asdctool.impl.migration.MigrationMsg.*;
33 import static org.openecomp.sdc.asdctool.impl.migration.v1707.MigrationUtils.willThrowException;
35 public abstract class FulfilledCapabilityRequirementMigrationService<T extends ToscaDataDefinition, S extends GraphNode> {
37 private static Logger LOGGER = LoggerFactory.getLogger(FulfilledCapabilityRequirementMigrationService.class);
39 @Resource(name = "topology-template-operation")
40 TopologyTemplateOperation topologyTemplateOperation;
42 @Resource(name = "tosca-path-calculator")
43 private ToscaDefinitionPathCalculator toscaDefinitionPathCalculator;
45 @Resource(name = "titan-dao")
48 public boolean associateToscaDefinitions(Component component, NodeTypeEnum componentType) {
50 return isDefinitionsAlreadyAssociated(component) || doAssociateToscaDefinitions(component, componentType);
51 } catch (MigrationException e) {
52 LOGGER.error(e.getMessage(), e);
57 private boolean isDefinitionsAlreadyAssociated(Component component) {
58 GraphVertex componentVertex = titanDao.getVertexById(component.getUniqueId()).left().on((err) -> willThrowException(FAILED_TO_RETRIEVE_VERTEX.getMessage(component.getName(), err.name())));
59 return this.getAssociatedDefinitions(componentVertex)
60 .either(vertex -> true,
61 errorStatus -> notFoundStatusOrFail(component, errorStatus));
65 private boolean notFoundStatusOrFail(Component component, TitanOperationStatus error) {
66 if (error.equals(TitanOperationStatus.NOT_FOUND)) {
69 throw new MigrationException(FAILED_TO_RETRIEVE_CAP_REQ_VERTEX.getMessage(component.getName(), error.name()));
72 private boolean doAssociateToscaDefinitions(Component component, NodeTypeEnum componentType) {
74 Map<String, MapDataDefinition> toscaDefByInstance = groupToscaDefinitionByInstance(component, componentType);
75 return toscaDefByInstance.isEmpty() || updateOnGraph(component, toscaDefByInstance);
76 } catch (MigrationException e) {
77 LOGGER.error(e.getMessage(), e);
82 private Map<String, MapDataDefinition> groupToscaDefinitionByInstance(Component component, NodeTypeEnum componentType) {
83 Map<String, MapDataDefinition> toscaDefByInstance = new HashMap<>();
84 for (ComponentInstance componentInstance : component.getComponentInstances()) {
85 List<ImmutablePair<S, GraphEdge>> fulfilledCapReq = getFulfilledCapReqs(componentType, componentInstance);
86 if (fulfilledCapReq.isEmpty()) {
89 toscaDefByInstance.put(componentInstance.getUniqueId(), getReqCapToscaDefs(fulfilledCapReq, componentInstance));
91 return toscaDefByInstance;
94 private MapDataDefinition getReqCapToscaDefs(List<ImmutablePair<S, GraphEdge>> capReqsData, ComponentInstance componentInstance) {
95 Map<String, List<T>> capReqDefinitions = getCapReqDefinitions(componentInstance, capReqsData);
96 return convertToMapDefinition(capReqDefinitions);
99 private List<ImmutablePair<S, GraphEdge>> getFulfilledCapReqs(NodeTypeEnum componentType, ComponentInstance componentInstance) {
100 return getFulfilledCapReqs(componentInstance, componentType)
101 .either(Function.identity(),
102 error -> emptyListOrFail(error, componentInstance.getName()));
105 private List<ImmutablePair<S, GraphEdge>> emptyListOrFail(TitanOperationStatus error, String instanceName) {
106 if (error.equals(TitanOperationStatus.NOT_FOUND)) {
107 return Collections.emptyList();
109 String errorMsg = FAILED_TO_RETRIEVE_REQ_CAP.getMessage(instanceName, error.name());
110 throw new MigrationException(errorMsg);
113 private Map<String, List<T>> getCapReqDefinitions(ComponentInstance componentInstance, List<ImmutablePair<S, GraphEdge>> capReqDataList) {
114 return capReqDataList.stream()
115 .map(capReqData -> convertToToscaDef(componentInstance, capReqData))
116 .collect(Collectors.groupingBy(this::getType));
119 private T convertToToscaDef(ComponentInstance componentInstance, ImmutablePair<S, GraphEdge> data) {
120 T def = getReqCapDataDefinition(data);
121 List<String> definitionPath = toscaDefinitionPathCalculator.calculateToscaDefinitionPath(componentInstance, data.getRight());
122 setPath(def, definitionPath);
126 private T getReqCapDataDefinition(ImmutablePair<S, GraphEdge> data) {
127 S capReqData = data.getLeft();
128 return getToscaDefinition(capReqData).left().on(err -> willThrowException(FAILED_TO_RETRIEVE_TOSCA_DEF.getMessage(capReqData.getUniqueId().toString(), err.toString())));
131 private boolean updateOnGraph(Component component, Map<String, MapDataDefinition> defsByInstance) {
132 GraphVertex graphVertex = getComponentGraphVertex(component);
133 Either<GraphVertex, StorageOperationStatus> associatedVertex = associateToGraph(graphVertex, defsByInstance);
134 return associatedVertex.either(vertex -> true, err -> MigrationUtils.handleError(FAILED_TO_ASSOCIATE_CAP_REQ.getMessage(component.getName(), err.name())));
137 private GraphVertex getComponentGraphVertex(Component component) {
138 return titanDao.getVertexById(component.getUniqueId())
139 .left().on(error -> willThrowException(FAILED_TO_RETRIEVE_VERTEX.getMessage(component.getUniqueId(), error.name())));
142 private MapDataDefinition convertToMapDefinition(Map<String, List<T>> toscaDefs) {
143 Map<String, ListDataDefinition> defsListByType = toscaDefs.entrySet().stream()
144 .collect(Collectors.toMap(Map.Entry::getKey, entry -> convertToDefinitionListObject(entry.getValue())));
145 return convertToDefinitionMapObject(defsListByType);
148 abstract Either<T, ?> getToscaDefinition(S data);
150 abstract void setPath(T def, List<String> path);
152 abstract String getType(T def);
154 abstract Either<List<ImmutablePair<S, GraphEdge>>, TitanOperationStatus> getFulfilledCapReqs(ComponentInstance instance, NodeTypeEnum nodeTypeEnum);
156 abstract ListDataDefinition convertToDefinitionListObject(List<T> capReqDefList);
158 abstract MapDataDefinition convertToDefinitionMapObject(Map<String, ListDataDefinition> reqCapForInstance);
160 abstract Either<GraphVertex, TitanOperationStatus> getAssociatedDefinitions(GraphVertex component);
162 abstract Either<GraphVertex, StorageOperationStatus> associateToGraph(GraphVertex graphVertex, Map<String, MapDataDefinition> defsByInstance);