aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVikas Varma <vikas.varma@att.com>2020-05-05 14:08:34 +0000
committerGerrit Code Review <gerrit@onap.org>2020-05-05 14:08:34 +0000
commit1b493a741b87880181a027fe102d295fcbd6f7cb (patch)
tree132c4156fc5c3360a5e180ee351d6bbcdaa444bf
parent070488fcb919b2cdffca8a3739b0f9abbb9414f4 (diff)
parente07bb7a6bce3fa331c3e556395663dd77bc02676 (diff)
Merge "Change to support PCI unchangeable cells"
-rw-r--r--apps/pci/optimizers/pci_opt_processor.py10
-rw-r--r--apps/pci/optimizers/solver/min_confusion_inl.mzn16
-rw-r--r--apps/pci/optimizers/solver/no_conflicts_no_confusion.mzn17
-rw-r--r--apps/pci/optimizers/solver/optimizer.py44
-rw-r--r--apps/pci/optimizers/solver/pci_utils.py7
-rw-r--r--test/pci-optimization-tests/fixed_pci.json42
-rw-r--r--test/test_process_fixed_pci.py79
7 files changed, 206 insertions, 9 deletions
diff --git a/apps/pci/optimizers/pci_opt_processor.py b/apps/pci/optimizers/pci_opt_processor.py
index 9948d55..01ae0b4 100644
--- a/apps/pci/optimizers/pci_opt_processor.py
+++ b/apps/pci/optimizers/pci_opt_processor.py
@@ -89,10 +89,16 @@ def get_solutions(cell_info_list, network_cell_info, request_json):
def build_solution_list(cell_info_list, network_cell_info, request_json):
status = "success"
req_id = request_json["requestInfo"]["requestId"]
+ pci_solutions =[]
+ anr_solutions=[]
try:
opt_solution = optimize(network_cell_info, cell_info_list, request_json)
- pci_solutions = build_pci_solution(network_cell_info, opt_solution['pci'])
- anr_solutions = build_anr_solution(network_cell_info, opt_solution.get('removables', {}))
+ if opt_solution == 'UNSATISFIABLE':
+ status = 'inconsistent input'
+ return status, pci_solutions, anr_solutions
+ else:
+ pci_solutions = build_pci_solution(network_cell_info, opt_solution['pci'])
+ anr_solutions = build_anr_solution(network_cell_info, opt_solution.get('removables', {}))
except RuntimeError:
error_log.error("Failed finding solution for {} {}".format(req_id, traceback.format_exc()))
status = "failed"
diff --git a/apps/pci/optimizers/solver/min_confusion_inl.mzn b/apps/pci/optimizers/solver/min_confusion_inl.mzn
index 0f0fc91..e677e27 100644
--- a/apps/pci/optimizers/solver/min_confusion_inl.mzn
+++ b/apps/pci/optimizers/solver/min_confusion_inl.mzn
@@ -52,6 +52,14 @@ int: NUM_IGNORABLE_NEIGHBOR_LINKS;
% of the links, like the previous structures.
array[1..NUM_IGNORABLE_NEIGHBOR_LINKS, 1..2] of int: IGNORABLE_NEIGHBOR_LINKS;
+% ids of cells for which the pci should remain unchanged
+set of int: PCI_UNCHANGEABLE_CELLS;
+
+% This array has the original pcis of all the cells. array is indexed by the ids
+% of the cell. eg. ORIGINAL_PCIS[3] returns the pci of cell whose id is 3.
+% ids start from 0
+array[1..NUM_NODES] of 0..NUM_PCIS-1: ORIGINAL_PCIS;
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Decision variables
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -65,6 +73,14 @@ array[1..NUM_IGNORABLE_NEIGHBOR_LINKS] of var 0..1: used_ignorables;
% Constraints
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% fixed pci cells
+constraint
+if(length(PCI_UNCHANGEABLE_CELLS) !=0) then
+forall(i in PCI_UNCHANGEABLE_CELLS)(
+ pci[i] == ORIGINAL_PCIS[i+1]
+)
+endif;
+
% Direct neighbors must have different PCIs for avoid **COLLISION**.
% Forced links.
constraint
diff --git a/apps/pci/optimizers/solver/no_conflicts_no_confusion.mzn b/apps/pci/optimizers/solver/no_conflicts_no_confusion.mzn
index 0a9b3e3..f059d4a 100644
--- a/apps/pci/optimizers/solver/no_conflicts_no_confusion.mzn
+++ b/apps/pci/optimizers/solver/no_conflicts_no_confusion.mzn
@@ -44,6 +44,15 @@ int: NUM_SECOND_LEVEL_NEIGHBORS;
% Each line represents an edge between undirect neighbors as defined before.
array[1..NUM_SECOND_LEVEL_NEIGHBORS, 1..2] of int: SECOND_LEVEL_NEIGHBORS;
+% ids of cells for which the pci should remain unchanged
+set of int: PCI_UNCHANGEABLE_CELLS;
+
+% This array has the original pcis of all the cells. array is indexed by the ids
+% of the cell. eg. ORIGINAL_PCIS[3] returns the pci of cell whose id is 3.
+% ids start from 0
+% array[0..NUM_NODES-1] of 0..NUM_PCIS-1: ORIGINAL_PCIS;
+array[1..NUM_NODES] of 0..NUM_PCIS-1: ORIGINAL_PCIS;
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Decision variables
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -55,6 +64,14 @@ array[0..NUM_NODES-1] of var 0..NUM_PCIS-1: pci;
% Constraints
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+constraint
+if(length(PCI_UNCHANGEABLE_CELLS) !=0) then
+forall(i in PCI_UNCHANGEABLE_CELLS)(
+ pci[i] == ORIGINAL_PCIS[i+1]
+)
+endif;
+
+
% Direct neighbors must have different PCIs for avoid **COLLISION**.
constraint
forall(i in 1..NUM_NEIGHBORS)(
diff --git a/apps/pci/optimizers/solver/optimizer.py b/apps/pci/optimizers/solver/optimizer.py
index 0a6d5a4..940f9f7 100644
--- a/apps/pci/optimizers/solver/optimizer.py
+++ b/apps/pci/optimizers/solver/optimizer.py
@@ -19,28 +19,56 @@
import itertools
import os
from collections import defaultdict
-
import pymzn
-from .pci_utils import get_id
+from .pci_utils import get_id,mapping
BASE_DIR = os.path.dirname(__file__)
-
+cell_id_mapping = dict()
+id_cell_mapping = dict()
def pci_optimize(network_cell_info, cell_info_list, request_json):
+ global cell_id_mapping, id_cell_mapping
+ cell_id_mapping, id_cell_mapping = mapping(network_cell_info)
+ original_pcis = get_original_pci_list(network_cell_info)
+ unchangeable_pcis = get_ids_of_fixed_pci_cells(request_json['cellInfo'].get('fixedPCICells', []))
neighbor_edges = get_neighbor_list(network_cell_info)
second_level_edges = get_second_level_neighbor(network_cell_info)
ignorable_links = get_ignorable_links(network_cell_info, request_json)
anr_flag = is_anr(request_json)
- dzn_data = build_dzn_data(cell_info_list, ignorable_links, neighbor_edges, second_level_edges, anr_flag)
+ dzn_data = build_dzn_data(cell_info_list, ignorable_links, neighbor_edges, second_level_edges, anr_flag, original_pcis, unchangeable_pcis)
return build_pci_solution(dzn_data, ignorable_links, anr_flag)
+def get_ids_of_fixed_pci_cells(fixed_pci_list):
+ fixed_pci_ids = set()
+ for cell in fixed_pci_list:
+ fixed_pci_ids.add(cell_id_mapping[cell])
+ return fixed_pci_ids
+
+
+def get_cell_id_pci_mapping(network_cell_info):
+ original_pcis = dict()
+ for cell in network_cell_info['cell_list']:
+ for nbr in cell['nbr_list']:
+ if cell_id_mapping[nbr['targetCellId']] not in original_pcis:
+ original_pcis[cell_id_mapping[nbr['targetCellId']]] = nbr['pciValue']
+ return original_pcis
+
+
+def get_original_pci_list(network_cell_info):
+ cell_id_pci_mapping = get_cell_id_pci_mapping(network_cell_info)
+ original_pcis_list = []
+ for i in range(len(cell_id_pci_mapping)):
+ original_pcis_list.append(cell_id_pci_mapping.get(i))
+ return original_pcis_list
+
def build_pci_solution(dzn_data, ignorable_links, anr_flag):
mzn_solution = solve(get_mzn_model(anr_flag), dzn_data)
-
+ if mzn_solution == 'UNSATISFIABLE':
+ return mzn_solution
solution = {'pci': mzn_solution[0]['pci']}
if anr_flag:
@@ -55,14 +83,16 @@ def build_pci_solution(dzn_data, ignorable_links, anr_flag):
return solution
-def build_dzn_data(cell_info_list, ignorable_links, neighbor_edges, second_level_edges, anr_flag):
+def build_dzn_data(cell_info_list, ignorable_links, neighbor_edges, second_level_edges, anr_flag,original_pcis, unchangeable_pcis):
dzn_data = {
'NUM_NODES': len(cell_info_list),
'NUM_PCIS': len(cell_info_list),
'NUM_NEIGHBORS': len(neighbor_edges),
'NEIGHBORS': get_list(neighbor_edges),
'NUM_SECOND_LEVEL_NEIGHBORS': len(second_level_edges),
- 'SECOND_LEVEL_NEIGHBORS': get_list(second_level_edges)
+ 'SECOND_LEVEL_NEIGHBORS': get_list(second_level_edges),
+ 'PCI_UNCHANGEABLE_CELLS': unchangeable_pcis,
+ 'ORIGINAL_PCIS': original_pcis
}
if anr_flag:
dzn_data['NUM_IGNORABLE_NEIGHBOR_LINKS'] = len(ignorable_links)
diff --git a/apps/pci/optimizers/solver/pci_utils.py b/apps/pci/optimizers/solver/pci_utils.py
index 04829cf..7db3a6f 100644
--- a/apps/pci/optimizers/solver/pci_utils.py
+++ b/apps/pci/optimizers/solver/pci_utils.py
@@ -16,6 +16,13 @@
# -------------------------------------------------------------------------
#
+def mapping(network_cell_info):
+ cell_id_mapping= dict()
+ id_cell_mapping = dict()
+ for i in network_cell_info['cell_list']:
+ cell_id_mapping[i['cell_id']] = i['id']
+ id_cell_mapping[i['id']] = i['cell_id']
+ return cell_id_mapping, id_cell_mapping
def get_id(network_cell_info, cell_id):
for i in network_cell_info['cell_list']:
diff --git a/test/pci-optimization-tests/fixed_pci.json b/test/pci-optimization-tests/fixed_pci.json
new file mode 100644
index 0000000..8bd159e
--- /dev/null
+++ b/test/pci-optimization-tests/fixed_pci.json
@@ -0,0 +1,42 @@
+{
+
+ "requestInfo": {
+
+ "transactionId": "xxx-xxx-xxxx",
+
+ "requestId": "yyy-yyy-yyyy",
+
+ "callbackUrl": "https://wiki.onap.org:5000/callbackUrl/",
+
+ "sourceId": "SO",
+
+ "requestType": "create",
+
+ "numSolutions": 1,
+
+ "optimizers": [
+
+ "pci-anr"
+
+ ],
+
+ "timeout": 600
+
+ },
+
+ "cellInfo": {
+
+ "networkId": "2000",
+
+ "cellIdList": [
+
+ "cell0"
+
+ ],
+
+ "fixedPCICells": ["cell21","cell22"],
+ "anrInputList": [{"cellId": "cell20", "removeableNeighbors" :["cell23"]}],
+ "trigger": "NbrListChange"
+ }
+
+}
diff --git a/test/test_process_fixed_pci.py b/test/test_process_fixed_pci.py
new file mode 100644
index 0000000..da68289
--- /dev/null
+++ b/test/test_process_fixed_pci.py
@@ -0,0 +1,79 @@
+# -------------------------------------------------------------------------
+# Copyright (c) 2018 AT&T Intellectual Property
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# -------------------------------------------------------------------------
+#
+import mock
+import unittest
+
+from flask import Response
+from mock import patch
+from osdf.adapters.local_data import local_policies
+from apps.pci.optimizers.pci_opt_processor import process_pci_optimation
+import osdf.config.loader as config_loader
+from osdf.utils.interfaces import json_from_file
+from osdf.utils.programming_utils import DotDict
+
+
+class TestProcessPlacementOpt(unittest.TestCase):
+
+ def setUp(self):
+ mock_req_accept_message = Response("Accepted Request", content_type='application/json; charset=utf-8')
+ self.patcher_req = patch('apps.pci.optimizers.configdb.request',
+ return_value={"solutionInfo": {"placementInfo": "dummy"}})
+ self.patcher_req_accept = patch('osdf.operation.responses.osdf_response_for_request_accept',
+ return_value=mock_req_accept_message)
+ self.patcher_callback = patch(
+ 'apps.pci.optimizers.pci_opt_processor.process_pci_optimation',
+ return_value=mock_req_accept_message)
+
+ mock_mzn_response = [{'pci': {0: 2, 1: 0, 2: 1, 3:3, 4:0} , 'used_ignorables': [0]}]
+
+ self.patcher_minizinc_callback = patch(
+ 'apps.pci.optimizers.solver.optimizer.solve',
+ return_value=mock_mzn_response )
+ self.patcher_RestClient = patch(
+ 'osdf.utils.interfaces.RestClient', return_value=mock.MagicMock())
+ self.Mock_req = self.patcher_req.start()
+ self.Mock_req_accept = self.patcher_req_accept.start()
+ self.Mock_callback = self.patcher_callback.start()
+ self.Mock_RestClient = self.patcher_RestClient.start()
+ self.Mock_mzn_callback = self.patcher_minizinc_callback.start()
+
+ def tearDown(self):
+ patch.stopall()
+
+ def test_process_pci_opt_solutions(self):
+ main_dir = ""
+ parameter_data_file = main_dir + "test/pci-optimization-tests/fixed_pci.json"
+ policy_data_path = main_dir + "test/policy-local-files/"
+ self.config_spec = {
+ "deployment": "test/functest/simulators/simulated-config/osdf_config.yaml",
+ "core": "test/functest/simulators/simulated-config/common_config.yaml"
+ }
+ self.osdf_config = DotDict(config_loader.all_configs(**self.config_spec))
+
+ valid_policies_list_file = policy_data_path + '/' + 'meta-valid-policies.txt'
+ valid_policies_files = local_policies.get_policy_names_from_file(valid_policies_list_file)
+
+ request_json = json_from_file(parameter_data_file)
+ policies = [json_from_file(policy_data_path + '/' + name) for name in valid_policies_files]
+
+ templ_string = process_pci_optimation(request_json, self.osdf_config,policies)
+
+
+if __name__ == "__main__":
+ unittest.main()
+