re base code
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / csar / CsarInfo.java
1 package org.openecomp.sdc.be.components.csar;
2
3 import fj.data.Either;
4 import org.apache.commons.collections.CollectionUtils;
5 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
6 import org.openecomp.sdc.be.dao.api.ActionStatus;
7 import org.openecomp.sdc.be.model.NodeTypeInfo;
8 import org.openecomp.sdc.be.model.Resource;
9 import org.openecomp.sdc.be.model.User;
10 import org.openecomp.sdc.be.tosca.CsarUtils;
11 import org.openecomp.sdc.be.utils.TypeUtils;
12 import org.openecomp.sdc.common.api.Constants;
13 import org.openecomp.sdc.common.log.wrappers.Logger;
14 import org.yaml.snakeyaml.Yaml;
15
16 import java.util.*;
17 import java.util.regex.Pattern;
18
19 import static org.openecomp.sdc.be.components.impl.ImportUtils.*;
20
21 public class CsarInfo {
22     private static final Logger log = Logger.getLogger(CsarInfo.class);
23
24     private String vfResourceName;
25     private User modifier;
26     private String csarUUID;
27     private Map<String, byte[]> csar;
28     private String mainTemplateName;
29     private String mainTemplateContent;
30     private Map<String, Object> mappedToscaMainTemplate;
31     private Map<String, String> createdNodesToscaResourceNames;
32     private Queue<String> cvfcToCreateQueue;
33     private boolean isUpdate;
34     private Map<String, Resource> createdNodes;
35
36     @SuppressWarnings("unchecked")
37     public CsarInfo(User modifier, String csarUUID, Map<String, byte[]> csar, String vfResourceName, String mainTemplateName, String mainTemplateContent, boolean isUpdate){
38         this.vfResourceName = vfResourceName;
39         this.modifier = modifier;
40         this.csarUUID = csarUUID;
41         this.csar = csar;
42         this.mainTemplateName = mainTemplateName;
43         this.mainTemplateContent = mainTemplateContent;
44         this.mappedToscaMainTemplate = (Map<String, Object>) new Yaml().load(mainTemplateContent);
45         this.createdNodesToscaResourceNames = new HashMap<>();
46         this.cvfcToCreateQueue = new PriorityQueue<>();
47         this.isUpdate = isUpdate;
48         this.createdNodes  = new HashMap<>();
49     }
50
51     public String getVfResourceName() {
52         return vfResourceName;
53     }
54
55     public void setVfResourceName(String vfResourceName) {
56         this.vfResourceName = vfResourceName;
57     }
58
59     public User getModifier() {
60         return modifier;
61     }
62
63     public void setModifier(User modifier) {
64         this.modifier = modifier;
65     }
66
67     public String getCsarUUID() {
68         return csarUUID;
69     }
70
71     public void setCsarUUID(String csarUUID) {
72         this.csarUUID = csarUUID;
73     }
74
75     public Map<String, byte[]> getCsar() {
76         return csar;
77     }
78
79     public void setCsar(Map<String, byte[]> csar) {
80         this.csar = csar;
81     }
82
83     public Map<String, Object> getMappedToscaMainTemplate() {
84         return mappedToscaMainTemplate;
85     }
86
87     public Map<String, String> getCreatedNodesToscaResourceNames() {
88         return createdNodesToscaResourceNames;
89     }
90
91     public void addNodeToQueue(String nodeName) {
92         if(!cvfcToCreateQueue.contains(nodeName)) {
93             cvfcToCreateQueue.add(nodeName);
94         } else {
95             log.debug("Failed to validate complex VFC {}. Loop detected, VSP {}. ", nodeName,
96                     getVfResourceName());
97             throw new ComponentException(ActionStatus.CFVC_LOOP_DETECTED,
98                     getVfResourceName(), nodeName);
99         }
100     }
101
102     public void removeNodeFromQueue() {
103         cvfcToCreateQueue.remove();
104     }
105
106     public boolean isUpdate() {
107         return isUpdate;
108     }
109
110     public void setUpdate(boolean isUpdate) {
111         this.isUpdate = isUpdate;
112     }
113
114     public Map<String, Resource> getCreatedNodes() {
115         return createdNodes;
116     }
117
118     public Map<String,NodeTypeInfo> extractNodeTypesInfo() {
119         Map<String, NodeTypeInfo> nodeTypesInfo = new HashMap<>();
120         List<Map.Entry<String, byte[]>> globalSubstitutes = new ArrayList<>();
121         for (Map.Entry<String, byte[]> entry : getCsar().entrySet()) {
122             extractNodeTypeInfo(nodeTypesInfo, globalSubstitutes, entry);
123         }
124         if (CollectionUtils.isNotEmpty(globalSubstitutes)) {
125             setDerivedFrom(nodeTypesInfo, globalSubstitutes);
126         }
127         markNestedVfc(getMappedToscaMainTemplate(), nodeTypesInfo);
128         return nodeTypesInfo;
129     }
130
131     @SuppressWarnings("unchecked")
132     private void extractNodeTypeInfo(Map<String, NodeTypeInfo> nodeTypesInfo,
133                                      List<Map.Entry<String, byte[]>> globalSubstitutes, Map.Entry<String, byte[]> entry) {
134         if (Pattern.compile(CsarUtils.SERVICE_TEMPLATE_PATH_PATTERN).matcher(entry.getKey()).matches()) {
135             if (!isGlobalSubstitute(entry.getKey())) {
136                 Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(new String(entry.getValue()));
137                 findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.SUBSTITUTION_MAPPINGS, ToscaElementTypeEnum.MAP)
138                     .right()
139                     .on(sub->handleSubstitutionMappings(nodeTypesInfo, entry, mappedToscaTemplate, (Map<String, Object>)sub));
140             }else {
141                 globalSubstitutes.add(entry);
142             }
143         }
144     }
145
146     private ResultStatusEnum handleSubstitutionMappings(Map<String, NodeTypeInfo> nodeTypesInfo, Map.Entry<String, byte[]> entry, Map<String, Object> mappedToscaTemplate, Map<String, Object> substitutionMappings) {
147         if (substitutionMappings.containsKey(TypeUtils.ToscaTagNamesEnum.NODE_TYPE.getElementName())) {
148             NodeTypeInfo nodeTypeInfo = new NodeTypeInfo();
149             nodeTypeInfo.setType(
150                     (String) substitutionMappings.get(TypeUtils.ToscaTagNamesEnum.NODE_TYPE.getElementName()));
151             nodeTypeInfo.setTemplateFileName(entry.getKey());
152             nodeTypeInfo.setMappedToscaTemplate(mappedToscaTemplate);
153             nodeTypesInfo.put(nodeTypeInfo.getType(), nodeTypeInfo);
154         }
155         return ResultStatusEnum.OK;
156     }
157
158     private boolean isGlobalSubstitute(String fileName) {
159         return fileName.equalsIgnoreCase(Constants.GLOBAL_SUBSTITUTION_TYPES_SERVICE_TEMPLATE)
160                 || fileName.equalsIgnoreCase(Constants.ABSTRACT_SUBSTITUTE_GLOBAL_TYPES_SERVICE_TEMPLATE);
161     }
162
163     @SuppressWarnings("unchecked")
164     private void setDerivedFrom(Map<String, NodeTypeInfo> nodeTypesInfo,
165                                 List<Map.Entry<String, byte[]>> globalSubstitutes) {
166         for (Map.Entry<String, byte[]> entry : globalSubstitutes) {
167             String yamlFileContents = new String(entry.getValue());
168             Map<String, Object> mappedToscaTemplate = (Map<String, Object>) new Yaml().load(yamlFileContents);
169             Either<Object, ResultStatusEnum> nodeTypesEither = findToscaElement(mappedToscaTemplate,
170                     TypeUtils.ToscaTagNamesEnum.NODE_TYPES, ToscaElementTypeEnum.MAP);
171             if (nodeTypesEither.isLeft()) {
172                 Map<String, Object> nodeTypes = (Map<String, Object>) nodeTypesEither.left().value();
173                 for (Map.Entry<String, Object> nodeType : nodeTypes.entrySet()) {
174                     processNodeType(nodeTypesInfo, nodeType);
175                 }
176             }
177         }
178     }
179
180     @SuppressWarnings("unchecked")
181     private void processNodeType(Map<String, NodeTypeInfo> nodeTypesInfo, Map.Entry<String, Object> nodeType) {
182         Map<String, Object> nodeTypeMap = (Map<String, Object>) nodeType.getValue();
183         if (nodeTypeMap.containsKey(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()) && nodeTypesInfo.containsKey(nodeType.getKey())) {
184             NodeTypeInfo nodeTypeInfo = nodeTypesInfo.get(nodeType.getKey());
185             List<String> derivedFrom = new ArrayList<>();
186             derivedFrom.add((String) nodeTypeMap.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()));
187             nodeTypeInfo.setDerivedFrom(derivedFrom);
188         }
189     }
190
191     @SuppressWarnings("unchecked")
192     public static void markNestedVfc(Map<String, Object> mappedToscaTemplate, Map<String, NodeTypeInfo> nodeTypesInfo) {
193         findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TEMPLATES,
194                 ToscaElementTypeEnum.MAP)
195                 .right()
196                 .on(nts-> processNodeTemplates((Map<String, Object>)nts, nodeTypesInfo));
197     }
198
199     @SuppressWarnings("unchecked")
200     private static ResultStatusEnum processNodeTemplates( Map<String, Object> nodeTemplates, Map<String, NodeTypeInfo> nodeTypesInfo) {
201         nodeTemplates.values().forEach(nt->processNodeTemplate(nodeTypesInfo, (Map<String, Object>) nt));
202         return ResultStatusEnum.OK;
203     }
204
205     private static void processNodeTemplate(Map<String, NodeTypeInfo> nodeTypesInfo, Map<String, Object> nodeTemplate) {
206         if (nodeTemplate.containsKey(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName())) {
207             String type = (String) nodeTemplate.get(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName());
208             if (nodeTypesInfo.containsKey(type)) {
209                 NodeTypeInfo nodeTypeInfo = nodeTypesInfo.get(type);
210                 nodeTypeInfo.setNested(true);
211             }
212         }
213     }
214
215     public String getMainTemplateName() {
216         return mainTemplateName;
217     }
218
219     public String getMainTemplateContent() {
220         return mainTemplateContent;
221     }
222 }