Support new policy model in HAS 17/66917/5
authorRuoyu Ying <ruoyu.ying@intel.com>
Mon, 17 Sep 2018 17:21:27 +0000 (01:21 +0800)
committerRuoyu Ying <ruoyu.ying@intel.com>
Tue, 18 Sep 2018 14:29:13 +0000 (22:29 +0800)
Make changes to support the newly defined policy model

Change-Id: Iea882b0c254c4bfca32da2458ea65f3daf56a779
Issue-ID: OPTFRA-322
Signed-off-by: Ruoyu Ying <ruoyu.ying@intel.com>
15 files changed:
conductor/conductor/controller/translator.py
conductor/conductor/data/plugins/inventory_provider/aai.py
conductor/conductor/data/plugins/inventory_provider/hpa_utils.py
conductor/conductor/data/service.py
conductor/conductor/solver/optimizer/constraints/hpa.py
conductor/conductor/solver/service.py
conductor/conductor/solver/utils/constraint_engine_interface.py
conductor/conductor/tests/unit/controller/hpa_constraints.json
conductor/conductor/tests/unit/controller/test_translator.py
conductor/conductor/tests/unit/data/hpa_constraints.json
conductor/conductor/tests/unit/data/plugins/inventory_provider/hpa_flavors.json
conductor/conductor/tests/unit/data/plugins/inventory_provider/hpa_req_features.json
conductor/conductor/tests/unit/data/plugins/inventory_provider/test_aai.py
conductor/conductor/tests/unit/data/test_service.py
conductor/conductor/tests/unit/solver/hpa_constraints.json

index fb591e0..4f0ed20 100644 (file)
@@ -105,7 +105,7 @@ CONSTRAINTS = {
     },
 }
 HPA_FEATURES = ['architecture', 'hpa-feature', 'hpa-feature-attributes',
-                'hpa-version', 'mandatory']
+                'hpa-version', 'mandatory', 'directives']
 HPA_OPTIONAL = ['score']
 HPA_ATTRIBUTES = ['hpa-attribute-key', 'hpa-attribute-value', 'operator']
 HPA_ATTRIBUTES_OPTIONAL = ['unit']
@@ -553,14 +553,18 @@ class Translator(object):
     def validate_hpa_constraints(self, req_prop, value):
         for para in value.get(req_prop):
             # Make sure there is at least one
-            # set of flavorLabel and flavorProperties
-            if not para.get('flavorLabel') \
+            # set of id, type, directives and flavorProperties
+            if not para.get('id') \
+                    or not para.get('type') \
+                    or not para.get('directives') \
                     or not para.get('flavorProperties') \
-                    or para.get('flavorLabel') == '' \
+                    or para.get('id') == '' \
+                    or para.get('type') == '' \
+                    or not isinstance(para.get('directives'), list)  \
                     or para.get('flavorProperties') == '':
                 raise TranslatorException(
                     "HPA requirements need at least "
-                    "one set of flavorLabel and flavorProperties"
+                    "one set of id, type, directives and flavorProperties"
                 )
             for feature in para.get('flavorProperties'):
                 if type(feature) is not dict:
@@ -574,7 +578,7 @@ class Translator(object):
                 hpa_optional = set(feature.keys()).difference(HPA_FEATURES)
                 if hpa_optional and not hpa_optional.issubset(HPA_OPTIONAL):
                     raise TranslatorException(
-                        "Lack of compulsory elements inside HPA feature")
+                        "Got unrecognized elements inside HPA feature")
                 if feature.get('mandatory') == 'False' and not feature.get(
                         'score'):
                     raise TranslatorException(
@@ -591,7 +595,7 @@ class Translator(object):
                     if bool(hpa_attr_mandatory):
                         raise TranslatorException(
                             "Lack of compulsory elements inside HPA "
-                            "feature atrributes")
+                            "feature attributes")
                     # process optional hpa attribute parameter
                     hpa_attr_optional = set(attr.keys()).difference(
                         HPA_ATTRIBUTES)
@@ -649,7 +653,7 @@ class Translator(object):
                                 "No value specified for property '{}' in "
                                 "constraint named '{}'".format(
                                     req_prop, name))
-                        # For HPA constraints
+                            # For HPA constraints
                         if constraint_type == 'hpa':
                             self.validate_hpa_constraints(req_prop, value)
 
index d23a483..8634b3f 100644 (file)
@@ -1340,6 +1340,6 @@ class AAI(base.InventoryProviderBase):
     def match_hpa(self, candidate, features):
         """Match HPA features requirement with the candidate flavors """
         hpa_provider = hpa_utils.HpaMatchProvider(candidate, features)
-        flavor_map = hpa_provider.match_flavor()
-        return flavor_map
+        directives = hpa_provider.match_flavor()
+        return directives
 
index 648775a..2414e61 100644 (file)
@@ -69,7 +69,7 @@ class HpaMatchProvider(object):
                 if hpa_list not in req_filter_list:
                     req_filter_list.append(hpa_list)
         max_score = -1
-        flavor_map = None
+        directives = None
         for flavor in self.flavors_list:
             flavor_filter_list = []
             try:
@@ -84,7 +84,7 @@ class HpaMatchProvider(object):
                 flavor_filter_list.append(hpa_list)
             # if flavor has the matching capability compare attributes
             if self._is_cap_supported(flavor_filter_list, req_filter_list):
-                match_found, score = self._compare_feature_attributes(flavor_cap_list)
+                match_found, score, req_directives = self._compare_feature_attributes(flavor_cap_list)
                 if match_found:
                     LOG.info(_LI("Matching Flavor found '{}' for request - {}").
                              format(flavor['flavor-name'], self.req_cap_list))
@@ -93,7 +93,9 @@ class HpaMatchProvider(object):
                         flavor_map = {"flavor-id": flavor['flavor-id'],
                                       "flavor-name": flavor['flavor-name'],
                                       "score": max_score}
-        return flavor_map
+                        directives = {"flavor_map": flavor_map,
+                                      "directives": req_directives}
+        return directives
 
 
     def _is_cap_supported(self, flavor, cap):
@@ -212,7 +214,7 @@ class HpaMatchProvider(object):
         for capability in CapabilityDataParser.get_item(flavor_cap_list,
                                                         'hpa-capability'):
             flavor_feature, feature_attributes = capability.get_fields()
-            # One feature will match this condition as we have pre-filtered
+            # Multiple features will match this condition as we have pre-filtered
             if feature == flavor_feature:
                 return feature_attributes
 
@@ -221,24 +223,31 @@ class HpaMatchProvider(object):
     # and compare each attribute
     def _compare_feature_attributes(self, flavor_cap_list):
         score = 0
+        directives = []
         for capability in CapabilityDataParser.get_item(self.req_cap_list, None):
             hpa_feature, req_cfa_list = capability.get_fields()
+            feature_directive = capability.get_directives()
+            if feature_directive:
+                feature_directive[:] = [d for d in feature_directive
+                                            if d.get("type") != ""]
+                for item in feature_directive:
+                    directives.append(item)
             flavor_cfa_list = self._get_flavor_cfa_list(hpa_feature, flavor_cap_list)
             if flavor_cfa_list is not None:
                 for req_feature_attr in req_cfa_list:
                     req_attr_key = req_feature_attr['hpa-attribute-key']
