2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2018 Ericsson. All rights reserved.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.distribution.reception.decoding.pdpx;
23 import java.util.ArrayList;
24 import java.util.List;
26 import java.util.HashMap;
27 import java.util.regex.Matcher;
28 import java.util.regex.Pattern;
29 import com.google.gson.Gson;
30 import com.google.gson.GsonBuilder;
31 import com.google.gson.reflect.TypeToken;
33 import org.onap.policy.common.logging.flexlogger.FlexLogger;
34 import org.onap.policy.common.logging.flexlogger.Logger;
35 import org.onap.policy.distribution.reception.decoding.PolicyDecodingException;
36 import org.onap.sdc.tosca.parser.api.ISdcCsarHelper;
37 import org.onap.sdc.toscaparser.api.CapabilityAssignment;
38 import org.onap.sdc.toscaparser.api.CapabilityAssignments;
39 import org.onap.sdc.toscaparser.api.NodeTemplate;
40 import org.onap.sdc.toscaparser.api.RequirementAssignment;
41 import org.onap.sdc.toscaparser.api.elements.Metadata;
44 * Extract concerned info from NodeTemplate, currently ONLY HPA Feature.
46 * @author Libo Zhu (libo.zhu@intel.com)
48 public class ExtractFromNode {
50 private static final Logger LOGGER = FlexLogger.getLogger(ExtractFromNode.class);
51 private static final String VDU_TYPE = "tosca.nodes.nfv.Vdu.Compute";
52 private static final String VDU_CP_TYPE = "tosca.nodes.nfv.VduCp";
53 private static final String VIRTUAL_MEM_SIZE_PATH = "virtual_memory#virtual_mem_size";
54 private static final String NUM_VIRTUAL_CPU_PATH = "virtual_cpu#num_virtual_cpu";
55 private static final String CPU_ARCHITECTURE_PATH = "virtual_cpu#cpu_architecture";
56 private static final String MEMORY_PAGE_SIZE_PATH = "virtual_memory#vdu_memory_requirements#memoryPageSize";
57 private static final String NETWORK_INTERFACE_TYPE_PATH =
58 "virtual_network_interface_requirements#network_interface_requirements#interfaceType";
59 private static final String NETWORK_PCI_PATH =
60 "virtual_network_interface_requirements#nic_io_requirements";
61 private static final String BASIC_CAPABILITIES_HPA_FEATURE = "BasicCapabilities";
62 private static final String HUGE_PAGES_HPA_FEATURE = "hugePages";
63 private static final Map<String, String> NETWORK_HPA_FEATURE_MAP = new HashMap() {{
64 put("SR-IOV", "SriovNICNetwork");
65 put("PCI-Passthrough", "pciePassthrough");
68 ISdcCsarHelper sdcCsarHelper;
69 final Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().disableHtmlEscaping().create();
71 public void setSdcCsarHelper(final ISdcCsarHelper sdcCsarHelper) {
72 this.sdcCsarHelper = sdcCsarHelper;
76 * ExtractInfo from VNF , each VNF may includes more than one VDUs and CPs return new generated
77 * PdpxPolicy if it has got Hpa feature info or else return null.
79 * @param node the NodeTemplate
81 * @return the extracted info from input node
83 * @throws PolicyDecodingException if extract fails
85 public Content extractInfo(final NodeTemplate node) throws PolicyDecodingException {
87 LOGGER.debug("the meta data of this nodetemplate = " + sdcCsarHelper.getNodeTemplateMetadata(node));
88 final List<NodeTemplate> lnodeChild = sdcCsarHelper.getNodeTemplateChildren(node);
89 LOGGER.debug("the size of lnodeChild = " + lnodeChild.size());
91 // Store all the VDUs under one VNF
92 final List<NodeTemplate> lnodeVdu = new ArrayList<>();
93 // Store all the Cps under one VNF
94 final List<NodeTemplate> lnodeVduCp = new ArrayList<>();
95 for (final NodeTemplate nodeChild : lnodeChild) {
96 final String type = sdcCsarHelper.getTypeOfNodeTemplate(nodeChild);
97 LOGGER.debug("the type of this nodeChild = " + type);
98 LOGGER.debug("the meta data of this nodetemplate = " + sdcCsarHelper.getNodeTemplateMetadata(nodeChild));
99 if (type.equalsIgnoreCase(VDU_TYPE)) {
100 lnodeVdu.add(nodeChild);
101 } else if (type.equalsIgnoreCase(VDU_CP_TYPE)) {
102 lnodeVduCp.add(nodeChild);
105 LOGGER.debug("the size of vdu is =" + lnodeVdu.size());
106 LOGGER.debug("the size of cp is =" + lnodeVduCp.size());
108 final Content content = new Content();
109 extractInfoVdu(lnodeVdu, content);
110 extractInfoVduCp(lnodeVduCp, content);
111 if (content.getFlavorFeatures().isEmpty()) {
120 * ExtractInfofromVdu, supported hpa features, All under the capability of
121 * tosca.nodes.nfv.Vdu.Compute.
123 * @param lnodeVdu the list of Vdu node
125 * @param content to be change based on lnodeVdu
127 public void extractInfoVdu(final List<NodeTemplate> lnodeVdu, final Content content) {
128 // each VDU <=> FlavorFeature
129 for (final NodeTemplate node : lnodeVdu) {
130 final Attribute flavorAttribute = new Attribute();
131 flavorAttribute.setAttributeName("flavorName");
132 flavorAttribute.setAttributeValue("");
133 final Directive flavorDirective = new Directive();
134 flavorDirective.setType("flavor_directive");
135 flavorDirective.getAttributes().add(flavorAttribute);
136 final FlavorFeature flavorFeature = new FlavorFeature();
137 flavorFeature.setId(sdcCsarHelper.getNodeTemplatePropertyLeafValue(node, "name"));
138 flavorFeature.getDirectives().add(flavorDirective);
140 final CapabilityAssignments capabilityAssignments = sdcCsarHelper.getCapabilitiesOf(node);
141 final CapabilityAssignment capabilityAssignment =
142 capabilityAssignments.getCapabilityByName("virtual_compute");
143 if (capabilityAssignment != null) {
144 generateBasicCapability(capabilityAssignment, flavorFeature);
145 generateHugePages(capabilityAssignment,flavorFeature);
147 content.getFlavorFeatures().add(flavorFeature);
152 * GenerateBasicCapability, supported hpa features, All under the capability of
153 * tosca.nodes.nfv.Vdu.Compute.
155 * @param capabilityAssignment represents the capability of node
157 * @param flavorFeature represents all the features of specified flavor
159 private void generateBasicCapability(final CapabilityAssignment capabilityAssignment, FlavorFeature flavorFeature){
160 //the format is xxx MB/GB like 4096 MB
161 String virtualMemSize = sdcCsarHelper.getCapabilityPropertyLeafValue(capabilityAssignment,
162 VIRTUAL_MEM_SIZE_PATH);
163 if (virtualMemSize != null) {
164 LOGGER.debug("the virtualMemSize = " + virtualMemSize);
165 HpaFeatureAttribute hpaFeatureAttribute = generateHpaFeatureAttribute("virtualMemSize", virtualMemSize);
166 FlavorProperty flavorProperty = new FlavorProperty();
167 flavorProperty.setHpaFeature(BASIC_CAPABILITIES_HPA_FEATURE);
168 flavorProperty.getHpaFeatureAttributes().add(hpaFeatureAttribute);
169 flavorFeature.getFlavorProperties().add(flavorProperty);
172 //the format is int like 2
173 String numVirtualCpu = sdcCsarHelper.getCapabilityPropertyLeafValue(capabilityAssignment,
174 NUM_VIRTUAL_CPU_PATH);
175 if (numVirtualCpu != null) {
176 LOGGER.debug("the numVirtualCpu = " + numVirtualCpu);
177 HpaFeatureAttribute hpaFeatureAttribute = generateHpaFeatureAttribute("numVirtualCpu", numVirtualCpu);
178 String cpuArchitecture = sdcCsarHelper.getCapabilityPropertyLeafValue
179 (capabilityAssignment,CPU_ARCHITECTURE_PATH);
180 FlavorProperty flavorProperty = new FlavorProperty();
181 flavorProperty.setHpaFeature(BASIC_CAPABILITIES_HPA_FEATURE);
182 if (cpuArchitecture != null) {
183 flavorProperty.setArchitecture(cpuArchitecture);
185 flavorProperty.getHpaFeatureAttributes().add(hpaFeatureAttribute);
186 flavorFeature.getFlavorProperties().add(flavorProperty);
191 * GenerateHpaFeatureAttribute based on the value of featureValue. the format:
192 * "hpa-attribute-key": "pciVendorId", "hpa-attribute-value": "1234", "operator": "=", "unit":
195 * @param hpaAttributeKey get from the high layer tosca DM
197 * @param featureValue get from the high layer tosca DM
200 private HpaFeatureAttribute generateHpaFeatureAttribute(final String hpaAttributeKey, final String featureValue) {
201 //based on input featureValue, return back a suitable hpaFeatureAttribute
202 final HpaFeatureAttribute hpaFeatureAttribute = new HpaFeatureAttribute();
203 hpaFeatureAttribute.setHpaAttributeKey(hpaAttributeKey);
204 final String tmp = featureValue.replace(" ", "");
205 final String pattern = "(\\D*)(\\d+)(\\D*)";
206 final Pattern r = Pattern.compile(pattern);
207 final Matcher m = r.matcher(tmp);
209 LOGGER.debug("operator = " + m.group(1));
210 LOGGER.debug("value = " + m.group(2));
211 LOGGER.debug("unit = " + m.group(3));
212 hpaFeatureAttribute.setOperator(m.group(1));
213 hpaFeatureAttribute.setHpaAttributeValue(m.group(2));
214 hpaFeatureAttribute.setUnit(m.group(3));
216 return hpaFeatureAttribute;
220 * GenerateHugePages, supported hpa features, All under the capability of
221 * tosca.nodes.nfv.Vdu.Compute. The format is a map like: {"schema-version": "0",
222 * "schema-location": "", "platform-id": "generic", "mandatory": true, "configuration-value": "2
225 * @param capabilityAssignment represents the capability of node
227 * @param flavorFeature represents all the features of specified flavor
229 private void generateHugePages(final CapabilityAssignment capabilityAssignment, FlavorFeature flavorFeature){
230 String memoryPageSize = sdcCsarHelper.getCapabilityPropertyLeafValue(capabilityAssignment,
231 MEMORY_PAGE_SIZE_PATH);
232 LOGGER.debug("the memoryPageSize = " + memoryPageSize);
233 if (memoryPageSize != null) {
234 Map<String, Object> retMap = gson.fromJson(memoryPageSize,
235 new TypeToken<HashMap<String, Object>>() {}.getType());
236 LOGGER.debug("the retMap = " + retMap);
237 String memoryPageSizeValue = retMap.get("configuration-value").toString();
238 String mandatory = retMap.get("mandatory").toString();
239 HpaFeatureAttribute hpaFeatureAttribute =
240 generateHpaFeatureAttribute("memoryPageSize",memoryPageSizeValue);
241 FlavorProperty flavorProperty = new FlavorProperty();
242 flavorProperty.setHpaFeature(HUGE_PAGES_HPA_FEATURE);
243 if (mandatory != null) {
244 flavorProperty.setMandatory(mandatory);
246 flavorProperty.getHpaFeatureAttributes().add(hpaFeatureAttribute);
247 flavorFeature.getFlavorProperties().add(flavorProperty);
252 * ExtractInfoVduCp, supported hpa features, under the virtual_network_interface_requirements of
253 * tosca.nodes.nfv.VduCp.
255 * @param lnodeVduCp the list of VduCp node
257 * @param content to be change based on lnodeVduCp
258 * @throws PolicyDecodingException if extract CP fails
260 public void extractInfoVduCp(final List<NodeTemplate> lnodeVduCp, Content content) throws PolicyDecodingException {
261 // each CP will binds to a VDU so need the vdu flavor map info.
262 Map<String, FlavorFeature> vduFlavorMap = new HashMap<>();
263 for ( FlavorFeature flavorFeature: content.getFlavorFeatures()) {
264 LOGGER.debug("the id = " + flavorFeature.getId());
265 vduFlavorMap.put(flavorFeature.getId(),flavorFeature);
267 for ( NodeTemplate node : lnodeVduCp) {
268 String interfaceType = sdcCsarHelper.getNodeTemplatePropertyLeafValue(node,NETWORK_INTERFACE_TYPE_PATH);
269 LOGGER.debug("the interfaceType = " + interfaceType);
270 Map<String, Object> retMap = new HashMap<>();
271 if (interfaceType != null) {
272 retMap = gson.fromJson(interfaceType, new TypeToken<HashMap<String, Object>>() {}.getType());
273 LOGGER.debug("the retMap = " + retMap);
276 String networkHpaFeature;
277 if ( retMap.containsKey("configuration-value")) {
278 String interfaceTypeValue = retMap.get("configuration-value").toString();
279 LOGGER.debug(" the interfacetype value is =" + interfaceTypeValue);
280 if ( NETWORK_HPA_FEATURE_MAP.containsKey(interfaceTypeValue)) {
281 networkHpaFeature = NETWORK_HPA_FEATURE_MAP.get(interfaceTypeValue);
282 LOGGER.debug(" the networkHpaFeature is =" + networkHpaFeature);
284 LOGGER.debug(" unspported network interface ");
288 LOGGER.debug(" no configuration-value defined in interfaceType");
292 for (RequirementAssignment requriement: sdcCsarHelper.getRequirementsOf(node).getAll()) {
293 String nodeTemplateName = requriement.getNodeTemplateName().toLowerCase();
294 LOGGER.debug("getNodeTemplateName =" + nodeTemplateName);
295 if ( nodeTemplateName == null) {
298 if (!vduFlavorMap.containsKey(nodeTemplateName)) {
299 throw new PolicyDecodingException("vdu Flavor Map should contains the key " + nodeTemplateName);
301 generateNetworkFeature(networkHpaFeature, node, vduFlavorMap.get(nodeTemplateName));
307 * GenerateNetworkFeature, all pci feature are grouped into FlavorFeature together.
309 * @param networkHpaFeature represents the specified Hpa feature
310 * @param node represents the CP Node
311 * @param flavorFeature represents all the features of specified flavor
313 private void generateNetworkFeature(final String networkHpaFeature, final NodeTemplate node, FlavorFeature flavorFeature) {
314 //the format is a map like: {"schema-version": "0", "schema-location": "", "platform-id": "generic",
315 // "mandatory": true, "configuration-value": "2 MB"}
316 FlavorProperty flavorProperty = new FlavorProperty();
317 flavorProperty.setHpaFeature(networkHpaFeature);
318 String[] pciKeys = { "pciVendorId", "pciDeviceId", "pciNumDevices", "physicalNetwork"};
319 for (String pciKey: pciKeys) {
320 LOGGER.debug("the pciKey = " + pciKey);
321 String pciKeyPath = NETWORK_PCI_PATH + "#" + pciKey;
322 String pciValue = sdcCsarHelper.getNodeTemplatePropertyLeafValue(node,pciKeyPath);
323 if (pciValue != null) {
324 LOGGER.debug("the pciValue = " + pciValue);
325 Map<String, Object> retMap = gson.fromJson(pciValue, new TypeToken<HashMap<String, Object>>() {}.getType());
326 String pciConfigValue = retMap.get("configuration-value").toString();
327 HpaFeatureAttribute hpaFeatureAttribute = generateHpaFeatureAttribute(pciKey,pciConfigValue);
328 flavorProperty.getHpaFeatureAttributes().add(hpaFeatureAttribute);
331 flavorFeature.getFlavorProperties().add(flavorProperty);