2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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 * Modifications copyright (c) 2019 Nokia
20 * ================================================================================
22 package org.openecomp.sdc.be.components.csar;
24 import static org.openecomp.sdc.be.components.impl.ImportUtils.findToscaElement;
26 import com.google.common.annotations.VisibleForTesting;
27 import fj.data.Either;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.HashMap;
31 import java.util.HashSet;
32 import java.util.List;
34 import java.util.Optional;
35 import java.util.PriorityQueue;
36 import java.util.Queue;
40 import org.apache.commons.collections.MapUtils;
41 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
42 import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum;
43 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
44 import org.openecomp.sdc.be.config.NonManoArtifactType;
45 import org.openecomp.sdc.be.config.NonManoConfiguration;
46 import org.openecomp.sdc.be.config.NonManoConfigurationManager;
47 import org.openecomp.sdc.be.config.NonManoFolderType;
48 import org.openecomp.sdc.be.dao.api.ActionStatus;
49 import org.openecomp.sdc.be.model.NodeTypeInfo;
50 import org.openecomp.sdc.be.model.Resource;
51 import org.openecomp.sdc.be.model.User;
52 import org.openecomp.sdc.be.utils.TypeUtils;
53 import org.openecomp.sdc.common.api.Constants;
54 import org.openecomp.sdc.common.log.wrappers.Logger;
55 import org.yaml.snakeyaml.Yaml;
58 * Provides access to the contents of a CSAR
60 public abstract class CsarInfo {
62 private static final Logger log = Logger.getLogger(CsarInfo.class);
63 private final NonManoConfiguration nonManoConfiguration;
66 private String vfResourceName;
69 private User modifier;
72 private String csarUUID;
74 private String csarVersionId;
77 protected Map<String, byte[]> csar;
79 private String mainTemplateName;
81 private String mainTemplateContent;
83 protected Map<String, Object> mappedToscaMainTemplate;
85 private Map<String, String> createdNodesToscaResourceNames;
86 private Queue<String> cvfcToCreateQueue;
87 private boolean isUpdate;
89 private Map<String, Resource> createdNodes;
90 protected Map<String, Object> datatypeDefinitions;
91 private Map<String, Object> policytypeDefinitions;
94 public CsarInfo(User modifier, String csarUUID, Map<String, byte[]> csar, String vfResourceName, String mainTemplateName,
95 String mainTemplateContent, boolean isUpdate) {
96 this.vfResourceName = vfResourceName;
97 this.modifier = modifier;
98 this.csarUUID = csarUUID;
100 this.mainTemplateName = mainTemplateName;
101 this.mainTemplateContent = mainTemplateContent;
102 this.mappedToscaMainTemplate = new Yaml().load(mainTemplateContent);
103 this.createdNodesToscaResourceNames = new HashMap<>();
104 this.cvfcToCreateQueue = new PriorityQueue<>();
105 this.isUpdate = isUpdate;
106 this.createdNodes = new HashMap<>();
107 this.nonManoConfiguration = NonManoConfigurationManager.getInstance().getNonManoConfiguration();
110 public String getVfResourceName() {
111 return vfResourceName;
114 public CsarInfo(final User modifier, final String csarUUID, final String csarVersionId, final Map<String, byte[]> csarContent,
115 final String vfResourceName, final String mainTemplateName, final String mainTemplateContent, final boolean isUpdate) {
116 this(modifier, csarUUID, csarContent, vfResourceName, mainTemplateName, mainTemplateContent, isUpdate);
117 this.csarVersionId = csarVersionId;
121 CsarInfo(final NonManoConfiguration nonManoConfiguration) {
122 this.nonManoConfiguration = nonManoConfiguration;
125 @SuppressWarnings("unchecked")
126 public static void markNestedVfc(Map<String, Object> mappedToscaTemplate, Map<String, NodeTypeInfo> nodeTypesInfo) {
127 findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TEMPLATES, ToscaElementTypeEnum.MAP).right()
128 .on(nts -> processNodeTemplates((Map<String, Object>) nts, nodeTypesInfo));
131 @SuppressWarnings("unchecked")
132 private static ResultStatusEnum processNodeTemplates(Map<String, Object> nodeTemplates, Map<String, NodeTypeInfo> nodeTypesInfo) {
133 nodeTemplates.values().forEach(nt -> processNodeTemplate(nodeTypesInfo, (Map<String, Object>) nt));
134 return ResultStatusEnum.OK;
137 private static void processNodeTemplate(Map<String, NodeTypeInfo> nodeTypesInfo, Map<String, Object> nodeTemplate) {
138 if (nodeTemplate.containsKey(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName())) {
139 String type = (String) nodeTemplate.get(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName());
140 if (nodeTypesInfo.containsKey(type)) {
141 NodeTypeInfo nodeTypeInfo = nodeTypesInfo.get(type);
142 if (nodeTypeInfo.isSubstitutionMapping() && type.contains(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX)) {
143 nodeTypeInfo.setNested(true);
149 public void addNodeToQueue(String nodeName) {
150 if (!cvfcToCreateQueue.contains(nodeName)) {
151 cvfcToCreateQueue.add(nodeName);
153 log.debug("Failed to validate complex VFC {}. Loop detected, VSP {}. ", nodeName, getVfResourceName());
154 throw new ByActionStatusComponentException(ActionStatus.CFVC_LOOP_DETECTED, getVfResourceName(), nodeName);
158 public void removeNodeFromQueue() {
159 cvfcToCreateQueue.remove();
162 public boolean isUpdate() {
166 public void setUpdate(boolean isUpdate) {
167 this.isUpdate = isUpdate;
170 public abstract Map<String, NodeTypeInfo> extractTypesInfo();
173 * Get the data types defined in the CSAR
175 * @return map with the data type name as key and representaion of the data type defintion as value
177 public abstract Map<String, Object> getDataTypes();
179 public Map<String, Object> getPolicyTypes() {
180 if (policytypeDefinitions == null) {
181 policytypeDefinitions = new HashMap<>();
182 policytypeDefinitions.putAll(getTypesFromTemplate(mappedToscaMainTemplate, TypeUtils.ToscaTagNamesEnum.POLICY_TYPES));
184 return policytypeDefinitions;
187 @SuppressWarnings("unchecked")
188 protected Map<String, Object> getTypesFromTemplate(final Map<String, Object> mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum type) {
189 final Either<Object, ResultStatusEnum> dataTypesEither = findToscaElement(mappedToscaTemplate, type,
190 ToscaElementTypeEnum.MAP);
191 if (dataTypesEither != null && dataTypesEither.isLeft()) {
192 return (Map<String, Object>) dataTypesEither.left().value();
194 return Collections.emptyMap();
197 protected Set<String> findNodeTypesUsedInNodeTemplates(final Map<String, Map<String, Object>> nodeTemplates) {
198 final Set<String> nodeTypes = new HashSet<>();
199 for (final Map<String, Object> nodeTemplate : nodeTemplates.values()) {
200 nodeTypes.add((String) nodeTemplate.get(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName()));
205 @SuppressWarnings("unchecked")
206 protected NodeTypeInfo buildNodeTypeInfo(final Map.Entry<String, Object> nodeType, final String templateFileName,
207 final Map<String, Object> mappedToscaTemplate) {
208 final NodeTypeInfo nodeTypeInfo = new NodeTypeInfo();
209 nodeTypeInfo.setSubstitutionMapping(false);
210 nodeTypeInfo.setNested(true);
211 nodeTypeInfo.setType(nodeType.getKey());
212 nodeTypeInfo.setTemplateFileName(templateFileName);
213 nodeTypeInfo.setMappedToscaTemplate(buildToscaTemplateForNode(nodeType.getKey(), mappedToscaTemplate));
214 final Map<String, Object> nodeTypeMap = (Map<String, Object>) nodeType.getValue();
215 final List<String> derivedFrom = new ArrayList<>();
216 derivedFrom.add((String) nodeTypeMap.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()));
217 nodeTypeInfo.setDerivedFrom(derivedFrom);
221 @SuppressWarnings("unchecked")
222 private Map<String, Object> buildToscaTemplateForNode(final String nodeTypeName, final Map<String, Object> mappedToscaTemplate) {
223 final Map<String, Object> mappedToscaTemplateforNode = new HashMap<>(mappedToscaTemplate);
224 final Either<Object, ResultStatusEnum> nodeTypesEither = findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES,
225 ToscaElementTypeEnum.MAP);
226 final Map<String, Object> nodeTypes = new HashMap<>();
227 if (nodeTypesEither.isLeft()) {
228 final Map<String, Object> allNodeTypes = (Map<String, Object>) nodeTypesEither.left().value();
229 nodeTypes.put(nodeTypeName, allNodeTypes.get(nodeTypeName));
231 mappedToscaTemplateforNode.put(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName(), nodeTypes);
232 return mappedToscaTemplateforNode;
236 * Gets the software information yaml path from the csar file map.
238 * @return the software information yaml path if it is present in the csar file map
240 public Optional<String> getSoftwareInformationPath() {
241 if (MapUtils.isEmpty(csar)) {
242 return Optional.empty();
244 final NonManoFolderType softwareInformationType = nonManoConfiguration.getNonManoType(NonManoArtifactType.ONAP_SW_INFORMATION);
245 return csar.keySet().stream().filter(filePath -> filePath.startsWith(softwareInformationType.getPath())).findFirst();