-                     # filter to get the attribute being compared
+                    # filter to get the attribute being compared
                     flavor_feature_attr = \
                         filter(lambda ele: ele['hpa-attribute-key'] == \
-                               req_attr_key, flavor_cfa_list)
-                    if not flavor_feature_attr:
-                        return False, 0
-                    if not self._compare_attribute(flavor_feature_attr[0],
-                                                   req_feature_attr):
-                        return False, 0
+                                req_attr_key, flavor_cfa_list)
+                    if not flavor_feature_attr and capability.item['mandatory'] == 'True':
+                        return False, 0, None
+                    if not self._compare_attribute(flavor_feature_attr[0], req_feature_attr) \
+                            and capability.item['mandatory'] == 'True':
+                        return False, 0, None
             if flavor_cfa_list is not None and capability.item['mandatory'] == 'False':
                 score = score + int(capability.item['score'])
-        return True, score
+        return True, score, directives
 
 
 class CapabilityDataParser(object):
@@ -269,3 +278,6 @@ class CapabilityDataParser(object):
 
     def get_feature(self):
         return self.item.get('hpa-feature')
+
+    def get_directives(self):
+        return self.item.get('directives')
index 0af7bb7..d6ea20f 100644 (file)
@@ -52,13 +52,13 @@ DATA_OPTS = [
                      'mode. When set to False, data will flush any abandoned '
                      'messages at startup.'),
     cfg.FloatOpt('existing_placement_cost',
-               default=-8000.0,
-               help='Default value is -8000, which is the diameter of the earth. '
-                    'The distance cannot larger than this value'),
+                 default=-8000.0,
+                 help='Default value is -8000, which is the diameter of the earth. '
+                      'The distance cannot larger than this value'),
     cfg.FloatOpt('cloud_candidate_cost',
-               default=2.0),
+                 default=2.0),
     cfg.FloatOpt('service_candidate_cost',
-               default=1.0),
+                 default=1.0),
 ]
 
 CONF.register_opts(DATA_OPTS, group='data')
@@ -223,7 +223,7 @@ class DataEndpoint(object):
                     discard_set.add(candidate.get("candidate_id"))
         return discard_set
 
-    #(TODO:Larry) merge this function with the "get_candidate_discard_set"
+    # (TODO:Larry) merge this function with the "get_candidate_discard_set"
     def get_candidate_discard_set_by_cloud_region(self, value, candidate_list, value_attrib):
         discard_set = set()
 
@@ -239,10 +239,8 @@ class DataEndpoint(object):
                     (candidate.get(value_attrib) not in service_requests):
                 discard_set.add(candidate.get("candidate_id"))
 
-
         return discard_set
 
-
     def get_inventory_group_candidates(self, ctx, arg):
         candidate_list = arg["candidate_list"]
         resolved_candidate = arg["resolved_candidate"]
@@ -442,18 +440,22 @@ class DataEndpoint(object):
         '''
         error = False
         candidate_list = arg["candidate_list"]
-        label_name = arg["label_name"]
+        id = arg["id"]
+        type = arg["type"]
+        directives = arg["directives"]
+        attr = directives[0].get("attributes")
+        label_name = attr[0].get("attribute_name")
         flavorProperties = arg["flavorProperties"]
         discard_set = set()
-        for candidate in candidate_list:
+        for i in range(len(candidate_list)):
             # perform this check only for cloud candidates
-            if candidate["inventory_type"] != "cloud":
+            if candidate_list[i]["inventory_type"] != "cloud":
                 continue
 
             # Check if flavor mapping for current label_name already
             # exists. This is an invalid condition.
-            if candidate.get("flavor_map") and candidate["flavor_map"].get(
-                    label_name):
+            if candidate_list[i].get("directives") and attr[0].get(
+                    "attribute_value") != "":
                 LOG.error(_LE("Flavor mapping for label name {} already"
                               "exists").format(label_name))
                 continue
@@ -461,36 +463,44 @@ class DataEndpoint(object):
             # RPC call to inventory provider for matching hpa capabilities
             results = self.ip_ext_manager.map_method(
                 'match_hpa',
-                candidate=candidate,
+                candidate=candidate_list[i],
                 features=flavorProperties
             )
 
-            if results and len(results) > 0:
-                flavor_info = results[0]
+            flavor_name = None
+            if results and len(results) > 0 and results[0] is not None:
+                LOG.debug("Find results {} and results length {}".format(results, len(results)))
+                flavor_info = results[0].get("flavor_map")
+                req_directives = results[0].get("directives")
+                LOG.debug("Get directives {}".format(req_directives))
+
             else:
                 flavor_info = None
                 LOG.info(
                     _LW("No flavor mapping returned by "
                         "inventory provider: {} for candidate: {}").format(
                         self.ip_ext_manager.names()[0],
-                        candidate.get("candidate_id")))
+                        candidate_list[i].get("candidate_id")))
             if not flavor_info:
-                discard_set.add(candidate.get("candidate_id"))
+                discard_set.add(candidate_list[i].get("candidate_id"))
             else:
                 if not flavor_info.get("flavor-name"):
-                    discard_set.add(candidate.get("candidate_id"))
+                    discard_set.add(candidate_list[i].get("candidate_id"))
                 else:
-                    # Create flavor_map if not exist already
-                    if not candidate.get("flavor_map"):
-                        candidate["flavor_map"] = {}
+                    if not candidate_list[i].get("flavor_map"):
+                        candidate_list[i]["flavor_map"] = {}
                     # Create flavor mapping for label_name to flavor
                     flavor_name = flavor_info.get("flavor-name")
-                    candidate["flavor_map"][label_name] = flavor_name
-                    # If hpa_score is not defined then initialize value 0
-                    # hpa_score = sum of scores of each vnfc hpa requirement score
-                    if not candidate.get("hpa_score"):
-                        candidate["hpa_score"] = 0
-                    candidate["hpa_score"] += flavor_info.get("score")
+                    candidate_list[i]["flavor_map"][label_name] = flavor_name
+                    # Create directives if not exist already
+                    if not candidate_list[i].get("all_directives"):
+                        candidate_list[i]["all_directives"] = {}
+                        candidate_list[i]["all_directives"]["directives"] = []
+                    # Create flavor mapping and merge directives
+                    self.merge_directives(candidate_list, i, id, type, directives, req_directives)
+                    if not candidate_list[i].get("hpa_score"):
+                        candidate_list[i]["hpa_score"] = 0
+                    candidate_list[i]["hpa_score"] += flavor_info.get("score")
 
         # return candidates not in discard set
         candidate_list[:] = [c for c in candidate_list
@@ -501,6 +511,34 @@ class DataEndpoint(object):
                                              self.ip_ext_manager.names()[0]))
         return {'response': candidate_list, 'error': error}
 
+    def merge_directives(self, candidate_list, index, id, type, directives, feature_directives):
+        '''
+        Merge the flavor_directives with other diectives listed under hpa capabilities in the policy
+        :param candidate_list: all candidates
+        :param index: index number
+        :param id: vfc name
+        :param type: vfc type
+        :param directives: directives for each vfc
+        :param feature_directives: directives for hpa-features
+        :return:
+        '''
+        directive= {"id": id,
+                    "type": type,
+                    "directives": ""}
+        for ele in directives:
+            if "flavor_directives" in ele.get("type"):
+                flag = True
+                break
+            else:
+                flag = False
+        if not flag:
+            LOG.error("No flavor directives found in {}".format(id))
+        for item in feature_directives:
+            if item and item not in directives:
+                directives.append(item)
+        directive["directives"] = directives
+        candidate_list[index]["all_directives"]["directives"].append(directive)
+
     def get_candidates_with_vim_capacity(self, ctx, arg):
         '''
         RPC for getting candidates with vim capacity
