[SDC] rebase 1710 code
[sdc.git] / asdctool / src / main / java / org / openecomp / sdc / asdctool / impl / migration / v1707 / Migration1707MissingInfoFix.java
1 package org.openecomp.sdc.asdctool.impl.migration.v1707;
2
3 import fj.data.Either;
4 import org.openecomp.sdc.asdctool.impl.migration.v1707.jsonmodel.NodeTemplateMissingDataResolver;
5 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
6 import org.openecomp.sdc.be.dao.jsongraph.TitanDao;
7 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
8 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
9 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
10 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
11 import org.openecomp.sdc.be.datatypes.elements.*;
12 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
13 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
14 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
15 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
16 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
17 import org.openecomp.sdc.be.model.*;
18 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
19 import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
20 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
21 import org.openecomp.sdc.be.model.operations.api.IServiceOperation;
22 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 import javax.annotation.Resource;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.function.Predicate;
32 import java.util.stream.Collectors;
33
34 @org.springframework.stereotype.Component("migration1707MissingInfoFix")
35 public class Migration1707MissingInfoFix {
36
37     private static final Logger LOGGER = LoggerFactory.getLogger(Migration1707MissingInfoFix.class);
38
39     @Resource(name = "service-operation")
40     private IServiceOperation serviceOperation;
41
42     @Resource(name = "node-template-missing-data-resolver")
43     private NodeTemplateMissingDataResolver nodeTemplateMissingDataResolver;
44
45     @Resource(name = "tosca-operation-facade")
46     private ToscaOperationFacade toscaOperations;
47
48     @Resource(name = "titan-dao")
49     private TitanDao titanDao;
50
51
52     public boolean migrate(){
53         boolean res = updateVFs();
54         if(res)
55             res = updateServices();
56         return res;
57     }
58
59     private ComponentParametersView getFilter() {
60         ComponentParametersView filter = new ComponentParametersView(true);
61         filter.setIgnoreComponentInstances(false);
62         filter.setIgnoreArtifacts(false);
63         filter.setIgnoreGroups(false);
64         filter.setIgnoreComponentInstancesInputs(false);
65         return filter;
66     }
67
68     // if new service has VF instances with no groups - try to fetch them from old graph
69     private boolean oldServiceModelRequired(Component newService) {
70         Predicate<ComponentInstance> vfInstanceWithNoGroups = p -> OriginTypeEnum.VF == p.getOriginType() && (null == p.getGroupInstances() || p.getGroupInstances().isEmpty());
71         return null != newService.getComponentInstances() && newService.getComponentInstances().stream()
72                 .anyMatch(vfInstanceWithNoGroups);
73     }
74
75
76
77     private List<GraphVertex> fetchVertices(Map<GraphPropertyEnum, Object> hasProps){
78         Either<List<GraphVertex>, TitanOperationStatus> componentsByCriteria = titanDao.getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, hasProps, JsonParseFlagEnum.ParseAll);
79         if (componentsByCriteria.isRight()) {
80             LOGGER.debug("couldn't fetch assets from sdctitan");
81             return null;
82         }
83         return componentsByCriteria.left().value();
84     }
85
86     private boolean updateVFs() {
87
88         boolean res = true;
89         Map<GraphPropertyEnum, Object> hasProps = new HashMap<>();
90         hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.RESOURCE.name());
91         hasProps.put(GraphPropertyEnum.RESOURCE_TYPE, ResourceTypeEnum.VF.name());
92
93         List<GraphVertex> resources = fetchVertices(hasProps);
94         if(null == resources)
95             return false;
96         ComponentParametersView filter = getFilter();
97         Map<String, ToscaElement> origCompMap = new HashMap<>();
98
99         for (GraphVertex gv : resources) {
100             boolean fixed = true;
101             Either<Component, StorageOperationStatus> toscaElement = toscaOperations.getToscaElement(gv.getUniqueId(), filter);
102             if (toscaElement.isRight()) {
103                 LOGGER.debug("Failed to fetch resource {} {}", gv.getUniqueId(), toscaElement.right().value());
104                 return false;
105             }
106             Component resource = toscaElement.left().value();
107             Map<String, Boolean> updateMap = new HashMap<>();
108             nodeTemplateMissingDataResolver.updateVFComposition(resource, origCompMap, updateMap);
109             if(updateMap.get(JsonConstantKeysEnum.COMPOSITION.name())){
110                 LOGGER.info("applying instance tosca name fix on VF {}", gv.getUniqueId());
111                 fixed = toscaOperations.updateComponentInstanceMetadataOfTopologyTemplate(resource).isLeft();
112             }
113             if(updateMap.get(EdgeLabelEnum.GROUPS.name())) {
114                 List<GroupDataDefinition> groups = new ArrayList<>(resource.getGroups());
115                 LOGGER.info("applying groups vertex fix on VF {}", gv.getUniqueId());
116                 fixed = fixed && toscaOperations.updateGroupsOnComponent(resource, ComponentTypeEnum.RESOURCE, groups).isLeft();
117             }
118
119             res = res && fixed;
120             titanDao.commit();
121         }
122         return res;
123     }
124
125     private Map<String, MapPropertiesDataDefinition> buildInstancesInputsMap(Component component){
126         Map<String, MapPropertiesDataDefinition> instanceInputsMap = new HashMap<>();
127         for (Map.Entry<String, List<ComponentInstanceInput>> entry : component.getComponentInstancesInputs().entrySet()) {
128             MapPropertiesDataDefinition inputsMap = new MapPropertiesDataDefinition();
129             inputsMap.setMapToscaDataDefinition(entry.getValue().stream().map(e -> new PropertyDataDefinition(e)).collect(Collectors.toMap(e -> e.getName(), e -> e)));
130             instanceInputsMap.put(entry.getKey(), inputsMap);
131         }
132         return instanceInputsMap;
133     }
134
135
136
137     private Map<String, MapGroupsDataDefinition> buildGroupInstanceMap(Component component) {
138         Map<String, MapGroupsDataDefinition> instGroupsMap = new HashMap<>();
139         for (ComponentInstance instance : component.getComponentInstances()) {
140             if (instance.getGroupInstances() != null) {
141                 MapGroupsDataDefinition groupsMap = new MapGroupsDataDefinition();
142                 groupsMap.setMapToscaDataDefinition(instance.getGroupInstances().stream().map(e -> new GroupInstanceDataDefinition(e)).collect(Collectors.toMap(e -> e.getName(), e -> e)));
143                 instGroupsMap.put(instance.getUniqueId(), groupsMap);
144             }
145         }
146         return instGroupsMap;
147     }
148
149     private <T extends ToscaDataDefinition> boolean updateDataVertex(GraphVertex componentVertex, VertexTypeEnum vertexType, EdgeLabelEnum edgeLabel, Map<String, T> dataMap){
150         Either<GraphVertex, TitanOperationStatus> dataVertexEither = titanDao.getChildVertex(componentVertex, edgeLabel, JsonParseFlagEnum.ParseJson);
151         if (dataVertexEither.isRight()) {
152             if(TitanOperationStatus.NOT_FOUND != dataVertexEither.right().value())
153                 return false;
154             return (nodeTemplateMissingDataResolver.topologyTemplateOperation.assosiateElementToData(componentVertex, vertexType, edgeLabel, dataMap)).isLeft();
155         }
156         GraphVertex dataVertex = dataVertexEither.left().value();
157         dataVertex.setJson(dataMap);
158         return (titanDao.updateVertex(dataVertex)).isLeft();
159
160     }
161
162
163     private boolean updateServices(){
164
165         boolean res = true;
166         Map<GraphPropertyEnum, Object> hasProps = new HashMap<>();
167         hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name());
168
169         List<GraphVertex> componentsByCriteria = fetchVertices(hasProps);
170         if(null == componentsByCriteria)
171             return false;
172
173         ComponentParametersView filter = getFilter();
174         Map<String, ToscaElement> origCompMap = new HashMap<>();
175
176         Predicate<ComponentInstance> containsGroupInstances = p -> null != p.getGroupInstances() && !p.getGroupInstances().isEmpty();
177
178         for (GraphVertex gv : componentsByCriteria) {
179
180             boolean fixed = true;
181             Either<org.openecomp.sdc.be.model.Service, StorageOperationStatus> toscaElement = toscaOperations.getToscaElement(gv.getUniqueId(), filter);
182             if (toscaElement.isRight()) {
183                 LOGGER.debug("Failed to fetch service {} {}", gv.getUniqueId(), toscaElement.right().value());
184                 return false;
185             }
186             Component service = toscaElement.left().value();
187             Component oldService = null;
188
189             if(oldServiceModelRequired(service)){
190                 Either<Service, StorageOperationStatus> oldServiceEither = serviceOperation.getService(gv.getUniqueId(), filter, false);
191                 if (oldServiceEither.isRight()){
192                     LOGGER.debug("couldn't fetch service {} from old titan", gv.getUniqueId());
193                 }else {
194                     oldService = oldServiceEither.left().value();
195                     oldService = oldService.getComponentInstances().stream().anyMatch(containsGroupInstances) ? oldService : null;
196                 }
197             }
198
199             Map<String, Boolean> updateMap = new HashMap<>();
200             nodeTemplateMissingDataResolver.updateServiceComposition(service, origCompMap, oldService, updateMap);
201             if(updateMap.get(JsonConstantKeysEnum.COMPOSITION.name())) {
202                 LOGGER.info("applying instance tosca name fix on service {}", gv.getUniqueId());
203                 fixed = (toscaOperations.updateComponentInstanceMetadataOfTopologyTemplate(service)).isLeft();
204             }
205             if(updateMap.get(EdgeLabelEnum.INST_GROUPS.name())) {
206                 Map<String, MapGroupsDataDefinition> groupsMap = buildGroupInstanceMap(service);
207                 LOGGER.info("applying groups instances vertex fix on service {}", gv.getUniqueId());
208                 fixed = fixed && updateDataVertex(gv, VertexTypeEnum.INST_GROUPS, EdgeLabelEnum.INST_GROUPS, groupsMap);
209             }
210             if(updateMap.get(EdgeLabelEnum.INST_INPUTS.name())) {
211                 Map<String, MapPropertiesDataDefinition> instInputs = buildInstancesInputsMap(service);
212                 LOGGER.info("applying instances inputs vertex fix on service {}", gv.getUniqueId());
213                 fixed = fixed && updateDataVertex(gv, VertexTypeEnum.INST_INPUTS, EdgeLabelEnum.INST_INPUTS, instInputs);
214             }
215             res = res && fixed;
216             titanDao.commit();
217         }
218         return res;
219     }
220 }