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 com.google.common.collect.ImmutableMap;
 
  24 import com.google.gson.Gson;
 
  25 import com.google.gson.GsonBuilder;
 
  26 import com.google.gson.reflect.TypeToken;
 
  27 import java.util.ArrayList;
 
  28 import java.util.HashMap;
 
  29 import java.util.List;
 
  31 import java.util.regex.Matcher;
 
  32 import java.util.regex.Pattern;
 
  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.RequirementAssignments;
 
  42 import org.onap.sdc.toscaparser.api.elements.Metadata;
 
  45  * Extract concerned info from NodeTemplate, currently ONLY HPA Feature.
 
  47  * @author Libo Zhu (libo.zhu@intel.com)
 
  49 public class ExtractFromNode {
 
  51     private static final String CONFIGURATION_VALUE = "configurationValue";
 
  52     private static final Logger LOGGER = FlexLogger.getLogger(ExtractFromNode.class);
 
  53     private static final String VDU_TYPE = "tosca.nodes.nfv.Vdu.Compute";
 
  54     private static final String VDU_CP_TYPE = "tosca.nodes.nfv.VduCp";
 
  55     private static final String VIRTUAL_MEM_SIZE_PATH = "virtual_memory#virtual_mem_size";
 
  56     private static final String NUM_VIRTUAL_CPU_PATH = "virtual_cpu#num_virtual_cpu";
 
  57     private static final String CPU_ARCHITECTURE_PATH = "virtual_cpu#cpu_architecture";
 
  58     private static final String MEMORY_PAGE_SIZE_PATH = "virtual_memory#vdu_memory_requirements#memoryPageSize";
 
  59     private static final String NETWORK_INTERFACE_TYPE_PATH =
 
  60             "virtual_network_interface_requirements#network_interface_requirements#interfaceType";
 
  61     private static final String NETWORK_PCI_PATH = 
 
  62             "virtual_network_interface_requirements#nic_io_requirements#logical_node_requirements";
 
  63     private static final String BASIC_CAPABILITIES_HPA_FEATURE = "BasicCapabilities";
 
  64     private static final String HUGE_PAGES_HPA_FEATURE = "hugePages";
 
  65     private static final Map<String, String> NETWORK_HPA_FEATURE_MAP =
 
  66             ImmutableMap.of("SR-IOV", "SriovNICNetwork", "PCI-Passthrough", "pciePassthrough");
 
  68     private 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 PdpxPolicy if it has
 
  77      * 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 {
 
  86         Metadata metaData = sdcCsarHelper.getNodeTemplateMetadata(node);
 
  87         LOGGER.debug("the meta data of this nodetemplate = " + metaData);
 
  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 nodeChild = " + 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         content.setResources(metaData.getValue("name"));
 
 110         content.setIdentity(content.getPolicyType() + "_" + content.getResources());
 
 111         extractInfoVdu(lnodeVdu, content);
 
 112         extractInfoVduCp(lnodeVduCp, content);
 
 113         if (content.getFlavorFeatures().isEmpty()) {
 
 121      * ExtractInfofromVdu, supported hpa features, All under the capability of 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_directives");
 
 135             flavorDirective.getAttributes().add(flavorAttribute);
 
 136             final FlavorFeature flavorFeature = new FlavorFeature();
 
 137             flavorFeature.setId(node.toString());
 
 138             LOGGER.debug("the name of node =" + node.toString());
 
 139             flavorFeature.getDirectives().add(flavorDirective);
 
 141             final CapabilityAssignments capabilityAssignments = sdcCsarHelper.getCapabilitiesOf(node);
 
 142             final CapabilityAssignment capabilityAssignment =
 
 143                     capabilityAssignments.getCapabilityByName("virtual_compute");
 
 144             if (capabilityAssignment != null) {
 
 145                 generateBasicCapability(capabilityAssignment, flavorFeature);
 
 146                 generateHugePages(capabilityAssignment, flavorFeature);
 
 148             content.getFlavorFeatures().add(flavorFeature);
 
 153      * GenerateBasicCapability, supported hpa features, All under the capability of 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,
 
 160             final FlavorFeature flavorFeature) {
 
 161         // the format is xxx MB/GB like 4096 MB
 
 162         final String virtualMemSize =
 
 163                 sdcCsarHelper.getCapabilityPropertyLeafValue(capabilityAssignment, VIRTUAL_MEM_SIZE_PATH);
 
 164         if (virtualMemSize != null) {
 
 165             LOGGER.debug("the virtualMemSize = " + virtualMemSize);
 
 166             final HpaFeatureAttribute hpaFeatureAttribute =
 
 167                     generateHpaFeatureAttribute("virtualMemSize", virtualMemSize);
 
 168             final FlavorProperty flavorProperty = new FlavorProperty();
 
 169             flavorProperty.setHpaFeature(BASIC_CAPABILITIES_HPA_FEATURE);
 
 170             flavorProperty.getHpaFeatureAttributes().add(hpaFeatureAttribute);
 
 171             flavorFeature.getFlavorProperties().add(flavorProperty);
 
 174         // the format is int like 2
 
 175         final String numVirtualCpu =
 
 176                 sdcCsarHelper.getCapabilityPropertyLeafValue(capabilityAssignment, NUM_VIRTUAL_CPU_PATH);
 
 177         if (numVirtualCpu != null) {
 
 178             LOGGER.debug("the numVirtualCpu = " + numVirtualCpu);
 
 179             final HpaFeatureAttribute hpaFeatureAttribute = generateHpaFeatureAttribute("numVirtualCpu", numVirtualCpu);
 
 180             final String cpuArchitecture =
 
 181                     sdcCsarHelper.getCapabilityPropertyLeafValue(capabilityAssignment, CPU_ARCHITECTURE_PATH);
 
 182             final FlavorProperty flavorProperty = new FlavorProperty();
 
 183             flavorProperty.setHpaFeature(BASIC_CAPABILITIES_HPA_FEATURE);
 
 184             if (cpuArchitecture != null) {
 
 185                 flavorProperty.setArchitecture(cpuArchitecture);
 
 187             flavorProperty.getHpaFeatureAttributes().add(hpaFeatureAttribute);
 
 188             flavorFeature.getFlavorProperties().add(flavorProperty);
 
 193      * GenerateHpaFeatureAttribute based on the value of featureValue. the format: "hpa-attribute-key": "pciVendorId",
 
 194      * "hpa-attribute-value": "1234", "operator": "=", "unit": "xxx".
 
 196      * @param hpaAttributeKey get from the high layer tosca DM
 
 198      * @param featureValue get from the high layer tosca DM
 
 201     private HpaFeatureAttribute generateHpaFeatureAttribute(final String hpaAttributeKey, final String featureValue) {
 
 202         // based on input featureValue, return back a suitable hpaFeatureAttribute
 
 203         final HpaFeatureAttribute hpaFeatureAttribute = new HpaFeatureAttribute();
 
 204         hpaFeatureAttribute.setHpaAttributeKey(hpaAttributeKey);
 
 205         final String tmp = featureValue.replace(" ", "");
 
 206         final String pattern = "(\\D*)(\\d+)(\\D*)";
 
 207         final Pattern r = Pattern.compile(pattern);
 
 208         final Matcher m = r.matcher(tmp);
 
 210             LOGGER.debug("operator = " + m.group(1));
 
 211             LOGGER.debug("value = " + m.group(2));
 
 212             LOGGER.debug("unit = " + m.group(3));
 
 213             hpaFeatureAttribute.setOperator(m.group(1));
 
 214             hpaFeatureAttribute.setHpaAttributeValue(m.group(2));
 
 215             hpaFeatureAttribute.setUnit(m.group(3));
 
 217         return hpaFeatureAttribute;
 
 221      * GenerateHugePages, supported hpa features, All under the capability of tosca.nodes.nfv.Vdu.Compute. The format is
 
 222      * a map like: {"schemaVersion": "0", "schemaSelector": "", "hardwarePlatform": "generic", "mandatory": "true",
 
 223      * "configurationValue": "2 MB"}
 
 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, final FlavorFeature flavorFeature) {
 
 230         final String memoryPageSize =
 
 231                 sdcCsarHelper.getCapabilityPropertyLeafValue(capabilityAssignment, MEMORY_PAGE_SIZE_PATH);
 
 232         LOGGER.debug("the memoryPageSize = " + memoryPageSize);
 
 233         if (memoryPageSize != null) {
 
 234             final Map<String, String> retMap =
 
 235                     gson.fromJson(memoryPageSize, new TypeToken<HashMap<String, String>>() {}.getType());
 
 236             LOGGER.debug("the retMap = " + retMap);
 
 237             final String memoryPageSizeValue = retMap.get(CONFIGURATION_VALUE);
 
 238             final String mandatory = retMap.get("mandatory");
 
 239             if (memoryPageSizeValue == null) {
 
 242             final HpaFeatureAttribute hpaFeatureAttribute =
 
 243                     generateHpaFeatureAttribute("memoryPageSize", memoryPageSizeValue);
 
 244             final FlavorProperty flavorProperty = new FlavorProperty();
 
 245             flavorProperty.setHpaFeature(HUGE_PAGES_HPA_FEATURE);
 
 246             if (mandatory != null) {
 
 247                 flavorProperty.setMandatory(mandatory);
 
 249             flavorProperty.getHpaFeatureAttributes().add(hpaFeatureAttribute);
 
 250             flavorFeature.getFlavorProperties().add(flavorProperty);
 
 255      * ExtractInfoVduCp, supported hpa features, under the virtual_network_interface_requirements of
 
 256      * tosca.nodes.nfv.VduCp.
 
 258      * @param lnodeVduCp the list of VduCp node
 
 260      * @param content to be change based on lnodeVduCp
 
 261      * @throws PolicyDecodingException if extract CP fails
 
 263     public void extractInfoVduCp(final List<NodeTemplate> lnodeVduCp, final Content content)
 
 264             throws PolicyDecodingException {
 
 265         // each CP will binds to a VDU so need the vdu flavor map info.
 
 266         final Map<String, FlavorFeature> vduFlavorMap = new HashMap<>();
 
 267         for (final FlavorFeature flavorFeature : content.getFlavorFeatures()) {
 
 268             LOGGER.debug("the id = " + flavorFeature.getId());
 
 269             vduFlavorMap.put(flavorFeature.getId(), flavorFeature);
 
 271         for (final NodeTemplate node : lnodeVduCp) {
 
 272             final String interfaceType =
 
 273                     sdcCsarHelper.getNodeTemplatePropertyLeafValue(node, NETWORK_INTERFACE_TYPE_PATH);
 
 274             LOGGER.debug("the interfaceType = " + interfaceType);
 
 275             Map<String, Object> retMap = new HashMap<>();
 
 276             if (interfaceType != null) {
 
 277                 retMap = gson.fromJson(interfaceType, new TypeToken<HashMap<String, Object>>() {}.getType());
 
 278                 LOGGER.debug("the retMap = " + retMap);
 
 281             String networkHpaFeature;
 
 282             if (retMap.containsKey(CONFIGURATION_VALUE)) {
 
 283                 final String interfaceTypeValue = retMap.get(CONFIGURATION_VALUE).toString();
 
 284                 LOGGER.debug(" the interfacetype value is =" + interfaceTypeValue);
 
 285                 if (NETWORK_HPA_FEATURE_MAP.containsKey(interfaceTypeValue)) {
 
 286                     networkHpaFeature = NETWORK_HPA_FEATURE_MAP.get(interfaceTypeValue);
 
 287                     LOGGER.debug(" the networkHpaFeature is =" + networkHpaFeature);
 
 289                     LOGGER.debug(" unspported network interface ");
 
 293                 LOGGER.debug(" no configurationValue defined in interfaceType");
 
 297             final RequirementAssignments requriements =
 
 298                 sdcCsarHelper.getRequirementsOf(node).getRequirementsByName("virtual_binding");
 
 299             for (final RequirementAssignment requriement : requriements.getAll()) {
 
 300                 final String nodeTemplateName = requriement.getNodeTemplateName();
 
 301                 LOGGER.debug("getNodeTemplateName =" + nodeTemplateName);
 
 302                 if (nodeTemplateName == null) {
 
 305                 if (!vduFlavorMap.containsKey(nodeTemplateName)) {
 
 306                     throw new PolicyDecodingException("vdu Flavor Map should contains the key " + nodeTemplateName);
 
 308                 generateNetworkFeature(networkHpaFeature, node, vduFlavorMap.get(nodeTemplateName));
 
 314      * GenerateNetworkFeature, all pci feature are grouped into FlavorFeature together. The format is a map like:
 
 315      * {"schemaVersion": "0", "schemaSelector": "", "hardwarePlatform": "generic", "mandatory": "true",
 
 316      * "configurationValue": "2 MB"}
 
 318      * @param networkHpaFeature represents the specified Hpa feature
 
 319      * @param node represents the CP Node
 
 320      * @param flavorFeature represents all the features of specified flavor
 
 322     private void generateNetworkFeature(final String networkHpaFeature, final NodeTemplate node,
 
 323             final FlavorFeature flavorFeature) {
 
 324         final FlavorProperty flavorProperty = new FlavorProperty();
 
 325         flavorProperty.setHpaFeature(networkHpaFeature);
 
 326         final String[] pciKeys = { "pciVendorId", "pciDeviceId", "pciNumDevices", "physicalNetwork" };
 
 327         for (final String pciKey : pciKeys) {
 
 328             LOGGER.debug("the pciKey = " + pciKey);
 
 329             final String pciKeyPath = NETWORK_PCI_PATH + "#" + pciKey;
 
 330             final String pciValue = sdcCsarHelper.getNodeTemplatePropertyLeafValue(node, pciKeyPath);
 
 331             if (pciValue != null) {
 
 332                 LOGGER.debug("the pciValue = " + pciValue);
 
 333                 final Map<String, String> retMap =
 
 334                         gson.fromJson(pciValue, new TypeToken<HashMap<String, String>>() {}.getType());
 
 335                 final String pciConfigValue = retMap.get(CONFIGURATION_VALUE);
 
 336                 if (pciConfigValue == null) {
 
 339                 final HpaFeatureAttribute hpaFeatureAttribute = generateHpaFeatureAttribute(pciKey, pciConfigValue);
 
 340                 flavorProperty.getHpaFeatureAttributes().add(hpaFeatureAttribute);
 
 343         flavorFeature.getFlavorProperties().add(flavorProperty);