aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/nst/optimizers/nst_select_processor.py90
-rw-r--r--config/common_config.yaml23
-rw-r--r--osdf/adapters/conductor/translation.py1
-rwxr-xr-xosdfapp.py2
-rw-r--r--test/policy-local-files/nst-selection-files/attribute_policy_nst.json42
-rw-r--r--test/policy-local-files/nst-selection-files/optimization_policy_nst.json37
-rw-r--r--test/policy-local-files/nst-selection-files/query_policy_nst.json31
-rw-r--r--test/policy-local-files/nst-selection-files/vnf_policy_nst.json34
8 files changed, 231 insertions, 29 deletions
diff --git a/apps/nst/optimizers/nst_select_processor.py b/apps/nst/optimizers/nst_select_processor.py
index faab999..5b31f73 100644
--- a/apps/nst/optimizers/nst_select_processor.py
+++ b/apps/nst/optimizers/nst_select_processor.py
@@ -18,8 +18,10 @@
"""
This application generates NST SELECTION API calls using the information received from SO
"""
-import json
import os
+from osdf.adapters.conductor import conductor
+from osdf.adapters.policy.interface import get_policies
+from osdf.logging.osdf_logging import debug_log
from osdf.logging.osdf_logging import error_log
from osdf.utils.interfaces import get_rest_client
from requests import RequestException
@@ -38,6 +40,7 @@ class NstSelection(Thread):
self.osdf_config = osdf_config
self.request_json = request_json
self.request_info = self.request_json['requestInfo']
+ self.request_info['numSolutions'] = 1
def run(self):
self.process_nst_selection()
@@ -52,7 +55,6 @@ class NstSelection(Thread):
try:
rest_client = get_rest_client(self.request_json, service='so')
solution = self.get_nst_solution()
- solution = self.get_nst_selection_response(solution)
except Exception as err:
error_log.error("Error for {} {}".format(self.request_info.get('requestId'),
traceback.format_exc()))
@@ -70,32 +72,12 @@ class NstSelection(Thread):
integrated there...
"""
-
- config_input_json = os.path.join(BASE_DIR, 'conf/configIinputs.json')
- with open(config_input_json, 'r') as openfile:
- service_profile = self.request_json["serviceProfile"]
- nst_solution_list = []
- resource_name = "NST"
- nst_object = json.load(openfile)
- for nst in nst_object[resource_name]:
- [(nst_name, nst_list)] = nst.items()
- individual_nst = dict()
- matchall = False
- for constraint_name in service_profile:
- constraint_value = nst_list.get(constraint_name)
- if not constraint_value:
- matchall = False
- break
- else:
- matchall = True
- if matchall:
- individual_nst["NSTName"] = nst_list.get("name")
- individual_nst["UUID"] = nst_list.get("modeluuid")
- individual_nst["invariantUUID"] = nst_list.get("modelinvariantuuid")
- individual_nst["individual_nst"] = 1
- nst_solution_list.append(individual_nst)
-
- return nst_solution_list
+ req_info = self.request_json['requestInfo']
+ requirements = self.request_json['serviceProfile']
+ model_name = "nst"
+ policies = self.get_app_policies(model_name, "nst_selection")
+ conductor_response = self.get_conductor(req_info, requirements, policies, model_name)
+ return conductor_response
def get_nst_selection_response(self, solutions):
"""Get NST selection response from final solution
@@ -119,3 +101,55 @@ class NstSelection(Thread):
'transactionId': self.request_info['transactionId'],
'requestStatus': 'error',
'statusMessage': error_message}
+
+ def get_app_policies(self, model_name, app_name):
+ policy_request_json = self.request_json.copy()
+ policy_request_json['serviceInfo'] = {'serviceName': model_name}
+ debug_log.debug("policy_request_json {}".format(str(policy_request_json)))
+ return get_policies(policy_request_json, app_name) # app_name: nst_selection
+
+ def get_conductor(self, req_info, request_parameters, policies, model_name):
+ demands = [
+ {
+ "resourceModuleName": model_name,
+ "resourceModelInfo": {}
+ }
+ ]
+
+ try:
+ template_fields = {
+ 'location_enabled': False,
+ 'version': '2020-08-13'
+ }
+ resp = conductor.request(req_info, demands, request_parameters, {}, template_fields,
+ self.osdf_config, policies)
+ except RequestException as e:
+ resp = e.response.json()
+ error = resp['plans'][0]['message']
+ if "Unable to find any" in error:
+ return self.get_nst_selection_response([])
+ error_log.error('Error from conductor {}'.format(error))
+ return self.error_response(error)
+ debug_log.debug("Response from conductor in get_conductor method {}".format(str(resp)))
+ recommendations = resp["plans"][0].get("recommendations")
+ return self.process_response(recommendations, model_name)
+
+ def process_response(self, recommendations, model_name):
+ """Process conductor response to form the response for the API request
+
+ :param recommendations: recommendations from conductor
+ :return: response json as a dictionary
+ """
+ if not recommendations:
+ return self.get_nst_selection_response([])
+ solutions = [self.get_solution_from_candidate(rec[model_name]['candidate'])
+ for rec in recommendations]
+ return self.get_nst_selection_response(solutions)
+
+ def get_solution_from_candidate(self, candidate):
+ if candidate['inventory_type'] == 'nst':
+ return {
+ 'UUID': candidate['model_version_id'],
+ 'invariantUUID': candidate['model_invariant_id'],
+ 'NSTName': candidate['name'],
+ }
diff --git a/config/common_config.yaml b/config/common_config.yaml
index d720fb2..d4d205e 100644
--- a/config/common_config.yaml
+++ b/config/common_config.yaml
@@ -12,6 +12,7 @@ osdf_temp: # special configuration required for "workarounds" or testing
global_disabled: True
local_placement_policies_enabled: True
local_slice_selection_policies_enabled: True
+ local_nst_selection_policies_enabled: True
placement_policy_dir_vcpe: "./test/policy-local-files/"
placement_policy_files_vcpe: # workaroud for policy platform glitches (or "work-arounds" for other components)
- Affinity_vCPE_1.json
@@ -45,6 +46,17 @@ osdf_temp: # special configuration required for "workarounds" or testing
- query_policy_nsi.json
- threshold_policy_nsi.json
- vnf_policy_nsi_shared_case.json
+ nst_selection_policy_dir_embb-nst: "./test/policy-local-files/nst-selection-files/"
+ nst_selection_policy_files_embb-nst:
+ - query_policy_nst.json
+ - attribute_policy_nst.json
+ - vnf_policy_nst.json
+ nst_selection_policy_dir_nst: "./test/policy-local-files/nst-selection-files/"
+ nst_selection_policy_files_nst:
+ - query_policy_nst.json
+ - attribute_policy_nst.json
+ - vnf_policy_nst.json
+ - optimization_policy_nst.json
service_info:
vCPE:
@@ -89,6 +101,17 @@ policy_info:
resources:
- get_param: service_name
+ nst_selection:
+ policy_fetch: by_scope
+ policy_scope:
+ -
+ scope:
+ - OSDF_GUILIN
+ services:
+ - nst
+ resources:
+ - nst
+
subnet_selection:
policy_fetch: by_scope
policy_scope:
diff --git a/osdf/adapters/conductor/translation.py b/osdf/adapters/conductor/translation.py
index 238428a..f44f27f 100644
--- a/osdf/adapters/conductor/translation.py
+++ b/osdf/adapters/conductor/translation.py
@@ -320,7 +320,6 @@ def get_demand_properties(demand, policies):
prop['filtering_attributes'].update({'equipment-role': policy_property['equipmentRole']}
if 'equipmentRole' in policy_property and policy_property['equipmentRole']
else {})
-
prop.update(get_candidates_demands(demand))
demand_properties.append(prop)
return demand_properties
diff --git a/osdfapp.py b/osdfapp.py
index df85343..28f9376 100755
--- a/osdfapp.py
+++ b/osdfapp.py
@@ -126,7 +126,9 @@ def do_mdons_route_calc():
def do_nst_selection():
request_json = request.get_json()
req_id = request_json['requestInfo']['requestId']
+ audit_log.info(MH.received_request(request.url, request.remote_addr, json.dumps(request_json)))
NSTSelectionAPI(request_json).validate()
+ audit_log.info(MH.new_worker_thread(req_id, "[for NST selection]"))
nst_selection = NstSelection(osdf_config, request_json)
nst_selection.start()
return req_accept(request_id=req_id,
diff --git a/test/policy-local-files/nst-selection-files/attribute_policy_nst.json b/test/policy-local-files/nst-selection-files/attribute_policy_nst.json
new file mode 100644
index 0000000..0989927
--- /dev/null
+++ b/test/policy-local-files/nst-selection-files/attribute_policy_nst.json
@@ -0,0 +1,42 @@
+{
+ "Threshold_nst": {
+ "metadata": {
+ "policy-id": "Threshold_nst",
+ "policy-version": 1
+ },
+ "properties": {
+ "geography": [],
+ "identity": "nst_Threshold",
+ "resources": [
+ "nst"
+ ],
+ "scope": [
+ "OSDF_GUILIN"
+ ],
+ "services": [
+ "nst"
+ ],
+ "thresholdProperties": [
+ {
+ "attribute": "latency",
+ "operator": "lte",
+ "threshold": {
+ "get_param": "latency"
+ },
+ "unit": "ms"
+ },
+ {
+ "attribute": "reliability",
+ "operator": "gte",
+ "threshold": {
+ "get_param": "reliability"
+ },
+ "unit": ""
+ }
+ ]
+ },
+ "type": "onap.policies.optimization.resource.ThresholdPolicy",
+ "type_version": "1.0.0",
+ "version": "1.0.0"
+ }
+} \ No newline at end of file
diff --git a/test/policy-local-files/nst-selection-files/optimization_policy_nst.json b/test/policy-local-files/nst-selection-files/optimization_policy_nst.json
new file mode 100644
index 0000000..27c1f7c
--- /dev/null
+++ b/test/policy-local-files/nst-selection-files/optimization_policy_nst.json
@@ -0,0 +1,37 @@
+{
+ "nst_minimize_latency": {
+ "metadata": {
+ "policy-id": "nst_minimize_latency",
+ "policy-version": 1
+ },
+ "properties": {
+ "geography": [],
+ "identity": "optimization",
+ "goal": "minimize",
+ "operation_function": {
+ "operator": "sum",
+ "operands": [
+ {
+ "function": "attribute",
+ "params": {
+ "attribute": "latency",
+ "demand": "nst"
+ }
+ }
+ ]
+ },
+ "resources": [
+ "nst"
+ ],
+ "scope": [
+ "OSDF_GUILIN"
+ ],
+ "services": [
+ "nst"
+ ]
+ },
+ "type": "onap.policies.optimization.resource.OptimizationPolicy",
+ "type_version": "2.0.0",
+ "version": "1.0.0"
+ }
+} \ No newline at end of file
diff --git a/test/policy-local-files/nst-selection-files/query_policy_nst.json b/test/policy-local-files/nst-selection-files/query_policy_nst.json
new file mode 100644
index 0000000..1955e7b
--- /dev/null
+++ b/test/policy-local-files/nst-selection-files/query_policy_nst.json
@@ -0,0 +1,31 @@
+{
+ "queryPolicy_nst": {
+ "type": "onap.policies.optimization.service.QueryPolicy",
+ "version": "1.0.0",
+ "type_version": "1.0.0",
+ "metadata": {
+ "policy-id": "queryPolicy_nst",
+ "policy-version": 1
+ },
+ "properties": {
+ "scope": [
+ "OSDF_GUILIN"
+ ],
+ "services": [
+ "nst"
+ ],
+ "geography": [],
+ "identity": "queryPolicy_nst",
+ "queryProperties": [
+ {
+ "attribute": "latency",
+ "attribute_location": "latency"
+ },
+ {
+ "attribute": "reliability",
+ "attribute_location": "reliability"
+ }
+ ]
+ }
+ }
+} \ No newline at end of file
diff --git a/test/policy-local-files/nst-selection-files/vnf_policy_nst.json b/test/policy-local-files/nst-selection-files/vnf_policy_nst.json
new file mode 100644
index 0000000..14906df
--- /dev/null
+++ b/test/policy-local-files/nst-selection-files/vnf_policy_nst.json
@@ -0,0 +1,34 @@
+{
+ "vnfPolicy_nst": {
+ "type": "onap.policies.optimization.resource.VnfPolicy",
+ "version": "1.0.0",
+ "type_version": "1.0.0",
+ "metadata": {
+ "policy-id": "vnfPolicy_nst",
+ "policy-version": 1
+ },
+ "properties": {
+ "scope": [
+ "OSDF_GUILIN"
+ ],
+ "resources": [
+ "nst"
+ ],
+ "services": [
+ "nst"
+ ],
+ "identity": "vnf_nst",
+ "applicableResources": "any",
+ "vnfProperties": [
+ {
+ "inventoryProvider": "aai",
+ "inventoryType": "nst",
+ "unique": "true",
+ "attributes": {
+ "model-role": "nst"
+ }
+ }
+ ]
+ }
+ }
+} \ No newline at end of file