[SDC] rebase 1710 code
[sdc.git] / asdctool / src / main / java / org / openecomp / sdc / asdctool / impl / migration / v1707 / jsonmodel / NodeTemplateMissingDataResolver.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.sdc.asdctool.impl.migration.v1707.jsonmodel;
21 import fj.data.Either;
22 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
23 import fj.data.Either;
24 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
25 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
26 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
27 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
28 import org.openecomp.sdc.be.model.*;
29 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
30 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
31 import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
32 import org.openecomp.sdc.be.model.jsontitan.operations.TopologyTemplateOperation;
33 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaElementLifecycleOperation;
34 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
35 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
36 import org.openecomp.sdc.common.api.Constants;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import javax.annotation.Resource;
41 import java.util.ArrayList;
42 import java.util.HashMap;
43 import java.util.*;
44 import java.util.stream.Collectors;
45 import java.util.List;
46 import java.util.Map;
47 import java.util.Optional;
48 import java.util.stream.Collectors;
49
50
51 public class NodeTemplateMissingDataResolver <T extends Component> {
52         
53         private static Logger LOGGER = LoggerFactory.getLogger(NodeTemplateMissingDataResolver.class);
54         
55         @Resource(name = "tosca-element-lifecycle-operation")
56     private ToscaElementLifecycleOperation lifecycleOperation;
57         
58         @Resource(name = "topology-template-operation")
59     public TopologyTemplateOperation topologyTemplateOperation;
60         
61         public void resolveNodeTemplateInfo(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap, T component) {
62                 lifecycleOperation.resolveToscaComponentName(vfInst, origCompMap);
63                 if(OriginTypeEnum.VF == vfInst.getOriginType()) {
64                         collectVFInstanceInputs(component, origCompMap, vfInst);
65                 }
66         }
67
68
69
70
71         public void updateServiceComposition(Component component, Map<String, ToscaElement> origCompMap, Component oldModelService, Map<String, Boolean> updateMap){
72
73                 boolean composition = false;
74                 boolean instInputs = false;
75                 boolean instGroups = false;
76                 List<ComponentInstance> instances = component.getComponentInstances();
77                 if(null != instances) {
78                         for (ComponentInstance instance : instances) {
79                                 composition = composition || lifecycleOperation.resolveToscaComponentName(instance, origCompMap);
80                                 if(OriginTypeEnum.VF == instance.getOriginType()) {
81                                         instInputs = instInputs || collectVFInstanceInputs(component, origCompMap, instance);
82                                         instGroups = instGroups || resolveInstGroupsFromOldTitanGraphAndApplyFix(component, instance, oldModelService);
83                                 }
84                         }
85                 }
86                 updateMap.put(JsonConstantKeysEnum.COMPOSITION.name(), composition);
87                 updateMap.put(EdgeLabelEnum.INST_INPUTS.name(), instInputs);
88                 updateMap.put(EdgeLabelEnum.INST_GROUPS.name(), instGroups);
89         }
90
91
92         public void updateVFComposition(Component component, Map<String, ToscaElement> origCompMap, Map<String, Boolean> updateMap) {
93
94                 boolean composition = false;
95                 boolean groups = fixVFGroups(component);
96                 List<ComponentInstance> instances = component.getComponentInstances();
97                 if(null != instances) {
98                         for (ComponentInstance instance : instances) {
99                                 composition = composition || lifecycleOperation.resolveToscaComponentName(instance, origCompMap);
100                         }
101                 }
102                 updateMap.put(JsonConstantKeysEnum.COMPOSITION.name(), composition);
103                 updateMap.put(EdgeLabelEnum.GROUPS.name(), groups);
104         }
105
106
107
108         private boolean resolveInstGroupsFromOldTitanGraphAndApplyFix(Component component, ComponentInstance instance, Component oldService){
109
110                 boolean res = false;
111                 //info already exists, apply fix if needed
112                 if(null != instance.getGroupInstances() && !instance.getGroupInstances().isEmpty()) {
113                         res = fixVFGroupInstances(component, instance);
114                 //get group instances from old model
115                 }else if(null != oldService){
116                         ComponentInstance origInstance = oldService.getComponentInstances().stream()
117                                         .filter(p -> instance.getUniqueId().equals(p.getUniqueId()))
118                                         .findAny().orElse(null);
119                         if(null != origInstance && null != origInstance.getGroupInstances()) {
120                                 fixVFGroupInstances(oldService, origInstance);
121                                 instance.setGroupInstances(origInstance.getGroupInstances());
122                                 res = true;
123                         }
124                 }
125                 return res;
126         }
127         
128         private boolean collectVFInstanceInputs(Component component, Map<String, ToscaElement> origCompMap, ComponentInstanceDataDefinition vfInst) {
129                 boolean res = false;
130                 String ciUid = vfInst.getUniqueId();
131                 String origCompUid = vfInst.getComponentUid();
132                 if(null == component.getComponentInstancesInputs())
133                         component.setComponentInstancesInputs(new HashMap<>());
134                 Map<String, List<ComponentInstanceInput>> componentInstInputs = component.getComponentInstancesInputs();
135                 Either<ToscaElement, StorageOperationStatus> origComp = fetchToscaElement(origCompMap, vfInst, origCompUid);
136         if(origComp.isRight())
137                 return false;
138                 Map<String, PropertyDataDefinition> origVFInputs = ((TopologyTemplate)origComp.left().value()).getInputs();
139                 if (origVFInputs != null && !origVFInputs.isEmpty()) {
140                         res = true;
141                         Map<String, ComponentInstanceInput> collectedVFInputs = origVFInputs.values().stream()
142                                                                                                                .collect(Collectors.toMap(PropertyDataDefinition::getName, ComponentInstanceInput::new));
143
144                         List<ComponentInstanceInput> instInputList = componentInstInputs.get(ciUid);
145                         Map<String, ComponentInstanceInput> existingInstInputs = ToscaDataDefinition.listToMapByName(instInputList);
146                         collectedVFInputs.putAll(existingInstInputs);
147                         List<ComponentInstanceInput> mergedList = new ArrayList<>(collectedVFInputs.values());
148                         componentInstInputs.put(ciUid, mergedList);
149                 }
150                 return res;
151         }
152
153         private Either<ToscaElement, StorageOperationStatus> fetchToscaElement(Map<String, ToscaElement> origCompMap, ComponentInstanceDataDefinition vfInst, String origCompUid) {
154                 Either<ToscaElement, StorageOperationStatus> origCompEither;
155                 if (!origCompMap.containsKey(origCompUid)) {
156                         origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
157                         if (origCompEither.isRight()) {
158                                   LOGGER.error("failed to fetch Tosca element {} with id {}", vfInst.getComponentName(), origCompUid);
159                                   return origCompEither;                
160                         }
161                         origCompMap.put(origCompUid, origCompEither.left().value());
162                 }
163                 return Either.left(origCompMap.get(origCompUid));
164         }
165         
166         protected boolean isProblematicGroup(GroupDefinition gr, String resourceName, Map<String, ArtifactDefinition> deploymentArtifacts) {
167                 List<String> artifacts = gr.getArtifacts();
168                 List<String> artifactsUuid = gr.getArtifactsUuid();
169
170                 if ((artifactsUuid == null || artifactsUuid.isEmpty()) && (artifacts == null || artifacts.isEmpty())) {
171                         LOGGER.debug("No groups in resource {} ", resourceName);
172                         return false;
173                 }
174                 if (artifacts.size() < artifactsUuid.size()) {
175                         LOGGER.debug(" artifacts.size() < artifactsUuid.size() group {} in resource {} ", gr.getName(), resourceName);
176                         return true;
177                 }
178                 if (artifacts.size() > 0 && (artifactsUuid == null || artifactsUuid.isEmpty())) {
179                         LOGGER.debug(" artifacts.size() > 0 && (artifactsUuid == null || artifactsUuid.isEmpty() group {} in resource {} ", gr.getName(), resourceName);
180                         return true;
181                 }
182                 if (artifactsUuid.contains(null)) {
183                         LOGGER.debug(" artifactsUuid.contains(null) group {} in resource {} ", gr.getName(), resourceName);
184                         return true;
185                 }
186
187                 for (String artifactId : artifacts) {
188                         String artifactlabel = findArtifactLabelFromArtifactId(artifactId);
189                         ArtifactDefinition artifactDefinition = deploymentArtifacts.get(artifactlabel);
190                         if (artifactDefinition == null) {
191                                 LOGGER.debug(" artifactDefinition == null label {} group {} in resource {} ", artifactlabel, gr.getName(), resourceName);
192                                 return true;
193                         }
194                         ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifactDefinition.getArtifactType());
195                         if (artifactType != ArtifactTypeEnum.HEAT_ENV) {
196                                 if (!artifactId.equals(artifactDefinition.getUniqueId())) {
197                                         LOGGER.debug(" !artifactId.equals(artifactDefinition.getUniqueId() artifact {}  artId {} group {} in resource {} ", artifactlabel, artifactId, gr.getName(), resourceName);
198                                         return true;
199                                 }
200                                 if (!artifactsUuid.contains(artifactDefinition.getArtifactUUID())) {
201                                         LOGGER.debug(" artifactsUuid.contains(artifactDefinition.getArtifactUUID() label {} group {} in resource {} ", artifactlabel, gr.getName(), resourceName);
202                                         return true;
203                                 }
204                         }
205                 }
206                 return false;
207         }
208
209         protected boolean isProblematicGroupInstance(GroupInstance gi, String instName, String servicename, Map<String, ArtifactDefinition> deploymentArtifacts) {
210                 List<String> artifacts = gi.getArtifacts();
211                 List<String> artifactsUuid = gi.getArtifactsUuid();
212                 List<String> instArtifactsUuid = gi.getGroupInstanceArtifactsUuid();
213
214                 if ((artifactsUuid == null || artifactsUuid.isEmpty()) && (artifacts == null || artifacts.isEmpty())) {
215                         LOGGER.debug("No instance groups for instance {} in service {} ", instName, servicename);
216                         return false;
217                 }
218                 if (artifacts.size() < artifactsUuid.size()) {
219                         LOGGER.debug(" artifacts.size() < artifactsUuid.size() inst {} in service {} ", instName, servicename);
220                         return true;
221                 }
222                 if (artifacts.size() > 0 && (artifactsUuid == null || artifactsUuid.isEmpty())) {
223                         LOGGER.debug(" artifacts.size() > 0 && (artifactsUuid == null || artifactsUuid.isEmpty() inst {} in service {} ", instName, servicename);
224                         return true;
225                 }
226                 if (artifactsUuid.contains(null)) {
227                         LOGGER.debug(" artifactsUuid.contains(null) inst {} in service {} ", instName, servicename);
228                         return true;
229                 }
230
231                 for (String artifactId : artifacts) {
232                         String artifactlabel = findArtifactLabelFromArtifactId(artifactId);
233                         ArtifactDefinition artifactDefinition = deploymentArtifacts.get(artifactlabel);
234                         if (artifactDefinition == null) {
235                                 LOGGER.debug(" artifactDefinition == null label {} inst {} in service {} ", artifactlabel, instName, servicename);
236                                 return true;
237                         }
238                         ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifactDefinition.getArtifactType());
239                         if (artifactType != ArtifactTypeEnum.HEAT_ENV) {
240                                 if (!artifactId.equals(artifactDefinition.getUniqueId())) {
241                                         LOGGER.debug(" !artifactId.equals(artifactDefinition.getUniqueId() artifact {}  artId {} inst {} in service {} ", artifactlabel, artifactId, instName, servicename);
242                                         return true;
243                                 }
244                                 if (!artifactsUuid.contains(artifactDefinition.getArtifactUUID())) {
245                                         LOGGER.debug(" artifactsUuid.contains(artifactDefinition.getArtifactUUID() label {} inst {} in service {} ", artifactlabel, instName, servicename);
246                                         return true;
247                                 }
248                         } else {
249                                 if (!instArtifactsUuid.contains(artifactDefinition.getArtifactUUID())) {
250                                         LOGGER.debug(" instArtifactsUuid.contains(artifactDefinition.getArtifactUUID() label {} inst {} in service {} ", artifactlabel, instName, servicename);
251                                         return true;
252                                 }
253                         }
254                 }
255                 return false;
256         }
257         
258         private String findArtifactLabelFromArtifactId(String artifactId) {
259                 String artifactLabel = "";
260
261                 int index = artifactId.lastIndexOf(".");
262                 if (index > 0 && index + 1 < artifactId.length())
263                         artifactLabel = artifactId.substring(index + 1);
264                 return artifactLabel;
265         }
266         
267         public boolean fixVFGroups(Component component){
268                 boolean res = false;
269
270                 Map<String, ArtifactDefinition> deploymentArtifacts = component.getDeploymentArtifacts();
271                 List<GroupDefinition> groups = component.getGroups();
272                 if (groups == null || groups.isEmpty()) {
273                         LOGGER.debug("No groups in component {} id {} ",  component.getName(), component.getUniqueId());
274                         return res;
275                 }       
276                                 
277                 for (GroupDefinition group : groups) {
278                         if (group.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE) && deploymentArtifacts != null) {
279                                 if (isProblematicGroup(group, component.getName(), deploymentArtifacts)) {
280                                         res = true;
281                                         List<String> groupArtifacts = null == group.getArtifacts()? new ArrayList<>() : new ArrayList<>(group.getArtifacts());
282                                         group.setArtifacts(new ArrayList<>());
283                                         group.setArtifactsUuid(new ArrayList<>());
284                                         for (String artifactId : groupArtifacts) {
285                                                 String artifactlabel = findArtifactLabelFromArtifactId(artifactId);
286                                                 LOGGER.debug("fix group:  group name {} artifactId for fix {} artifactlabel {} ", group.getName(), artifactId, artifactlabel);
287                                                 if (!artifactlabel.isEmpty() && deploymentArtifacts.containsKey(artifactlabel)) {
288                                                         ArtifactDefinition artifact = deploymentArtifacts.get(artifactlabel);
289                                                         String correctArtifactId = artifact.getUniqueId();
290                                                         String correctArtifactUUID = artifact.getArtifactUUID();
291                                                         LOGGER.debug(" fix group:  group name {} correct artifactId {} artifactUUID {} ", group.getName(), correctArtifactId, correctArtifactUUID);
292                                                         group.getArtifacts().add(correctArtifactId);
293                                                         if (correctArtifactUUID != null && !correctArtifactUUID.isEmpty()) {
294                                                                 group.getArtifactsUuid().add(correctArtifactUUID);
295                                                         }
296                                                 }
297                                         }
298                                 }
299                         }
300                 }
301                 return res;
302         }
303         
304         public boolean fixVFGroupInstances(Component component, ComponentInstance instance){
305                 boolean res = false;
306                 
307                 Map<String, ArtifactDefinition> deploymentArtifacts = instance.getDeploymentArtifacts();
308                 List<GroupInstance> groupInstances = instance.getGroupInstances();
309                 if (groupInstances == null || groupInstances.isEmpty()) {
310                         LOGGER.debug("No instance groups for instance {} in service {} id {} ", instance.getName(), component.getName(), component.getUniqueId());
311                         return res;
312                 }               
313                 for (GroupInstance group : groupInstances) {
314                         if (group.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE)) {
315                                 if (isProblematicGroupInstance(group, instance.getName(), component.getName(), deploymentArtifacts)) {
316                                         res = true;
317                                         LOGGER.debug("Migration1707ArtifactUuidFix fix group: resource id {}, group name {} ", component.getUniqueId(), group.getName());
318                                         List<String> groupArtifacts = null == group.getArtifacts()? new ArrayList<>() : new ArrayList<>(group.getArtifacts());
319                                         group.setArtifacts(new ArrayList<>());
320                                         group.setArtifactsUuid(new ArrayList<>());
321                                         group.setGroupInstanceArtifacts(new ArrayList<>());
322                                         group.setGroupInstanceArtifactsUuid(new ArrayList<>());
323
324                                         for (String artifactId : groupArtifacts) {
325                                                 String artifactlabel = findArtifactLabelFromArtifactId(artifactId);
326                                                 LOGGER.debug("Migration1707ArtifactUuidFix  fix group:  group name {} artifactId for fix {} artifactlabel {} ", group.getName(), artifactId, artifactlabel);
327                                                 if (!artifactlabel.isEmpty() && deploymentArtifacts.containsKey(artifactlabel)) {
328                                                         ArtifactDefinition artifact = deploymentArtifacts.get(artifactlabel);
329                                                         ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifact.getArtifactType());
330                                                         String correctArtifactId = artifact.getUniqueId();
331                                                         String correctArtifactUUID = artifact.getArtifactUUID();
332                                                         if (artifactType != ArtifactTypeEnum.HEAT_ENV) {
333
334                                                                 LOGGER.debug("Migration1707ArtifactUuidFix  fix group:  group name {} correct artifactId {} artifactUUID {} ", group.getName(), correctArtifactId, correctArtifactUUID);
335                                                                 group.getArtifacts().add(correctArtifactId);
336                                                                 if (correctArtifactUUID != null && !correctArtifactUUID.isEmpty()) {
337                                                                         group.getArtifactsUuid().add(correctArtifactUUID);
338                                                                 }
339                                                         } else {
340                                                                 LOGGER.debug("Migration1707ArtifactUuidFix  fix group:  group name {} correct artifactId {} artifactUUID {} ", group.getName(), correctArtifactId, correctArtifactUUID);
341                                                                 group.getGroupInstanceArtifacts().add(correctArtifactId);
342                                                                 if (correctArtifactUUID != null && !correctArtifactUUID.isEmpty()) {
343                                                                         group.getGroupInstanceArtifactsUuid().add(correctArtifactUUID);
344                                                                 }
345                                                         }
346                                                 }
347                                         }
348                                 }
349                         }
350                 }
351                 return res;
352         }
353 }