index 98d95d9..106953b 100644 (file)
@@ -54,15 +54,19 @@ class HPA(constraint.Constraint):
             self.constraint_type, demand_name))
         vm_label_list = self.properties.get('evaluate')
         for vm_demand in vm_label_list:
-            label_name = vm_demand['flavorLabel']
+            id = vm_demand['id']
+            type = vm_demand['type']
+            directives = vm_demand['directives']
             flavorProperties = vm_demand['flavorProperties']
-            response = (cei.get_candidates_with_hpa(label_name,
+            response = (cei.get_candidates_with_hpa(id,
+                                                    type,
+                                                    directives,
                                                     _candidate_list,
                                                     flavorProperties))
             _candidate_list = response
             if not response:
                 LOG.error(_LE("No matching candidates for HPA exists").format(
-                    label_name))
+                    id))
                 break
                 # No need to continue.
 
index e539acd..56ec683 100644 (file)
@@ -347,10 +347,10 @@ class SolverService(cotyledon.Service):
                         rec["candidate"]["host_id"] = resource.get("host_id")
 
                     if rec["candidate"]["inventory_type"] == "cloud":
-                        if resource.get("flavor_map"):
-                            rec["attributes"]["flavors"] = resource.get(
-                                "flavor_map")
-
+                        if resource.get("all_directives") and resource.get("flavor_map"):
+                            rec["attributes"]["directives"] = \
+                                self.set_flavor_in_flavor_directives(
+                                    resource.get("flavor_map"), resource.get("all_directives"))
                     # TODO(snarayanan): Add total value to recommendations?
                     # msg = "--- total value of decision = {}"
                     # LOG.debug(msg.format(_best_path.total_value))
@@ -387,3 +387,18 @@ class SolverService(cotyledon.Service):
         """Reload"""
         LOG.debug("%s" % self.__class__.__name__)
         self._restart()
+
+    def set_flavor_in_flavor_directives(self, flavor_map, directives):
+        '''
+        Insert the flavor name inside the flavor_map into flavor_directives
+        :param flavor_map: flavor map get
+        :param directives: All the directives get from request
+        '''
+        flavor_label = flavor_map.keys()
+        for ele in directives.get("directives"):
+            for item in ele.get("directives"):
+                if "flavor_directives" in item.get("type"):
+                    for attr in item.get("attributes"):
+                        attr["attribute_value"] = flavor_map.get(attr["attribute_name"]) \
+                            if attr.get("attribute_name") in flavor_label else ""
+        return directives
index 43331aa..bbb782d 100644 (file)
@@ -117,7 +117,7 @@ class ConstraintEngineInterface(object):
         # response is a list of (candidate, cost) tuples
         return response
 
