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.Collection;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.List;
35 import java.util.Optional;
36 import java.util.PriorityQueue;
37 import java.util.Queue;
39 import java.util.stream.Stream;
42 import org.apache.commons.collections.MapUtils;
43 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
44 import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum;
45 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
46 import org.openecomp.sdc.be.config.NonManoArtifactType;
47 import org.openecomp.sdc.be.config.NonManoConfiguration;
48 import org.openecomp.sdc.be.config.NonManoConfigurationManager;
49 import org.openecomp.sdc.be.config.NonManoFolderType;
50 import org.openecomp.sdc.be.dao.api.ActionStatus;
51 import org.openecomp.sdc.be.model.NodeTypeInfo;
52 import org.openecomp.sdc.be.model.Resource;
53 import org.openecomp.sdc.be.model.User;
54 import org.openecomp.sdc.be.utils.TypeUtils;
55 import org.openecomp.sdc.common.api.Constants;
56 import org.openecomp.sdc.common.log.wrappers.Logger;
57 import org.yaml.snakeyaml.Yaml;
60 * Provides access to the contents of a CSAR
62 public abstract class CsarInfo {
64 private static final Logger log = Logger.getLogger(CsarInfo.class);
65 private final NonManoConfiguration nonManoConfiguration;
68 private String vfResourceName;
71 private User modifier;
74 private String csarUUID;
76 private String csarVersionId;
79 protected Map<String, byte[]> csar;
81 private String mainTemplateName;
83 private String mainTemplateContent;
85 protected Map<String, Object> mappedToscaMainTemplate;
87 private Map<String, String> createdNodesToscaResourceNames;
88 private Queue<String> cvfcToCreateQueue;
89 private boolean isUpdate;
91 private Map<String, Resource> createdNodes;
92 protected Map<String, Object> artifacttypeDefinitions;
93 private Map<String, Object> policytypeDefinitions;
95 protected CsarInfo(User modifier, String csarUUID, Map<String, byte[]> csar, String vfResourceName, String mainTemplateName,
96 String mainTemplateContent, boolean isUpdate) {
97 this.vfResourceName = vfResourceName;
98 this.modifier = modifier;
99 this.csarUUID = csarUUID;
101 this.mainTemplateName = mainTemplateName;
102 this.mainTemplateContent = mainTemplateContent;
103 this.mappedToscaMainTemplate = new Yaml().load(mainTemplateContent);
104 this.createdNodesToscaResourceNames = new HashMap<>();
105 this.cvfcToCreateQueue = new PriorityQueue<>();
106 this.isUpdate = isUpdate;
107 this.createdNodes = new HashMap<>();
108 this.nonManoConfiguration = NonManoConfigurationManager.getInstance().getNonManoConfiguration();
111 public String getVfResourceName() {
112 return vfResourceName;
115 protected CsarInfo(final User modifier, final String csarUUID, final String csarVersionId, final Map<String, byte[]> csarContent,
116 final String vfResourceName, final String mainTemplateName, final String mainTemplateContent, final boolean isUpdate) {
117 this(modifier, csarUUID, csarContent, vfResourceName, mainTemplateName, mainTemplateContent, isUpdate);
118 this.csarVersionId = csarVersionId;
122 CsarInfo(final NonManoConfiguration nonManoConfiguration) {
123 this.nonManoConfiguration = nonManoConfiguration;
126 @SuppressWarnings("unchecked")
127 public static void markNestedVfc(Map<String, Object> mappedToscaTemplate, Map<String, NodeTypeInfo> nodeTypesInfo) {
128 findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TEMPLATES, ToscaElementTypeEnum.MAP).right()
129 .on(nts -> processNodeTemplates((Map<String, Object>) nts, nodeTypesInfo));
132 @SuppressWarnings("unchecked")
133 private static ResultStatusEnum processNodeTemplates(Map<String, Object> nodeTemplates, Map<String, NodeTypeInfo> nodeTypesInfo) {
134 nodeTemplates.values().forEach(nt -> processNodeTemplate(nodeTypesInfo, (Map<String, Object>) nt));
135 return ResultStatusEnum.OK;
138 private static void processNodeTemplate(Map<String, NodeTypeInfo> nodeTypesInfo, Map<String, Object> nodeTemplate) {
139 if (nodeTemplate.containsKey(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName())) {
140 String type = (String) nodeTemplate.get(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName());
141 if (nodeTypesInfo.containsKey(type)) {
142 NodeTypeInfo nodeTypeInfo = nodeTypesInfo.get(type);
143 if (nodeTypeInfo.isSubstitutionMapping() && type.contains(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX)) {
144 nodeTypeInfo.setNested(true);
150 public void addNodeToQueue(String nodeName) {
151 if (!cvfcToCreateQueue.contains(nodeName)) {
152 cvfcToCreateQueue.add(nodeName);
154 log.debug("Failed to validate complex VFC {}. Loop detected, VSP {}. ", nodeName, getVfResourceName());
155 throw new ByActionStatusComponentException(ActionStatus.CFVC_LOOP_DETECTED, getVfResourceName(), nodeName);
159 public void removeNodeFromQueue() {
160 cvfcToCreateQueue.remove();
163 public boolean isUpdate() {
167 public void setUpdate(boolean isUpdate) {
168 this.isUpdate = isUpdate;
171 public abstract Map<String, NodeTypeInfo> extractTypesInfo();
174 * Get the data types defined in the CSAR
176 * @return map with the data type name as key and representaion of the data type defintion as value
178 public abstract Map<String, Object> getDataTypes();
180 public abstract Map<String, Object> getGroupTypes();
182 public abstract Map<String, Object> getCapabilityTypes();
184 public abstract Map<String, Object> getArtifactTypes();
186 public Map<String, Object> getPolicyTypes() {
187 if (policytypeDefinitions == null) {
188 policytypeDefinitions = new HashMap<>();
189 policytypeDefinitions.putAll(getTypesFromTemplate(mappedToscaMainTemplate, TypeUtils.ToscaTagNamesEnum.POLICY_TYPES));
191 return policytypeDefinitions;
194 @SuppressWarnings("unchecked")
195 protected Map<String, Object> getTypesFromTemplate(final Map<String, Object> mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum type) {
196 final Either<Object, ResultStatusEnum> dataTypesEither = findToscaElement(mappedToscaTemplate, type, ToscaElementTypeEnum.MAP);
197 if (dataTypesEither != null && dataTypesEither.isLeft()) {
198 return (Map<String, Object>) dataTypesEither.left().value();
200 return Collections.emptyMap();
203 @SuppressWarnings("unchecked")
204 protected Map<String, Object> getTypesFromTemplate(final Map<String, Object> mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum type,
205 Collection<String> names) {
206 Map<String, Object> allTypes = getTypesFromTemplate(mappedToscaTemplate, type);
208 final Map<String, Object> typesToReturn = new HashMap<>();
209 final Stream<Map.Entry<String, Object>> requestedTypes = allTypes.entrySet().stream().filter(entry -> names.contains(entry.getKey()));
211 requestedTypes.forEach(requestedType -> typesToReturn.put(requestedType.getKey(), requestedType.getValue()));
213 return typesToReturn;
216 protected Set<String> findNodeTypesUsedInNodeTemplates(final Map<String, Map<String, Object>> nodeTemplates) {
217 final Set<String> nodeTypes = new HashSet<>();
218 for (final Map<String, Object> nodeTemplate : nodeTemplates.values()) {
219 nodeTypes.add((String) nodeTemplate.get(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName()));
224 @SuppressWarnings("unchecked")
225 protected NodeTypeInfo buildNodeTypeInfo(final Map.Entry<String, Object> nodeType, final String templateFileName,
226 final Map<String, Object> mappedToscaTemplate) {
227 final NodeTypeInfo nodeTypeInfo = new NodeTypeInfo();
228 nodeTypeInfo.setSubstitutionMapping(false);
229 nodeTypeInfo.setNested(true);
230 nodeTypeInfo.setType(nodeType.getKey());
231 nodeTypeInfo.setTemplateFileName(templateFileName);
232 nodeTypeInfo.setMappedToscaTemplate(buildToscaTemplateForNode(nodeType.getKey(), mappedToscaTemplate));
233 final Map<String, Object> nodeTypeMap = (Map<String, Object>) nodeType.getValue();
234 final List<String> derivedFrom = new ArrayList<>();
235 derivedFrom.add((String) nodeTypeMap.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName()));
236 nodeTypeInfo.setDerivedFrom(derivedFrom);
240 @SuppressWarnings("unchecked")
241 private Map<String, Object> buildToscaTemplateForNode(final String nodeTypeName, final Map<String, Object> mappedToscaTemplate) {
242 final Map<String, Object> mappedToscaTemplateforNode = new HashMap<>(mappedToscaTemplate);
243 final Either<Object, ResultStatusEnum> nodeTypesEither = findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES,
244 ToscaElementTypeEnum.MAP);
245 final Map<String, Object> nodeTypes = new HashMap<>();
246 if (nodeTypesEither.isLeft()) {
247 final Map<String, Object> allNodeTypes = (Map<String, Object>) nodeTypesEither.left().value();
248 nodeTypes.put(nodeTypeName, allNodeTypes.get(nodeTypeName));
250 mappedToscaTemplateforNode.put(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName(), nodeTypes);
251 return mappedToscaTemplateforNode;
255 * Gets the software information yaml path from the csar file map.
257 * @return the software information yaml path if it is present in the csar file map
259 public Optional<String> getSoftwareInformationPath() {
260 if (MapUtils.isEmpty(csar)) {
261 return Optional.empty();
263 final NonManoFolderType softwareInformationType = nonManoConfiguration.getNonManoType(NonManoArtifactType.ONAP_SW_INFORMATION);
264 return csar.keySet().stream().filter(filePath -> filePath.startsWith(softwareInformationType.getPath())).findFirst();