From 231252b878029f8d2ec2859bf2d60212f350db32 Mon Sep 17 00:00:00 2001 From: krishnaa96 Date: Tue, 6 Oct 2020 10:27:35 +0530 Subject: Fix bugs related to slice selection Issue-ID: OPTFRA-855 Signed-off-by: krishnaa96 Change-Id: I3ca5bf8c0f22a6ce2ae84c3286c9977fe2d22744 --- .../plugins/inventory_provider/utils/aai_utils.py | 4 +- conductor/conductor/solver/service.py | 112 ++++++++++----------- .../plugins/inventory_provider/nsi_response.json | 2 +- .../plugins/inventory_provider/nssi_response.json | 4 +- 4 files changed, 60 insertions(+), 62 deletions(-) (limited to 'conductor') diff --git a/conductor/conductor/data/plugins/inventory_provider/utils/aai_utils.py b/conductor/conductor/data/plugins/inventory_provider/utils/aai_utils.py index 8a11070..ee870d4 100644 --- a/conductor/conductor/data/plugins/inventory_provider/utils/aai_utils.py +++ b/conductor/conductor/data/plugins/inventory_provider/utils/aai_utils.py @@ -76,6 +76,6 @@ def get_instance_info(nxi_instance): nxi_dict = dict() nxi_dict['instance_id'] = nxi_instance.get('service-instance-id') nxi_dict['instance_name'] = nxi_instance.get('service-instance-name') - if nxi_instance.get('service-function'): - nxi_dict['domain'] = nxi_instance.get('service-function') + if nxi_instance.get('workload-context'): + nxi_dict['domain'] = nxi_instance.get('workload-context') return nxi_dict diff --git a/conductor/conductor/solver/service.py b/conductor/conductor/solver/service.py index 3d0d8fa..e147661 100644 --- a/conductor/conductor/solver/service.py +++ b/conductor/conductor/solver/service.py @@ -19,34 +19,34 @@ # import collections - -import conductor.common.prometheus_metrics as PC import cotyledon import json +import socket import time import traceback -import json -import socket -import json + from oslo_config import cfg from oslo_log import log -from conductor.common.models import plan, region_placeholders, country_latency, group_rules, groups +from conductor.common.models import country_latency from conductor.common.models import order_lock +from conductor.common.models.order_lock import OrderLock from conductor.common.models import order_lock_history +from conductor.common.models import plan +from conductor.common.models import region_placeholders +from conductor.common.models import triage_tool from conductor.common.music import api from conductor.common.music import messaging as music_messaging from conductor.common.music.model import base -from conductor.i18n import _LE, _LI +import conductor.common.prometheus_metrics as PC +from conductor.common.utils import conductor_logging_util as log_util +from conductor.i18n import _LE +from conductor.i18n import _LI from conductor import messaging from conductor import service from conductor.solver.optimizer import optimizer from conductor.solver.request import parser from conductor.solver.utils import constraint_engine_interface as cei -from conductor.common.utils import conductor_logging_util as log_util -from conductor.common.models.order_lock import OrderLock -from conductor.common.models import triage_tool -from conductor.common.models.triage_tool import TriageTool # To use oslo.log in services: # @@ -138,7 +138,7 @@ class SolverServiceLauncher(object): # Dynamically create a plan class for the specified keyspace self.Plan = base.create_dynamic_model( keyspace=conf.keyspace, baseclass=plan.Plan, classname="Plan") - self.OrderLock =base.create_dynamic_model( + self.OrderLock = base.create_dynamic_model( keyspace=conf.keyspace, baseclass=order_lock.OrderLock, classname="OrderLock") self.OrderLockHistory = base.create_dynamic_model( keyspace=conf.keyspace, baseclass=order_lock_history.OrderLockHistory, classname="OrderLockHistory") @@ -147,10 +147,10 @@ class SolverServiceLauncher(object): self.CountryLatency = base.create_dynamic_model( keyspace=conf.keyspace, baseclass=country_latency.CountryLatency, classname="CountryLatency") self.TriageTool = base.create_dynamic_model( - keyspace=conf.keyspace, baseclass=triage_tool.TriageTool ,classname = "TriageTool") - #self.Groups = base.create_dynamic_model( + keyspace=conf.keyspace, baseclass=triage_tool.TriageTool, classname="TriageTool") + # self.Groups = base.create_dynamic_model( # keyspace=conf.keyspace, baseclass=groups.Groups, classname="Groups") - #self.GroupRules = base.create_dynamic_model( + # self.GroupRules = base.create_dynamic_model( # keyspace=conf.keyspace, baseclass=group_rules.GroupRules, classname="GroupRules") # Initialize Prometheus metrics Endpoint @@ -169,10 +169,6 @@ class SolverServiceLauncher(object): raise if not self.TriageTool: raise - #if not self.Groups: - # raise - #if not self.GroupRules: - # raise def run(self): kwargs = {'plan_class': self.Plan, @@ -181,8 +177,6 @@ class SolverServiceLauncher(object): 'region_placeholders': self.RegionPlaceholders, 'country_latency': self.CountryLatency, 'triage_tool': self.TriageTool - #'groups': self.Groups, - #'group_rules': self.GroupRules } # kwargs = {'plan_class': self.Plan} svcmgr = cotyledon.ServiceManager() @@ -204,7 +198,7 @@ class SolverService(cotyledon.Service): def __init__(self, worker_id, conf, **kwargs): """Initializer""" - LOG.debug("%s" % self.__class__.__name__) + LOG.debug({}.format(self.__class__.__name__)) super(SolverService, self).__init__(worker_id) self._init(conf, **kwargs) self.running = True @@ -217,13 +211,10 @@ class SolverService(cotyledon.Service): self.Plan = kwargs.get('plan_class') self.OrderLock = kwargs.get('order_locks') self.OrderLockHistory = kwargs.get('order_locks_history') - #self.OrderLock =kwargs.get('order_locks') self.RegionPlaceholders = kwargs.get('region_placeholders') self.CountryLatency = kwargs.get('country_latency') self.TriageTool = kwargs.get('triage_tool') - # self.Groups = kwargs.get('groups') - #self.GroupRules = kwargs.get('group_rules') # Set up the RPC service(s) we want to talk to. self.data_service = self.setup_rpc(conf, "data") @@ -272,7 +263,7 @@ class SolverService(cotyledon.Service): def millisec_to_sec(self, millisec): """Convert milliseconds to seconds""" - return millisec/1000 + return millisec / 1000 def setup_rpc(self, conf, topic): """Set up the RPC Client""" @@ -285,9 +276,8 @@ class SolverService(cotyledon.Service): return client def run(self): - """Run""" - LOG.debug("%s" % self.__class__.__name__) + LOG.debug({}.format(self.__class__.__name__)) # TODO(snarayanan): This is really meant to be a control loop # As long as self.running is true, we process another request. @@ -312,7 +302,6 @@ class SolverService(cotyledon.Service): translated_plans = self.Plan.query.get_plan_by_col("status", self.Plan.TRANSLATED) solving_plans = self.Plan.query.get_plan_by_col("status", self.Plan.SOLVING) - # combine the plans with status = 'translated' and 'solving' together plans = translated_plans + solving_plans @@ -323,8 +312,8 @@ class SolverService(cotyledon.Service): json_template = p.translation found_translated_template = True break - elif p.status == self.Plan.SOLVING and \ - (self.current_time_seconds() - self.millisec_to_sec(p.updated)) > self.conf.solver.timeout: + elif p.status == self.Plan.SOLVING and (self.current_time_seconds() + - self.millisec_to_sec(p.updated)) > self.conf.solver.timeout: p.status = self.Plan.TRANSLATED p.update(condition=self.solving_status_condition) break @@ -340,8 +329,8 @@ class SolverService(cotyledon.Service): continue if found_translated_template and p and p.solver_counter >= self.conf.solver.max_solver_counter: - message = _LE("Tried {} times. Plan {} is unable to solve")\ - .format(self.conf.solver.max_solver_counter, p.id) + message = _LE("Tried {} times. Plan {} is unable to solve").format(self.conf.solver.max_solver_counter, + p.id) LOG.error(message) p.status = self.Plan.ERROR p.message = message @@ -363,7 +352,7 @@ class SolverService(cotyledon.Service): continue LOG.info(_LI("Sovling starts, changing the template status from translated to solving, " - "atomic update response from MUSIC {}").format(_is_updated)) + "atomic update response from MUSIC {}").format(_is_updated)) LOG.info(_LI("Plan {} with request id {} is solving by machine {}. Tried to solve it for {} times."). format(p.id, p.name, p.solver_owner, p.solver_counter)) @@ -378,7 +367,7 @@ class SolverService(cotyledon.Service): if num_solution.isdigit(): num_solution = int(num_solution) - #TODO(inam/larry): move this part of logic inside of parser and don't apply it to distance_between + # TODO(inam/larry): move this part of logic inside of parser and don't apply it to distance_between try: # getting region placeholders from database and insert/put into regions_maps dictionary region_placeholders = self.RegionPlaceholders.query.all() @@ -396,7 +385,7 @@ class SolverService(cotyledon.Service): if len(countries) == 0: LOG.info("country is not present is country latency table, looking for * wildcard entry") - countries = self.CountryLatency.query.get_plan_by_col("country_name","*") + countries = self.CountryLatency.query.get_plan_by_col("country_name", "*") if len(countries) != 0: LOG.info("Found '*' wild card entry in country latency table") else: @@ -474,7 +463,8 @@ class SolverService(cotyledon.Service): else: is_rehome = "false" if resource.get("existing_placement") == 'true' else "true" - location_id = "" if resource.get("cloud_region_version") == '2.5' else resource.get("location_id") + location_id = "" if resource.get("cloud_region_version") == '2.5' \ + else resource.get("location_id") rec = { # FIXME(shankar) A&AI must not be hardcoded here. @@ -488,8 +478,7 @@ class SolverService(cotyledon.Service): "cloud_owner": resource.get("cloud_owner"), "location_type": resource.get("location_type"), "location_id": location_id, - "is_rehome": is_rehome, - }, + "is_rehome": is_rehome}, "attributes": { "physical-location-id": resource.get("physical_location_id"), @@ -497,7 +486,7 @@ class SolverService(cotyledon.Service): 'aic_version': resource.get("cloud_region_version")}, } - if rec["candidate"]["inventory_type"] == "nssi": + if rec["candidate"]["inventory_type"] in ["nssi", "nsi", "slice_profiles"]: rec["candidate"] = resource if resource.get('vim-id'): @@ -585,8 +574,10 @@ class SolverService(cotyledon.Service): ''' go through list of recommendations in the solution for cloud candidates, check if (cloud-region-id + e2evnfkey) is in the order_locks table - if so, insert the row with status 'parked' in order_locks, changes plan status to 'pending' in plans table (or other status value) - otherwise, insert the row with status 'locked' in order_locks, and change status to 'solved' in plans table - continue reservation + if so, insert the row with status 'parked' in order_locks, changes plan status to 'pending' in plans + table (or other status value) + otherwise, insert the row with status 'locked' in order_locks, and change status to 'solved' in plans + table - continue reservation ''' # clean up the data/record in order_locks table, deleting all records that failed from MSO @@ -599,7 +590,8 @@ class SolverService(cotyledon.Service): if plan_dict.get('status', None) == OrderLock.FAILED: order_lock_record.delete() - LOG.info(_LI("The order lock record {} with status {} is deleted (due to failure spinup from MSO) from order_locks table"). + LOG.info(_LI("The order lock record {} with status {} is deleted (due to failure" + " spinup from MSO) from order_locks table"). format(order_lock_record, plan_dict.get('status'))) break @@ -626,7 +618,8 @@ class SolverService(cotyledon.Service): order_lock_record = self.OrderLock.query.get_plan_by_col("id", conflict_id) if order_lock_record: is_spinup_completed = getattr(order_lock_record[0], 'is_spinup_completed') - spinup_completed_timestamp = getattr(order_lock_record[0], 'spinup_completed_timestamp') + spinup_completed_timestamp = getattr(order_lock_record[0], + 'spinup_completed_timestamp') if is_spinup_completed and spinup_completed_timestamp > p.translation_begin_timestamp: is_order_translated_before_spinup = True break @@ -691,13 +684,17 @@ class SolverService(cotyledon.Service): if is_spinup_completed: # persist the record in order_locks_history table - order_lock_history_record = self.OrderLockHistory(conflict_id=conflict_id, plans=plans, - is_spinup_completed=is_spinup_completed, - spinup_completed_timestamp=spinup_completed_timestamp) - LOG.debug("Inserting the history record with conflict id {} to order_locks_history table".format(conflict_id)) + order_lock_history_record = \ + self.OrderLockHistory(conflict_id=conflict_id, plans=plans, + is_spinup_completed=is_spinup_completed, + spinup_completed_timestamp=spinup_completed_timestamp + ) + LOG.debug("Inserting the history record with conflict id {}" + " to order_locks_history table".format(conflict_id)) order_lock_history_record.insert() # remove the older record - LOG.debug("Deleting the order lock record {} from order_locks table".format(deleting_record)) + LOG.debug("Deleting the order lock record {} from order_locks table" + .format(deleting_record)) deleting_record.delete() plan = { @@ -729,18 +726,19 @@ class SolverService(cotyledon.Service): elif p.status == self.Plan.SOLVING: if len(inserted_order_records_dict) > 0: - LOG.info(_LI("The plan with id {} is parked in order_locks table, waiting for MSO release calls"). - format(p.id)) + LOG.info(_LI("The plan with id {} is parked in order_locks table," + "waiting for MSO release calls").format(p.id)) p.status = self.Plan.WAITING_SPINUP else: LOG.info(_LI("The plan with id {} is inserted in order_locks table."). format(p.id)) p.status = self.Plan.SOLVED - while 'FAILURE' in _is_success and (self.current_time_seconds() - self.millisec_to_sec(p.updated)) <= self.conf.solver.timeout: + while 'FAILURE' in _is_success \ + and (self.current_time_seconds() - self.millisec_to_sec(p.updated)) <= self.conf.solver.timeout: _is_success = p.update(condition=self.solver_owner_condition) LOG.info(_LI("Plan search complete, changing the template status from solving to {}, " - "atomic update response from MUSIC {}").format(p.status, _is_success)) + "atomic update response from MUSIC {}").format(p.status, _is_success)) LOG.info(_LI("Plan {} search complete, {} solution(s) found by machine {}"). format(p.id, len(solution_list), p.solver_owner)) @@ -750,14 +748,14 @@ class SolverService(cotyledon.Service): def terminate(self): """Terminate""" - LOG.debug("%s" % self.__class__.__name__) + LOG.debug({}.format(self.__class__.__name__)) self.running = False self._gracefully_stop() super(SolverService, self).terminate() def reload(self): """Reload""" - LOG.debug("%s" % self.__class__.__name__) + LOG.debug({}.format(self.__class__.__name__)) self._restart() def current_time_millis(self): @@ -765,8 +763,8 @@ class SolverService(cotyledon.Service): return int(round(time.time() * 1000)) def set_flavor_in_flavor_directives(self, flavor_map, directives): - ''' - Insert the flavor name inside the flavor_map into flavor_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 ''' diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/nsi_response.json b/conductor/conductor/tests/unit/data/plugins/inventory_provider/nsi_response.json index 8acb33d..f24409e 100644 --- a/conductor/conductor/tests/unit/data/plugins/inventory_provider/nsi_response.json +++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/nsi_response.json @@ -5,7 +5,7 @@ "service-instance-name": "nsi_test_0211", "service-type": "embb", "service-role": "nsi", - "environment-context": "shared", + "service-function": "shared", "model-invariant-id": "51e57d4b-52ad-4d3c-a798-248b5bb9124a", "model-version-id": "67ea363e-e39c-4bd9-a9d5-1371c28f4d22", "resource-version": "1581418601616", diff --git a/conductor/conductor/tests/unit/data/plugins/inventory_provider/nssi_response.json b/conductor/conductor/tests/unit/data/plugins/inventory_provider/nssi_response.json index 286c8bf..8165408 100644 --- a/conductor/conductor/tests/unit/data/plugins/inventory_provider/nssi_response.json +++ b/conductor/conductor/tests/unit/data/plugins/inventory_provider/nssi_response.json @@ -3,8 +3,8 @@ "service-instance-name": "nssi_test_0211", "service-type": "embb", "service-role": "nssi", - "service-function": "cn", - "environment-context": "shared", + "workload-context": "cn", + "service-function": "shared", "model-invariant-id": "21d57d4b-52ad-4d3c-a798-248b5bb9124a", "model-version-id": "bfba363e-e39c-4bd9-a9d5-1371c28f4d22", "resource-version": "1581418601616", -- cgit 1.2.3-korg