-    def get_candidates_with_hpa(self, label_name, candidate_list,
+    def get_candidates_with_hpa(self, id, type, directives, candidate_list,
                                 flavorProperties):
         '''
         Returns the candidate_list with an addition of flavor_mapping for
@@ -130,7 +130,9 @@ class ConstraintEngineInterface(object):
         ctxt = {}
         args = {"candidate_list": candidate_list,
                 "flavorProperties": flavorProperties,
-                "label_name": label_name}
+                "id": id,
+                "type": type,
+                "directives": directives}
         response = self.client.call(ctxt=ctxt,
                                     method="get_candidates_with_hpa",
                                     args=args)
index 5a86ede..a2543bc 100644 (file)
@@ -27,7 +27,8 @@
                       "unit": "GB"
                     }
                   ],
-                  "hpa-version": "v1"
+                  "hpa-version": "v1",
+                  "directives": []
                 },
                 {
                   "architecture": "generic",
@@ -61,7 +62,8 @@
                       "unit": "GB"
                     }
                   ],
-                  "hpa-version": "v1"
+                  "hpa-version": "v1",
+                  "directives": []
                 },
                 {
                   "architecture": "generic",
                       "operator": "="
                     }
                   ],
-                  "hpa-version": "v1"
+                  "hpa-version": "v1",
+                  "directives": []
                 }
               ],
-              "flavorLabel": "flavor_label_1"
+              "id": "vg_1",
+              "type": "vnfc",
+              "directives": [
+                {
+                  "type": "flavor_directives",
+                  "attributes": [
+                    {
+                      "attribute_name": "flavor_label_1",
+                      "attribute_value": ""
+                    }
+                  ]
+                }
+              ]
             },
             {
               "flavorProperties": [
                       "unit": "GB"
                     }
                   ],
-                  "hpa-version": "v1"
+                  "hpa-version": "v1",
+                  "directives": []
                 },
                 {
                   "architecture": "generic",
                       "unit": "GB"
                     }
                   ],
-                  "hpa-version": "v1"
+                  "hpa-version": "v1",
+                  "directives": []
                 },
                 {
                   "architecture": "generic",
                       "unit": "GB"
                     }
                   ],
-                  "hpa-version": "v1"
+                  "hpa-version": "v1",
+                  "directives": []
                 }
               ],
-              "flavorLabel": "flavor_label_2"
+              "id": "vg_2",
+              "type": "vnfc",
+              "directives": [
+                {
+                  "type": "flavor_directives",
+                  "attributes": [
+                    {
+                      "attribute_name": "flavor_label_2",
+                      "attribute_value": ""
+                    }
+                  ]
+                }
+              ]
             }
           ]
         }
index e6575a9..c61e57e 100644 (file)
@@ -232,12 +232,25 @@ class TestNoExceptionTranslator(unittest.TestCase):
                 ],
                 "properties": {
                     "evaluate": [
-                        {'flavorLabel': 'xx',
+                        {'id': 'vg_0',
+                         'type': 'vnfc',
+                         'directives': [
+                             {
+                                 "type": "flavor_directives",
+                                 "attributes": [
+                                     {
+                                         "attribute_name": "label_0",
+                                         "attribute_value": ""
+                                     }
+                                 ]
+                             }
+                         ],
                          'flavorProperties': [{
                              'hpa-feature': 'BasicCapabilities',
                              'hpa-version': 'v1',
                              'architecture': 'generic',
                              'mandatory': 'False',
+                             'directives': [],
                              'score': '5',
                              'hpa-feature-attributes': [
                                  {
@@ -264,6 +277,7 @@ class TestNoExceptionTranslator(unittest.TestCase):
                         {'architecture': 'generic',
                          'mandatory': 'False',
                          'score': '5',
+                         'directives': [],
                          'hpa-feature': 'BasicCapabilities',
                          'hpa-feature-attributes': [
                              {
@@ -279,7 +293,20 @@ class TestNoExceptionTranslator(unittest.TestCase):
                              }
                          ],
                          'hpa-version': 'v1'}],
-                    'flavorLabel': 'xx'}]},
+                    'id': 'vg_0',
+                    'type': 'vnfc',
+                    'directives': [
+                        {
+                            'type': 'flavor_directives',
+                            'attributes': [
+                                {
+                                    'attribute_name': 'label_0',
+                                    'attribute_value': ''
+                                }
+                            ]
+                        }
+                    ]
+                }]},
                 'type': 'hpa'
             }
         }
@@ -295,12 +322,25 @@ class TestNoExceptionTranslator(unittest.TestCase):
                 ],
                 "properties": {
                     "evaluate": [
-                        {'flavorLabel': 'xx',
+                        {'id': 'vg_0',
+                         'type': 'vnfc',
+                         'directives': [
+                            {
+                                'type': 'flavor_directives',
+                                'attributes': [
+                                    {
+                                        'attribute_name': 'label_0',
+                                        'attribute_value': ''
+                                    }
+                                ]
+                            }
+                         ],
                          'flavorProperties': [{
                              'hpa-feature': 'BasicCapabilities',
                              'hpa-version': 'v1',
                              'architecture': 'generic',
                              'mandatory': 'True',
+                             'directives': [],
                              'hpa-feature-attributes': [
                                  {
                                      'hpa-attribute-key': 'numVirtualCpu',
@@ -325,6 +365,7 @@ class TestNoExceptionTranslator(unittest.TestCase):
                     'flavorProperties': [
                         {'architecture': 'generic',
                          'mandatory': 'True',
+                         'directives': [],
                          'hpa-feature': 'BasicCapabilities',
                          'hpa-feature-attributes': [
                              {
@@ -340,7 +381,19 @@ class TestNoExceptionTranslator(unittest.TestCase):
                              }
                          ],
                          'hpa-version': 'v1'}],
-                    'flavorLabel': 'xx'}]},
+                    'id': 'vg_0',
+                    'type': 'vnfc',
+                    'directives': [
+                        {
+                            'type': 'flavor_directives',
+                            'attributes': [
+                                {
+                                    'attribute_name': 'label_0',
+                                    'attribute_value': ''
+                                }
+                            ]
+                        }
+                    ]}]},
                 'type': 'hpa'
             }
         }
@@ -356,7 +409,7 @@ class TestNoExceptionTranslator(unittest.TestCase):
                     "vG"
                 ],
                 "properties": {
-                    "evaluate": [{'flavor': 'xx',
+                    "evaluate": [{'id': 'xx',
                                   'flavorProperties': []}]
                 }
             }
@@ -369,7 +422,8 @@ class TestNoExceptionTranslator(unittest.TestCase):
                 ],
                 "properties": {
                     "evaluate": [
-                        {'flavorLabel': 'xx',
+                        {'id': 'xx',
+                         'type': 'xx',
                          'flavorProperties': [
                              {
                                  'hpa-feature': '',
@@ -393,7 +447,9 @@ class TestNoExceptionTranslator(unittest.TestCase):
                 "properties": {
                     "evaluate": [
                         {
-                            "flavorLabel": "xx",
+                            "id": "xx",
+                            "type": 'xx',
+                            "directives": [],
                             "flavorProperties": [
                                 {
                                     "hpa-feature": "BasicCapabilities",
@@ -422,7 +478,9 @@ class TestNoExceptionTranslator(unittest.TestCase):
                     "vG"
                 ],
                 "properties": {
-                    "evaluate": [{'flavorLabel': 'xx',
+                    "evaluate": [{'id': 'xx',
+                                  "type": 'xx',
+                                  "directives": [],
                                   'flavorProperties': [{
                                       'hpa-feature': '',
                                       'architecture': '',
index 829eaf3..0f42cc9 100644 (file)
@@ -26,7 +26,8 @@
                         "unit": "GB"
                       }
                     ],
-                    "hpa-version": "v1"
+                    "hpa-version": "v1",
+                    "directives": []
                   },
                   {
                     "architecture": "generic",
@@ -60,7 +61,8 @@
                         "unit": "GB"
                       }
                     ],
-                    "hpa-version": "v1"
+                    "hpa-version": "v1",
+                    "directives": []
                   },
                   {
                     "architecture": "generic",
                         "operator": "="
                       }
                     ],
-                    "hpa-version": "v1"
+                    "hpa-version": "v1",
+                    "directives": []
                   }
                 ],
-                "flavorLabel": "flavor_label_1"
+                "id": "vg_1",
+                "type": "vnfc",
+                "directives": [
+                  {
+                    "type": "flavor_directives",
+                    "attributes": [
+                      {
+                        "attribute_name": "flavor_label_1",
+                        "attribute_value": ""
+                      }
+                    ]
+                  }
+                ]
               },
               {
                 "flavorProperties": [
                         "unit": "GB"
                       }
                     ],
-                    "hpa-version": "v1"
+                    "hpa-version": "v1",
+                    "directives": []
                   },
                   {
                     "architecture": "generic",
                         "unit": "GB"
                       }
                     ],
-                    "hpa-version": "v1"
+                    "hpa-version": "v1",
+                    "directives": []
                   },
                   {
                     "architecture": "generic",
                         "unit": "GB"
                       }
                     ],
-                    "hpa-version": "v1"
+                    "hpa-version": "v1",
+                    "directives": []
                   }
                 ],
-                "flavorLabel": "flavor_label_2"
+                "id": "vg_2",
+                "type": "vnfc",
+                "directives": [
+                  {
+                    "type": "flavor_directives",
+                    "attributes": [
+                      {
+                        "attribute_name": "flavor_label_2",
+                        "attribute_value": ""
+                      }
+                    ]
+                  }
+                ]
               }
             ]
           }
index db5ea54..19cf8b9 100644 (file)
       },
       "resource-version": "1520943846264"
     },
+    {
+      "flavor-id": "f5aa2b2e-3206-41b6-80d5-cf6t2b098c43",
+      "flavor-name": "flavor-ovsdpdk-cpu-pinning-sriov-NIC-Network-set",
+      "flavor-vcpus": 32,
+      "flavor-ram": 131072,
+      "flavor-disk": 2097152,
+      "flavor-ephemeral": 128,
+      "flavor-swap": "0",
+      "flavor-is-public": false,
+      "flavor-selflink": "pXtX",
+      "flavor-disabled": false,
+      "hpa-capabilities": {
+        "hpa-capability": [
+          {
+            "hpa-capability-id": "8d36a8fe-bfee-446a-bbcb-881ee66c8f78",
+            "hpa-feature": "ovsDpdk",
+            "hpa-version": "v1",
+            "architecture": "generic",
+            "resource-version": "1520943846328",
+            "hpa-feature-attributes": [
+              {
+                "hpa-attribute-key": "dataProcessingAccelerationLibrary",
+                "hpa-attribute-value": "{\"value\":\"v18.02\"}",
+                "resource-version": "1520943846346"
+              }
+            ]
+          },
+          {
+            "hpa-capability-id": "c140c945-1532-4908-86c9-d7f71416f1dd",
+            "hpa-feature": "cpuPinning",
+            "hpa-version": "v1",
+            "architecture": "generic",
+            "resource-version": "1520943846297",
+            "hpa-feature-attributes": [
+              {
+                "hpa-attribute-key": "logicalCpuPinningPolicy",
+                "hpa-attribute-value": "{\"value\":\"dedicated\"}",
+                "resource-version": "1520943846312"
+              },
+              {
+                "hpa-attribute-key": "logicalCpuThreadPinningPolicy",
+                "hpa-attribute-value": "{\"value\":\"prefer\"}",
+                "resource-version": "1520943846301"
+              }
+            ]
+          },
+          {
+            "hpa-capability-id": "4565615b-1077-4bb5-a340-c5be48db2aaa",
+            "hpa-feature": "basicCapabilities",
+            "hpa-version": "v1",
+            "architecture": "generic",
+            "resource-version": "1520943846269",
+            "hpa-feature-attributes": [
+              {
+                "hpa-attribute-key": "virtualMemSize",
+                "hpa-attribute-value": "{\"value\":\"16\", \"unit\":\"GB\" }",
+                "resource-version": "1520943846282"
+              },
+              {
+                "hpa-attribute-key": "numVirtualCpu",
+                "hpa-attribute-value": "{\"value\":\"8\"}",
+                "resource-version": "1520943846272"
+              }
+            ]
+          },
+          {
+            "hpa-capability-id": "8fa22e64-41b4-471f-96ad-6c470868eo4c",
+            "hpa-feature": "sriovNICNetwork",
+            "hpa-version": "v1",
+            "architecture": "generic",
+            "resource-version": "1520943845443",
+            "hpa-feature-attributes": [
+              {
+                "hpa-attribute-key": "pciCount",
+                "hpa-attribute-value": "{\"value\":\"1\"}",
+                "resource-version": "1520943845870"
+              },
+              {
+                "hpa-attribute-key": "pciVendorId",
+                "hpa-attribute-value": "{\"value\": \"8086\"}",
+                "resource-version": "1520943845764"
+              },
+              {
+                "hpa-attribute-key": "pciDeviceId",
+                "hpa-attribute-value": "{\"value\": \"1234\"}",
+                "resource-version": "1520943847729"
+              },
+              {
+                "hpa-attribute-key": "physicalNetwork",
+                "hpa-attribute-value": "{\"value\": \"physnet1\"}",
+                "resource-version": "1520943871129"
+              }
+            ]
+          }
+
+        ]
+      },
+      "resource-version": "1520943439264"
+    },
     {
       "flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
       "flavor-name": "flavor-cpu-pinning-ovsdpdk-instruction-set",
index 4a5d37a..bfda6a7 100644 (file)
 [
-   [
-      {
-         "hpa-feature":"basicCapabilities",
-         "hpa-version":"v1",
-         "architecture":"generic",
-         "mandatory":"True",
-         "hpa-feature-attributes":[
+  [
+    {
+      "hpa-feature": "basicCapabilities",
+      "hpa-version": "v1",
+      "architecture": "generic",
+      "mandatory": "True",
+      "directives": [],
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "numVirtualCpu",
+          "hpa-attribute-value": "8",
+          "operator": "="
+        },
+        {
+          "hpa-attribute-key": "virtualMemSize",
+          "hpa-attribute-value": "16384",
+          "operator": "=",
+          "unit": "MB"
+        }
+      ]
+    },
+    {
+      "hpa-feature": "cpuPinning",
+      "hpa-version": "v1",
+      "architecture": "generic",
+      "mandatory": "True",
+      "directives": [],
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "logicalCpuThreadPinningPolicy",
+          "hpa-attribute-value": "prefer",
+          "operator": "="
+        },
+        {
+          "hpa-attribute-key": "logicalCpuPinningPolicy",
+          "hpa-attribute-value": "dedicated",
+          "operator": "="
+        }
+      ]
+    },
+    {
+      "hpa-feature": "cpuTopology",
+      "hpa-version": "v1",
+      "mandatory": "True",
+      "architecture": "generic",
+      "directives": [],
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "numCpuSockets",
+          "hpa-attribute-value": "2",
+          "operator": ">=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "numCpuSockets",
+          "hpa-attribute-value": "4",
+          "operator": "<=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "numCpuCores",
+          "hpa-attribute-value": "2",
+          "operator": ">=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "numCpuCores",
+          "hpa-attribute-value": "4",
+          "operator": "<=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "numCpuThreads",
+          "hpa-attribute-value": "4",
+          "operator": ">=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "numCpuThreads",
+          "hpa-attribute-value": "8",
+          "operator": "<=",
+          "unit": ""
+        }
+      ]
+    }
+  ],
+  [
+    {
+      "hpa-feature": "basicCapabilities",
+      "hpa-version": "v1",
+      "architecture": "generic",
+      "mandatory": "True",
+      "directives": [],
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "numVirtualCpu",
+          "hpa-attribute-value": "8",
+          "operator": "="
+        },
+        {
+          "hpa-attribute-key": "virtualMemSize",
+          "hpa-attribute-value": "16384",
+          "operator": "=",
+          "unit": "MB"
+        }
+      ]
+    },
+    {
+      "hpa-feature": "ovsDpdk",
+      "hpa-version": "v1",
+      "architecture": "generic",
+      "mandatory": "False",
+      "score": "5",
+      "directives": [],
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "dataProcessingAccelerationLibrary",
+          "hpa-attribute-value": "v18.02",
+          "operator": "="
+        }
+      ]
+    },
+    {
+      "hpa-feature": "cpuPinning",
+      "hpa-version": "v1",
+      "architecture": "generic",
+      "mandatory": "False",
+      "score": "1",
+      "directives": [],
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "logicalCpuThreadPinningPolicy",
+          "hpa-attribute-value": "prefer",
+          "operator": "="
+        },
+        {
+          "hpa-attribute-key": "logicalCpuPinningPolicy",
+          "hpa-attribute-value": "dedicated",
+          "operator": "="
+        }
+      ]
+    },
+    {
+      "hpa-feature": "instructionSetExtensions",
+      "hpa-version": "v1",
+      "architecture": "Intel64",
+      "mandatory": "False",
+      "score": "5",
+      "directives": [],
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "instructionSetExtensions",
+          "hpa-attribute-value": [
+            "A11",
+            "B22"
+          ],
+          "operator": "ALL"
+        }
+      ]
+    },
+    {
+      "hpa-feature": "cpuTopology",
+      "hpa-version": "v1",
+      "mandatory": "True",
+      "architecture": "generic",
+      "directives": [],
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "numCpuSockets",
+          "hpa-attribute-value": "2",
+          "operator": ">=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "numCpuSockets",
+          "hpa-attribute-value": "4",
+          "operator": "<=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "numCpuCores",
+          "hpa-attribute-value": "2",
+          "operator": ">=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "numCpuCores",
+          "hpa-attribute-value": "4",
+          "operator": "<=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "numCpuThreads",
+          "hpa-attribute-value": "4",
+          "operator": ">=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "numCpuThreads",
+          "hpa-attribute-value": "8",
+          "operator": "<=",
+          "unit": ""
+        }
+      ]
+    }
+  ],
+  [
+    {
+      "hpa-feature": "basicCapabilities",
+      "hpa-version": "v1",
+      "architecture": "generic",
+      "mandatory": "True",
+      "directives": [],
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "numVirtualCpu",
+          "hpa-attribute-value": "8",
+          "operator": "="
+        },
+        {
+          "hpa-attribute-key": "virtualMemSize",
+          "hpa-attribute-value": "16",
+          "operator": "=",
+          "unit": "GB"
+        }
+      ]
+    },
+    {
+      "hpa-feature": "ovsDpdk",
+      "hpa-version": "v1",
+      "architecture": "generic",
+      "mandatory": "False",
+      "score": "5",
+      "directives": [],
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "dataProcessingAccelerationLibrary",
+          "hpa-attribute-value": "v18.02",
+          "operator": "="
+        }
+      ]
+    },
+    {
+      "hpa-feature": "cpuPinning",
+      "hpa-version": "v1",
+      "architecture": "generic",
+      "mandatory": "False",
+      "score": "1",
+      "directives": [],
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "logicalCpuThreadPinningPolicy",
+          "hpa-attribute-value": "prefer",
+          "operator": "="
+        },
+        {
+          "hpa-attribute-key": "logicalCpuPinningPolicy",
+          "hpa-attribute-value": "dedicated",
+          "operator": "="
+        }
+      ]
+    },
+    {
+      "hpa-feature": "instructionSetExtensions",
+      "hpa-version": "v1",
+      "architecture": "Intel64",
+      "mandatory": "False",
+      "score": "5",
+      "directives": [],
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "instructionSetExtensions",
+          "hpa-attribute-value": [
+            "A11",
+            "B22"
+          ],
+          "operator": "ALL"
+        }
+      ]
+    },
+    {
+      "hpa-feature": "sriovNICNetwork",
+      "hpa-version": "v1",
+      "mandatory": "False",
+      "architecture": "generic",
+      "directives": [
+        {
+          "type": "sriovNICNetwork_directives",
+          "attributes": [
             {
-               "hpa-attribute-key":"numVirtualCpu",
-               "hpa-attribute-value":"8",
-               "operator":"="
-            },
-            {
-               "hpa-attribute-key":"virtualMemSize",
-               "hpa-attribute-value":"16384",
-               "operator":"=",
-               "unit":"MB"
-            }
-         ]
-      },
-      {
-         "hpa-feature":"cpuPinning",
-         "hpa-version":"v1",
-         "architecture":"generic",
-         "mandatory":"True",
-         "hpa-feature-attributes":[
-            {
-               "hpa-attribute-key":"logicalCpuThreadPinningPolicy",
-               "hpa-attribute-value":"prefer",
-               "operator":"="
-            },
-            {
-               "hpa-attribute-key":"logicalCpuPinningPolicy",
-               "hpa-attribute-value":"dedicated",
-               "operator":"="
-            }
-         ]
-      },
-      {
-         "hpa-feature":"cpuTopology",
-         "hpa-version":"v1",
-         "mandatory":"True",
-         "architecture":"generic",
-         "hpa-feature-attributes":[
-            {
-               "hpa-attribute-key":"numCpuSockets",
-               "hpa-attribute-value":"2",
-               "operator":">=",
-               "unit":""
-            },
-            {
-               "hpa-attribute-key":"numCpuSockets",
-               "hpa-attribute-value":"4",
-               "operator":"<=",
-               "unit":""
-            },
-            {
-               "hpa-attribute-key":"numCpuCores",
-               "hpa-attribute-value":"2",
-               "operator":">=",
-               "unit":""
-            },
-            {
-               "hpa-attribute-key":"numCpuCores",
-               "hpa-attribute-value":"4",
-               "operator":"<=",
-               "unit":""
-            },
-            {
-               "hpa-attribute-key":"numCpuThreads",
-               "hpa-attribute-value":"4",
-               "operator":">=",
-               "unit":""
-            },
-            {
-               "hpa-attribute-key":"numCpuThreads",
-               "hpa-attribute-value":"8",
-               "operator":"<=",
-               "unit":""
-            }
-         ]
-      }
-   ],
-   [
-      {
-         "hpa-feature":"basicCapabilities",
-         "hpa-version":"v1",
-         "architecture":"generic",
-         "mandatory":"True",
-         "hpa-feature-attributes":[
-            {
-               "hpa-attribute-key":"numVirtualCpu",
-               "hpa-attribute-value":"8",
-               "operator":"="
-            },
-            {
-               "hpa-attribute-key":"virtualMemSize",
-               "hpa-attribute-value":"16384",
-               "operator":"=",
-               "unit":"MB"
-            }
-         ]
-      },
-      {
-         "hpa-feature":"ovsDpdk",
-         "hpa-version":"v1",
-         "architecture":"generic",
-         "mandatory":"False",
-         "score":"5",
-         "hpa-feature-attributes":[
-            {
-               "hpa-attribute-key":"dataProcessingAccelerationLibrary",
-               "hpa-attribute-value":"v18.02",
-               "operator":"="
-            }
-         ]
-      },
-      {
-         "hpa-feature":"cpuPinning",
-         "hpa-version":"v1",
-         "architecture":"generic",
-         "mandatory":"False",
-         "score":"1",
-         "hpa-feature-attributes":[
-            {
-               "hpa-attribute-key":"logicalCpuThreadPinningPolicy",
-               "hpa-attribute-value":"prefer",
-               "operator":"="
-            },
-            {
-               "hpa-attribute-key":"logicalCpuPinningPolicy",
-               "hpa-attribute-value":"dedicated",
-               "operator":"="
-            }
-         ]
-      },
-      {
-         "hpa-feature":"instructionSetExtensions",
-         "hpa-version":"v1",
-         "architecture":"Intel64",
-         "mandatory":"False",
-         "score":"5",
-         "hpa-feature-attributes":[
-            {
-               "hpa-attribute-key":"instructionSetExtensions",
-               "hpa-attribute-value":[
-                  "A11",
-                  "B22"
-               ],
-               "operator":"ALL"
-            }
-         ]
-      },
-      {
-         "hpa-feature":"cpuTopology",
-         "hpa-version":"v1",
-         "mandatory":"True",
-         "architecture":"generic",
-         "hpa-feature-attributes":[
-            {
-               "hpa-attribute-key":"numCpuSockets",
-               "hpa-attribute-value":"2",
-               "operator":">=",
-               "unit":""
-            },
-            {
-               "hpa-attribute-key":"numCpuSockets",
-               "hpa-attribute-value":"4",
-               "operator":"<=",
-               "unit":""
-            },
-            {
-               "hpa-attribute-key":"numCpuCores",
-               "hpa-attribute-value":"2",
-               "operator":">=",
-               "unit":""
-            },
-            {
-               "hpa-attribute-key":"numCpuCores",
-               "hpa-attribute-value":"4",
-               "operator":"<=",
-               "unit":""
-            },
-            {
-               "hpa-attribute-key":"numCpuThreads",
-               "hpa-attribute-value":"4",
-               "operator":">=",
-               "unit":""
-            },
-            {
-               "hpa-attribute-key":"numCpuThreads",
-               "hpa-attribute-value":"8",
-               "operator":"<=",
-               "unit":""
+              "attribute_name": "A",
+              "attribute_value": "a"
             }
-         ]
-      }
-   ]
+          ]
+        }
+      ],
+      "score": "7",
+      "hpa-feature-attributes": [
+        {
+          "hpa-attribute-key": "pciCount",
+          "hpa-attribute-value": "1",
+          "operator": "=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "pciVendorId",
+          "hpa-attribute-value": "8086",
+          "operator": "=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "pciDeviceId",
+          "hpa-attribute-value": "1234",
+          "operator": "=",
+          "unit": ""
+        },
+        {
+          "hpa-attribute-key": "physicalNetwork",
+          "hpa-attribute-value": "physnet1",
+          "operator": "=",
+          "unit": ""
+        }
+      ]
+    }
+  ]
 ]
\ No newline at end of file
index 5713d04..435e0a9 100644 (file)
@@ -28,7 +28,6 @@ from oslo_config import cfg
 class TestAAI(unittest.TestCase):
 
     def setUp(self):
-
         CONF = cfg.CONF
         CONF.register_opts(aai.AAI_OPTS, group='aai')
         self.conf = CONF
@@ -38,20 +37,16 @@ class TestAAI(unittest.TestCase):
         mock.patch.stopall()
 
     def test_get_version_from_string(self):
-
         self.assertEqual("2.5", self.aai_ep._get_version_from_string("AAI2.5"))
         self.assertEqual("3.0", self.aai_ep._get_version_from_string("AAI3.0"))
 
     def test_aai_versioned_path(self):
-
         self.assertEqual('/{}/cloud-infrastructure/cloud-regions/?depth=0'.format(self.conf.aai.server_url_version),
                          self.aai_ep._aai_versioned_path("/cloud-infrastructure/cloud-regions/?depth=0"))
         self.assertEqual('/{}/query?format=id'.format(self.conf.aai.server_url_version),
                          self.aai_ep._aai_versioned_path("/query?format=id"))
 
-
     def test_resolve_clli_location(self):
-
         req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_clli_location.json'
         req_json = json.loads(open(req_json_file).read())
 
@@ -62,11 +57,10 @@ class TestAAI(unittest.TestCase):
 
         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
         self.mock_get_request.start()
-        self.assertEqual({'country': u'USA', 'latitude': u'40.39596', 'longitude': u'-74.135342'} ,
-                        self.aai_ep.resolve_clli_location("clli_code"))
+        self.assertEqual({'country': u'USA', 'latitude': u'40.39596', 'longitude': u'-74.135342'},
+                         self.aai_ep.resolve_clli_location("clli_code"))
 
     def test_get_inventory_group_pair(self):
-
         req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_inventory_group_pair.json'
         req_json = json.loads(open(req_json_file).read())
 
@@ -77,11 +71,10 @@ class TestAAI(unittest.TestCase):
 
         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
         self.mock_get_request.start()
-        self.assertEqual([[u'instance-1', u'instance-2']] ,
-                        self.aai_ep.get_inventory_group_pairs("service_description"))
+        self.assertEqual([[u'instance-1', u'instance-2']],
+                         self.aai_ep.get_inventory_group_pairs("service_description"))
 
     def test_resolve_host_location(self):
-
         req_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_host_name.json'
         req_json = json.loads(open(req_json_file).read())
 
@@ -99,11 +92,10 @@ class TestAAI(unittest.TestCase):
         self.mock_get_complex = mock.patch.object(AAI, '_get_complex', return_value=complex_json)
         self.mock_get_complex.start()
 
-        self.assertEqual({'country': u'USA', 'latitude': u'28.543251', 'longitude': u'-81.377112'} ,
+        self.assertEqual({'country': u'USA', 'latitude': u'28.543251', 'longitude': u'-81.377112'},
                          self.aai_ep.resolve_host_location("host_name"))
 
     def test_resolve_demands(self):
-
         self.assertEqual({}, self.aai_ep.resolve_demands(dict()))
 
         demands_list_file = './conductor/tests/unit/data/plugins/inventory_provider/demand_list.json'
@@ -126,7 +118,8 @@ class TestAAI(unittest.TestCase):
         req_response.ok = True
         req_response.json.return_value = demand_service_response
 
-        self.mock_first_level_service_call = mock.patch.object(AAI, 'first_level_service_call', return_value=generic_vnf_list)
+        self.mock_first_level_service_call = mock.patch.object(AAI, 'first_level_service_call',
+                                                               return_value=generic_vnf_list)
         self.mock_first_level_service_call.start()
 
         self.mock_get_regions = mock.patch.object(AAI, '_get_regions', return_value=regions_response)
@@ -167,7 +160,6 @@ class TestAAI(unittest.TestCase):
             self.aai_ep.resolve_demands(demands_list))
 
     def test_get_complex(self):
-
         complex_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_get_complex.json'
         complex_json = json.loads(open(complex_json_file).read())
 
@@ -179,12 +171,12 @@ class TestAAI(unittest.TestCase):
         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
         self.mock_get_request.start()
 
-        self.assertEqual({u'city': u'Middletown', u'latitude': u'28.543251', u'longitude': u'-81.377112', u'country': u'USA', u'region': u'SE'} ,
-                         self.aai_ep._get_complex("/v10/complex/complex_id", "complex_id"))
-
+        self.assertEqual(
+            {u'city': u'Middletown', u'latitude': u'28.543251', u'longitude': u'-81.377112', u'country': u'USA',
+             u'region': u'SE'},
+            self.aai_ep._get_complex("/v10/complex/complex_id", "complex_id"))
 
     def test_check_network_roles(self):
-
         network_role_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_network_role.json'
         network_role_json = json.loads(open(network_role_json_file).read())
 
@@ -195,12 +187,10 @@ class TestAAI(unittest.TestCase):
 
         self.mock_get_request = mock.patch.object(AAI, '_request', return_value=response)
         self.mock_get_request.start()
-        self.assertEqual(set(['test-cloud-value']) ,
-                        self.aai_ep.check_network_roles("network_role_id"))
-
+        self.assertEqual(set(['test-cloud-value']),
+                         self.aai_ep.check_network_roles("network_role_id"))
 
     def test_check_candidate_role(self):
-
         candidate_role_json_file = './conductor/tests/unit/data/plugins/inventory_provider/_request_candidate_role.json'
         candidate_role_json = json.loads(open(candidate_role_json_file).read())
 
@@ -223,7 +213,8 @@ class TestAAI(unittest.TestCase):
         inventory_attributes['attr-1'] = 'attr-1-value1'
 
         self.assertEqual(True,
-                         self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes, "candidate-id"))
+                         self.aai_ep.match_inventory_attributes(template_attributes, inventory_attributes,
+                                                                "candidate-id"))
 
         template_attributes['attr-1'] = {
             'not': ['attr-1-value2']
@@ -268,7 +259,6 @@ class TestAAI(unittest.TestCase):
                          self.aai_ep._refresh_cache())
 
     def test_get_aai_rel_link(self):
-
         relatonship_response_file = './conductor/tests/unit/data/plugins/inventory_provider/relationship_list.json'
         relatonship_response = json.loads(open(relatonship_response_file).read())
         related_to = "service-instance"
@@ -301,7 +291,7 @@ class TestAAI(unittest.TestCase):
 
     def test_match_hpa(self):
         flavor_json_file = \
-           './conductor/tests/unit/data/plugins/inventory_provider/hpa_flavors.json'
+            './conductor/tests/unit/data/plugins/inventory_provider/hpa_flavors.json'
         flavor_json = json.loads(open(flavor_json_file).read())
         feature_json_file = \
             './conductor/tests/unit/data/plugins/inventory_provider/hpa_req_features.json'
@@ -310,17 +300,34 @@ class TestAAI(unittest.TestCase):
         candidate_json = json.loads(open(candidate_json_file).read())
         candidate_json['candidate_list'][1]['flavors'] = flavor_json
 
-        flavor_map = {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
-                      "flavor-name": "flavor-cpu-pinning-ovsdpdk-instruction-set",
-                      "score": 0}
+        flavor_map = {
+            "directives": [],
+            "flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
+                           "flavor-name": "flavor-cpu-pinning-ovsdpdk-instruction-set",
+                           "score": 0}}
         self.assertEqual(flavor_map,
                          self.aai_ep.match_hpa(candidate_json['candidate_list'][1],
                                                feature_json[0]))
 
-        flavor_map = {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
-                      "flavor-name": "flavor-cpu-ovsdpdk-instruction-set",
-                      "score": 10}
+        flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf041b098c43",
+                                     "flavor-name": "flavor-cpu-ovsdpdk-instruction-set",
+                                     "score": 10},
+                      "directives": []}
         self.assertEqual(flavor_map,
-             self.aai_ep.match_hpa(candidate_json['candidate_list'][1],
-                                   feature_json[1]))
-
+                         self.aai_ep.match_hpa(candidate_json['candidate_list'][1],
+                                               feature_json[1]))
+        flavor_map = {"flavor_map": {"flavor-id": "f5aa2b2e-3206-41b6-80d5-cf6t2b098c43",
+                                     "flavor-name": "flavor-ovsdpdk-cpu-pinning-sriov-NIC-Network-set",
+                                     "score": 13},
+                      "directives": [{
+                          "type": "sriovNICNetwork_directives",
+                          "attributes": [
+                              {
+                                  "attribute_name": "A",
+                                  "attribute_value": "a"
+                              }
+                          ]
+                      }]}
+        self.assertEqual(flavor_map,
+                         self.aai_ep.match_hpa(candidate_json['candidate_list'][1],
+                                               feature_json[2]))
index 8c74097..7953f3f 100644 (file)
@@ -238,25 +238,38 @@ class TestDataEndpoint(unittest.TestCase):
             hpa_json["conductor_solver"]["constraints"][0].items()[0]
         hpa_constraint = constraint_info['properties']
         flavorProperties = hpa_constraint['evaluate'][0]['flavorProperties']
-        label_name = hpa_constraint['evaluate'][0]['flavorLabel']
+        id = hpa_constraint['evaluate'][0]['id']
+        type = hpa_constraint['evaluate'][0]['type']
+        directives = hpa_constraint['evaluate'][0]['directives']
+        attr = directives[0].get("attributes")
+        label_name = attr[0].get("attribute_name")
         ext_mock1.return_value = ['aai']
         flavor_info = {"flavor-id": "vim-flavor-id1",
-                       "flavor-name": "vim-flavor-name1",
-                       "score": 0}
+                       "flavor-name": "vim-flavor-name1"}
+        directive = [
+            {
+                "id": id,
+                "type": type,
+                "directives": directives
+            }
+        ]
         hpa_mock.return_value = [flavor_info]
         self.maxDiff = None
-        args = generate_args(candidate_list, flavorProperties, label_name)
+        args = generate_args(candidate_list, flavorProperties, id, type, directives)
         hpa_candidate_list = copy.deepcopy(candidate_list)
         hpa_candidate_list[1]['flavor_map'] = {}
         hpa_candidate_list[1]['flavor_map'][label_name] = "vim-flavor-name1"
-        hpa_candidate_list[1]['hpa_score'] = 0
-        expected_response = {'response': hpa_candidate_list, 'error': False}
+        hpa_candidate_list[1]['all_directives'] = {}
+        hpa_candidate_list[1]['all_directives']['directives'] = directive
+        hpa_candidate_list1 = []
+        hpa_candidate_list1.append(hpa_candidate_list[0])
+        expected_response = {'response': hpa_candidate_list1, 'error': False}
         self.assertEqual(expected_response,
                          self.data_ep.get_candidates_with_hpa(None, args))
 
         hpa_candidate_list2 = list()
         hpa_candidate_list2.append(copy.deepcopy(candidate_list[0]))
-        args = generate_args(candidate_list, flavorProperties, label_name)
+        args = generate_args(candidate_list, flavorProperties, id, type, directives)
         hpa_mock.return_value = []
         expected_response = {'response': hpa_candidate_list2, 'error': False}
         self.assertEqual(expected_response,
@@ -322,11 +335,13 @@ class TestDataEndpoint(unittest.TestCase):
                                                                        args))
 
 
-def generate_args(candidate_list, flavorProperties, label_name):
+def generate_args(candidate_list, flavorProperties, vf_id, model_type, directives):
     arg_candidate_list = copy.deepcopy(candidate_list)
     args = {"candidate_list": arg_candidate_list,
             "flavorProperties": flavorProperties,
-            "label_name": label_name}
+            "id": vf_id,
+            "type": model_type,
+            "directives": directives}
     return args
 
 def ip_ext_sideeffect(*args, **kwargs):
index 829eaf3..5f9c4c5 100644 (file)
@@ -13,6 +13,7 @@
                   {
                     "architecture": "generic",
                     "hpa-feature": "basicCapabilities",
+                    "directives": [],
                     "hpa-feature-attributes": [
                       {
                         "hpa-attribute-key": "numVirtualCpu",
@@ -31,6 +32,7 @@
                   {
                     "architecture": "generic",
                     "hpa-feature": "numa",
+                    "directives": [],
                     "hpa-feature-attributes": [
                       {
                         "hpa-attribute-key": "numaNodes",
@@ -65,6 +67,7 @@
                   {
                     "architecture": "generic",
                     "hpa-feature": "cpuPinning",
+                    "directives": [],
                     "hpa-feature-attributes": [
                       {
                         "hpa-attribute-key": "logicalCpuThreadPinningPolicy",
                     "hpa-version": "v1"
                   }
                 ],
-                "flavorLabel": "flavor_label_1"
+                "id": "vg_1",
+                "type": "vnfc",
+                "directives": [
+                  {
+                    "type": "flavor_directives",
+                    "attributes": [
+                      {
+                        "attribute_name": "flavor_label_1",
+                        "attribute_value": ""
+                      }
+                    ]
+                  }
+                ]
               },
               {
                 "flavorProperties": [
                         "unit": "GB"
                       }
                     ],
-                    "hpa-version": "v1"
+                    "hpa-version": "v1",
+                    "directives": []
                   },
                   {
                     "architecture": "generic",
                         "unit": "GB"
                       }
                     ],
-                    "hpa-version": "v1"
+                    "hpa-version": "v1",
+                    "directives": []
                   },
                   {
                     "architecture": "generic",
                         "unit": "GB"
                       }
                     ],
-                    "hpa-version": "v1"
+                    "hpa-version": "v1",
+                    "directives": []
                   }
                 ],
-                "flavorLabel": "flavor_label_2"
+                "id": "vg_2",
+                "type": "vnfc",
+                "directives": [
+                  {
+                    "type": "flavor_directives",
+                    "attributes": [
+                      {
+                        "attribute_name": "flavor_label_2",
+                        "attribute_value": ""
+                      }
+                    ]
+                  }
+                ]
               }
             ]
           }