Fixed SONAR issues
[sdc.git] / openecomp-be / lib / openecomp-heat-lib / src / main / java / org / openecomp / sdc / heat / services / tree / HeatTreeManager.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
21 package org.openecomp.sdc.heat.services.tree;
22
23 import org.openecomp.core.utilities.file.FileContentHandler;
24 import org.openecomp.core.utilities.file.FileUtils;
25 import org.openecomp.core.utilities.json.JsonUtil;
26 import org.openecomp.core.validation.types.GlobalValidationContext;
27 import org.openecomp.sdc.common.utils.SdcCommon;
28 import org.openecomp.sdc.datatypes.error.ErrorMessage;
29 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
30 import org.openecomp.sdc.heat.datatypes.manifest.ManifestContent;
31 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
32 import org.openecomp.sdc.heat.datatypes.structure.Artifact;
33 import org.openecomp.sdc.heat.datatypes.structure.HeatStructureTree;
34 import org.openecomp.sdc.logging.api.Logger;
35 import org.openecomp.sdc.logging.api.LoggerFactory;
36 import org.openecomp.sdc.tosca.services.YamlUtil;
37
38 import java.io.InputStream;
39 import java.util.HashMap;
40 import java.util.HashSet;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Objects;
44 import java.util.Set;
45
46
47 public class HeatTreeManager {
48
49   private static Logger logger = (Logger) LoggerFactory.getLogger(HeatTreeManager.class);
50
51
52   private FileContentHandler heatContentMap = new FileContentHandler();
53   private byte[] manifest;
54   private HeatStructureTree tree = new HeatStructureTree();
55   private Map<String, HeatStructureTree> fileTreeRef = new HashMap<>();
56   private Map<String, Artifact> artifactRef = new HashMap<>();
57   private Map<String, Artifact> candidateOrphanArtifacts = new HashMap<>();
58   private Map<String, HeatStructureTree> nestedFiles = new HashMap<>();
59   private Map<HeatStructureTree, HeatStructureTree> volumeFileToParent = new HashMap<>();
60   private Map<HeatStructureTree, HeatStructureTree> networkFileToParent = new HashMap<>();
61   private Set<String> manifestFiles = new HashSet<>();
62
63   /**
64    * Add file.
65    *
66    * @param fileName the file name
67    * @param content  the content
68    */
69   public void addFile(String fileName, InputStream content) {
70     if (fileName.equals(SdcCommon.MANIFEST_NAME)) {
71       manifest = FileUtils.toByteArray(content);
72
73     } else {
74       heatContentMap.addFile(fileName, content);
75     }
76   }
77
78   /**
79    * Create tree.
80    */
81   public void createTree() {
82     if (manifest == null) {
83       logger.error("Missing manifest file in the zip.");
84       return;
85     }
86     ManifestContent manifestData =
87         JsonUtil.json2Object(new String(manifest), ManifestContent.class);
88     scanTree(null, manifestData.getData());
89     addNonNestedVolumeNetworkToTree(volumeFileToParent, nestedFiles.keySet(), true);
90     addNonNestedVolumeNetworkToTree(networkFileToParent, nestedFiles.keySet(), false);
91     handleOrphans();
92
93     tree = fileTreeRef.get(SdcCommon.PARENT);
94   }
95
96   private void handleOrphans() {
97     tree = fileTreeRef.get(SdcCommon.PARENT);
98     candidateOrphanArtifacts.entrySet().stream()
99         .forEach(entry -> tree.addArtifactToArtifactList(entry.getValue()));
100     nestedFiles
101         .values().stream().filter(heatStructureTree -> tree.getHeat().contains(heatStructureTree))
102         .forEach(heatStructureTree -> tree.getHeat().remove(heatStructureTree));
103
104     heatContentMap.getFileList().stream().filter(fileName -> isNotInManifestFiles(fileName))
105         .forEach(fileName -> addTreeOther(fileName));
106   }
107
108   private boolean isNotInManifestFiles(String fileName) {
109     return !manifestFiles.contains(fileName);
110   }
111
112   private void addTreeOther(String fileName) {
113     if (tree.getOther() == null) {
114       tree.setOther(new HashSet<>());
115     }
116     HeatStructureTree other = new HeatStructureTree(fileName, false);
117     fileTreeRef.put(fileName, other);
118     tree.getOther().add(other);
119   }
120
121
122   private void handleHeatContentReference(String filename, HeatStructureTree fileHeatStructureTree,
123                                           GlobalValidationContext globalContext) {
124
125     String fileName = fileHeatStructureTree.getFileName();
126     InputStream fileContent = this.heatContentMap.getFileContent(fileName);
127     if (fileContent == null) {
128       return; // file exist in manifest but does not exist in zip
129     }
130     try {
131       HeatOrchestrationTemplate hot =
132           new YamlUtil().yamlToObject(fileContent, HeatOrchestrationTemplate.class);
133
134       Set<String> nestedSet = HeatTreeManagerUtil.getNestedFiles(filename, hot, globalContext);
135       addHeatNestedFiles(fileHeatStructureTree, nestedSet);
136
137       Set<String> artifactSet = HeatTreeManagerUtil.getArtifactFiles(filename, hot, globalContext);
138       addHeatArtifactFiles(fileHeatStructureTree, artifactSet);
139     } catch (Exception ignore) { /* invalid yaml no need to process reference */
140       logger.debug("",ignore);
141     }
142   }
143
144
145   private void addHeatArtifactFiles(HeatStructureTree fileHeatStructureTree,
146                                     Set<String> artifactSet) {
147     Artifact artifact;
148     for (String artifactName : artifactSet) {
149       FileData.Type type =
150           candidateOrphanArtifacts.get(artifactName) != null ? candidateOrphanArtifacts
151               .get(artifactName).getType() : null;
152       artifact = new Artifact(artifactName, type);
153       artifactRef.put(artifactName, artifact);
154       candidateOrphanArtifacts.remove(artifactName);
155       fileHeatStructureTree.addArtifactToArtifactList(artifact);
156     }
157   }
158
159
160   private void addHeatNestedFiles(HeatStructureTree fileHeatStructureTree, Set<String> nestedSet) {
161     HeatStructureTree childHeatStructureTree;
162     for (String nestedName : nestedSet) {
163       childHeatStructureTree = fileTreeRef.get(nestedName);
164       if (childHeatStructureTree == null) {
165         childHeatStructureTree = new HeatStructureTree();
166         childHeatStructureTree.setFileName(nestedName);
167         fileTreeRef.put(nestedName, childHeatStructureTree);
168       }
169       fileHeatStructureTree.addHeatStructureTreeToNestedHeatList(childHeatStructureTree);
170       nestedFiles.put(childHeatStructureTree.getFileName(), childHeatStructureTree);
171     }
172   }
173
174
175   /**
176    * Add errors.
177    *
178    * @param validationErrors the validation errors
179    */
180   public void addErrors(Map<String, List<ErrorMessage>> validationErrors) {
181
182     validationErrors.entrySet().stream().filter(entry -> {
183       return fileTreeRef.get(entry.getKey()) != null;
184     }).forEach(entry -> entry.getValue().stream().forEach(error ->
185         fileTreeRef.get(entry.getKey()).addErrorToErrorsList(error)));
186
187     validationErrors.entrySet().stream().filter(entry -> {
188       return artifactRef.get(entry.getKey()) != null;
189     }).forEach(entry -> artifactRef.get(entry.getKey()).setErrors(entry.getValue()));
190
191   }
192
193   /**
194    * Scan tree.
195    *
196    * @param parent the parent
197    * @param data   the data
198    */
199   public void scanTree(String parent, List<FileData> data) {
200     String fileName;
201     FileData.Type type;
202     HeatStructureTree parentHeatStructureTree;
203     HeatStructureTree fileHeatStructureTree;
204     HeatStructureTree childHeatStructureTree;
205     Artifact artifact;
206     if (parent == null) {
207       parentHeatStructureTree = new HeatStructureTree();
208       fileTreeRef.put(SdcCommon.PARENT, parentHeatStructureTree);
209     } else {
210       parentHeatStructureTree = fileTreeRef.get(parent);
211     }
212
213     for (FileData fileData : data) {
214       fileName = fileData.getFile();
215       manifestFiles.add(fileName);
216       type = fileData.getType();
217
218       if (Objects.nonNull(type) && FileData.Type.HEAT.equals(type)) {
219         fileHeatStructureTree = fileTreeRef.get(fileName);
220         if (fileHeatStructureTree == null) {
221           fileHeatStructureTree = new HeatStructureTree();
222           fileTreeRef.put(fileName, fileHeatStructureTree);
223         }
224         fileHeatStructureTree.setFileName(fileName);
225         fileHeatStructureTree.setBase(fileData.getBase());
226         fileHeatStructureTree.setType(type);
227         handleHeatContentReference(null, fileHeatStructureTree, null);
228         parentHeatStructureTree.addHeatToHeatList(fileHeatStructureTree);
229         if (fileData.getData() != null) {
230           scanTree(fileName, fileData.getData());
231         }
232       } else {
233         childHeatStructureTree = new HeatStructureTree();
234         childHeatStructureTree.setFileName(fileName);
235         childHeatStructureTree.setBase(fileData.getBase());
236         childHeatStructureTree.setType(type);
237         fileTreeRef.put(childHeatStructureTree.getFileName(), childHeatStructureTree);
238
239         if (type == null) {
240           parentHeatStructureTree.addOtherToOtherList(childHeatStructureTree);
241         } else if (FileData.Type.HEAT_NET.equals(type)) {
242           //parentHeatStructureTree.addNetworkToNetworkList(childHeatStructureTree);
243           networkFileToParent.put(childHeatStructureTree, parentHeatStructureTree);
244           if (fileData.getData() != null) {
245             scanTree(fileName, fileData.getData());
246           }
247
248         } else if (FileData.Type.HEAT_VOL.equals(type)) {
249           //parentHeatStructureTree.addVolumeFileToVolumeList(childHeatStructureTree);
250           volumeFileToParent.put(childHeatStructureTree, parentHeatStructureTree);
251           if (fileData.getData() != null) {
252             scanTree(fileName, fileData.getData());
253           }
254         } else if (FileData.Type.HEAT_ENV.equals(type)) {
255           if (parentHeatStructureTree != null && parentHeatStructureTree.getFileName() != null) {
256             parentHeatStructureTree.setEnv(childHeatStructureTree);
257           } else {
258             if (parentHeatStructureTree.getOther() == null) {
259               parentHeatStructureTree.setOther(new HashSet<>());
260             }
261             parentHeatStructureTree.getOther().add(childHeatStructureTree);
262           }
263         } else {
264           artifact = new Artifact(fileName, type);
265           if (!artifactRef.keySet().contains(fileName)) {
266             artifactRef.put(fileName, artifact);
267             candidateOrphanArtifacts.put(fileName, artifact);
268           }
269         }
270       }
271     }
272   }
273
274
275   private void addNonNestedVolumeNetworkToTree(
276       Map<HeatStructureTree, HeatStructureTree> netVolToParent, Set<String> nestedFileNames,
277       boolean isVolume) {
278     for (Map.Entry<HeatStructureTree, HeatStructureTree> entry : netVolToParent.entrySet()) {
279       HeatStructureTree netOrVolNode = entry.getKey();
280       HeatStructureTree parent = entry.getValue();
281       if (!nestedFileNames.contains(netOrVolNode.getFileName())) {
282         if (isVolume) {
283           parent.addVolumeFileToVolumeList(netOrVolNode);
284         } else {
285           parent.addNetworkToNetworkList(netOrVolNode);
286         }
287       }
288     }
289   }
290
291
292   public HeatStructureTree getTree() {
293     return tree;
294   }
295 }